マンガでよめる痔のこと・薬のこと

親ウィンドウに入ってくるメッセージを子ウィンドウ(ダイアログ)のメッセージマップで処理したいと思ってますが、どうにもできません。なにかよい方法はないでしょうか?

処理したいメッセージはESCが押されたかどうかだけなので、親で受けたメッセージを子供にSendMessageすればよいのですが、できれば、親で受けたメッセージすべてを子供にそのまま渡すというようなことができたらうれしいです。
ATL/WTLでの書き方だともっとうれしいです。
どうぞよろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

親ウィンドウを弄らずに子ウィンドウでメッセージを取りたいならばHookと言う手があります。

ご存知かもしれませんが、プログラムのみならずOS自体にも致命的なダメージを与えかねないので注意して使用してください。

#メモリ確保などを子ウィンドウが行っていたとしても、終了の命令は(拡張時に他のウィンドウなども管理する観点から)明示的に親ウィンドウから行われるべきだと思います。メモリ開放などはそれを受けた子ウィンドウが行い、完了した旨を親ウィンドウに通知してプログラムが終了するのが通例でしょう。ただ、コメントから親ウィンドウを弄らないと言う記述があるので特殊なケースを狙ったものかもしれませんが…
    • good
    • 0
この回答へのお礼

MESSAGE_RANGE_HANDLER
で、複数のメッセージをハンドルできましたのである程度解決しました。
アドバイスありがとうございます。

お礼日時:2005/10/05 15:55

ATL/WTLしか書かれていないので、他環境が良く判りませんが、親のWindowProc()から任意の関数にそのままメッセージを投

げるのは試されましたか?

この回答への補足

理想を言うと、親ウィンドウのメッセージマップにハンドラは書かずに、子供の方にハンドラを書いて(すでに書いてある)処理したいと思っています。
詳しく書くと、実行中は親ウィンドウの方がアクティブになっています。(表示のためだけ)表示のための計算やメモリの確保などの処理は子供のダイアログの方で行ってますので、終了コードは子供に書かれています。しかし親ウィンドウがアクティブになっているので、子供の方で処理ができません。そこで、親から子供にメッセージを出して終了させたいと考えました。

環境は、
VC2003でWTLは7.5を使っています。

基本的に考え方がおかしいとか、気がつく点があったらアドバイスをおねがしいます。

補足日時:2005/10/02 23:40
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

QC++とVC++の違いについて

この質問をご覧頂きありがとうございます。

みなさんに2つ、お聞きしたいことがあり、質問させていただきます。
1.C++とVC++とでは、どのくらいの違い(どういう違い、特徴)があるのでしょうか?

2.また、これからC++/VC++でプログラミングを始めようとした場合、
C++からVC++へと段階を踏んで勉強した方がよいのでしょうか?

一応、私のプログラミングの履歴としては、
言語としてVisual Basicは多少勉強はしておりました。
また、オブジェクト指向の基礎程度(多相、継承、カプセル化)は理解しています。

抽象的な質問で大変恐縮なのですが、
みなさんの経験論や、ご参考にした本、HP等がありましたら、
ご教授いただければと思います。

Aベストアンサー

こんにちは、honiyonです。
 VC++ は、Microsoftの発売している C++開発環境です。 純正C++に加え、独自に機能(という言い方でいいのかな?)を追加しており、更に開発しやすいソフト(環境)を添付してあります。

 VC++に限らず、大体はそうです。 ProC++も、Borland C++も皆そうです。
 今までお使いになっていた VBも、BASICコンパイラ+開発環境です。 
 こちらの場合、BASICに機能を追加・・・というより仕様そのものを大幅いじってますね(笑)

 VC++をただ単純に C++として使用するなら良いですが、VC++とMFCを使用してウインドウアプリケーションを作りたいという事であれば、死に物狂いな勉強が必要が必要かもしれません。Windowアプリケーションの処理プロセスを理解していないと、とっても難解に感じると思います。
 VC++でなければいや!という理由がなく、Visual Basicからスムーズに移行でき、かつVisual Basicより奥の深い事をしたい、というならば C++ Builder をお勧めします。 こちらで腕を慣らし、徐々にWindowアプリケーションの処理プロセス(WinMainから始まるプログラムの組み方の事です)を学ぶと良いかな、と思います。 その上で VC++&MFCな環境に移行すると、敷居はぐっと低くなります。
 私は一度VC++&MFCに挫折しましたが、こちらの方法で何とか理解する事が出来ました(^^;

 参考になれば幸いです(..
 

こんにちは、honiyonです。
 VC++ は、Microsoftの発売している C++開発環境です。 純正C++に加え、独自に機能(という言い方でいいのかな?)を追加しており、更に開発しやすいソフト(環境)を添付してあります。

 VC++に限らず、大体はそうです。 ProC++も、Borland C++も皆そうです。
 今までお使いになっていた VBも、BASICコンパイラ+開発環境です。 
 こちらの場合、BASICに機能を追加・・・というより仕様そのものを大幅いじってますね(笑)

 VC++をただ単純に C++として使用するなら良いで...続きを読む

Qボタンの表示の色、フォントを変更したい

VC++でプログラミングしています。
MFCのダイアログベースのEXEを造っています。
ダイアログにはボタンとエディットボックスを貼り付けています。
私がやりたいのは以下のことです。

・ボタンの色を設定したい
・ボタン、エディットボックスに表示する文字の色を設定したい
・ボタン、エディットボックスに表示する文字のフォント(サイズ)を設定したい

プロパティでサイズ変更すると全体に反映されてしまうので、個々の
コントロールについて制御したいと思っています。

ヘルプで調べて、それらしい関数を見つけるのですが使い方がわかりません。
VCを始めたばかりで、クラスの理解がまだ浅いです。。。
関数の説明は理解できても、「じゃあ、コードはどう書くの?」という状態です。
「○○ は ×× のメンバではありません」と、よく怒られてます。。。

識者の方、ご教授願います。
コードがどうなるのか知りたいので、簡単なサンプルコードがあると助かります。

また、質問ではないのですが、「この関数は○○をする」というのではなく、
「○○をするにはこの関数を使う」という様に調べられる、お勧めの書籍、
Webなどがありましたら教えてください。
今後の勉強に役立てたいと思っています。

VC++でプログラミングしています。
MFCのダイアログベースのEXEを造っています。
ダイアログにはボタンとエディットボックスを貼り付けています。
私がやりたいのは以下のことです。

・ボタンの色を設定したい
・ボタン、エディットボックスに表示する文字の色を設定したい
・ボタン、エディットボックスに表示する文字のフォント(サイズ)を設定したい

プロパティでサイズ変更すると全体に反映されてしまうので、個々の
コントロールについて制御したいと思っています。

ヘルプで調べ...続きを読む

Aベストアンサー

下2つについては以下でいけると思います。

class CMyDlg : CDialog
{
public:

  CFont m_cFont; //Dlgクラスのメンバとして用意
/*
  他のメンバ
*/
  virtual BOOL OnInitDialog(); //初期化

};


BOOL CMyDlg::OnInitDialog()
{
  //TODO:ここでFontを設定しておく(文字の色、サイズなど)

  //Fontを設定
  ((CButton *)GetDlgItem(IDC_BUTTON))->SetFont(&m_cFont,TRUE);

  //TODO:その他の初期化

  return TRUE;
}
//見易さのために、全角スペースを使っています;;

一番上はBitmapを貼り付けるか、CWndのメンバ関数を使って
塗りつぶすかどうかだと思います。

MFCではなく、C++Builderのページなのですが、少しいじればMFCでも使えるので、参考URLに示しておきます。

参考URL:http://market.agr.tottori-u.ac.jp/ken/tech.html

下2つについては以下でいけると思います。

class CMyDlg : CDialog
{
public:

  CFont m_cFont; //Dlgクラスのメンバとして用意
/*
  他のメンバ
*/
  virtual BOOL OnInitDialog(); //初期化

};


BOOL CMyDlg::OnInitDialog()
{
  //TODO:ここでFontを設定しておく(文字の色、サイズなど)

  //Fontを設定
  ((CButton *)GetDlgItem(IDC_BUTTON))->SetFont(&m_cFont,TRUE);

  //TODO:その他の初期化

  return TRUE;
}
//見易さのために、全角スペースを使って...続きを読む

QVC++,SendMessage()の使い方

初心者です。
メニューに、ID_ENGAGEというIDをもつアイテムを作って、CViewにそのハンドラを作りました。
メニューをクリックして確認すると、ハンドラは正常に動いています。

しかし、CView内(OnKeyUp())でSendMessage(ID_ENGAGE)やPostMessage(ID_ENGAGE)を実行しても、ハンドラを呼んでくれないようなのです。

CFrameWndに送る必要があるのかもしれないと、GetParent()->SendMessage(ID_ENGAGE)も試してみましたがうまくいきませんでした。

どうすればうまくいくのでしょうか?
お分かりになる方がいらっしゃいましたら、よろしくお願いします。

Aベストアンサー

Dannerです

SendMessageの最初の引数は、メッセージIDを指定します。
(ID_ENGAGEはコマンドを識別するためのID)

したがって
SendMessage(WM_COMMAND, ID_ENGAGE);
にすれば、動くと思います。

同じクラス内で呼ぶのなら、直接ハンドラ関数を呼んだ方が簡単です。

QcharからLPTSTRへの変換方法

リストコントロールにchar型の変数の値を数値として表示させたいのですが、charからLPTSTRへの洗練された変換方法がよくわからないです。

char tempChar;
CString tempString;
tempString.Format("%s", tempChar);
LPTSTR lpsz = new TCHAR[tempString.GetLength()+1];
_tcscpy(lpsz, tempString);

こんなプログラムを考えてみたのですが、汚いような気がします。もっと簡単で洗練された変換方法はないのでしょうか?

Aベストアンサー

wsprintfを使ってはどうでしょうか?

char tmpChar = 100;//表示する数値
TCHAR buf[5];
wsprintf(buf, "%d", tempChar);

Q他のウィンドウのボタンを自動的に押したい

VisualC++で作ったアプリケーションから、例えばWindowsに標準搭載の「電卓アプリケーション」のウィンドウをアクティブにして、さらにその中の「1」ボタンを認識して押す、テキストボックスを認識してそこに文字列を入れるといったソフトを作りたいです。

簡単にいうと、他のアプリケーションを自動的に操作するソフトを作りたいのです。

これを実現するために、Web検索してみましたが、関連する技術の名前やMFCでのAPI名がわからないです。これはどういった名前の技術で、VisualC++でどういった名前の関数を使うのでしょうか?

当方の環境はWindowsXP&VisualC++6.0です。

以上、よろしくお願いします。

Aベストアンサー

★列挙方法のアドバイス
・補足になる仕様の
>(1)ウィンドウのタイトルバーの名前(例:「電卓」)、
>またはウィンドウのIDでウィンドウを探す
 ↑
 これなら FindWindow() 関数でウインドウ・ハンドルを探せます。
 例: HWND hWnd = FindWindow( "SciCalc", "電卓" );
>(2)最初にヒットしたウィンドウをアクティブにする
 ↑
 最初にヒットした hWnd を SetForegroundWindow() 関数でアクティブにします。
 例: SetForegroundWindow( hWnd );
>(3)アクティブにしたウィンドウの中にあるボタンを探す
 ↑
 (1)で取得しているウインドウに対して子ウインドウ(ボタンなど)を列挙します。
 列挙には EnumChildWindows() 関数と EnumChildProc() のコールバック関数を使います。
>(4)「1」のボタン、またはボタンのIDがヒットしたらそのボタンを押す
 ↑
 列挙のコールバック関数(EnumChildProc)でボタンのキャプションを調べて
 『1』となっている文字列が電卓の『1』ボタンです。
 このときにボタンを押す処理をプログラムから行います。
 例: SendMessage( hChild, BM_CLICK, 0, 0 );
 URL: http://wisdom.sakura.ne.jp/system/winapi/win32/win53.html
・上記のような感じで操作できます。
 一番重要なのは操作するウインドウのハンドルを正しく見つけ出すことです。
 このウインドウ・ハンドルを見つけるには次の方法があります。
 (1)FindWindow() 関数を使う
 (2)EnumWindows() 関数を使う
 (3)Process32First()、Process32Next() 関数を使う
 (4)EnumProcesses() 関数を使う
 などがあります。
 今回は簡単な(1)を紹介しました。
 もしもウインドウのクラス名やキャプション名以外で詳しく捜査対象の
 ウインドウを検索するには(2)の EnumWindows() 関数や起動パス名を
 調べて特定できる (3)、(4)の関数群を利用します。
>テキストの内容の認識や保存など色々な機能を盛り込んだソフトを作りたいからです。
 ↑
 ボタンなどのテキストを認識、保存には GetWindowText()、WM_GETTEXT メッセージを
 使います。メッセージの場合は SendMessage() 関数でキャプション文字列を取得します。
 例: SendMessage( hChild, WM_GETTEXT, sizeof(szBuff), szBuff );
・下に簡単なボタンの列挙を載せます。これを活用して下さい。

サンプル:
#include <stdio.h>
#include <windows.h>

// コールバック関数
BOOL CALLBACK EnumChildProc( HWND hWnd, LPARAM lParam )
{
 TCHAR szBuff[ 1024 ];
 
 // キャプションの取得
 GetWindowText( hWnd, szBuff, sizeof(szBuff) );
 printf( "├[%s]\n", szBuff );
 return TRUE;
}

// メイン関数
int main( void )
{
 HWND hCalc;
 
 if ( (hCalc = FindWindow("SciCalc","電卓")) != NULL ){
  printf( "◆電卓のコントロール列挙\n" );
  EnumChildWindows( hCalc, EnumChildProc, NULL );
 }
 return 0;
}
以上。

★列挙方法のアドバイス
・補足になる仕様の
>(1)ウィンドウのタイトルバーの名前(例:「電卓」)、
>またはウィンドウのIDでウィンドウを探す
 ↑
 これなら FindWindow() 関数でウインドウ・ハンドルを探せます。
 例: HWND hWnd = FindWindow( "SciCalc", "電卓" );
>(2)最初にヒットしたウィンドウをアクティブにする
 ↑
 最初にヒットした hWnd を SetForegroundWindow() 関数でアクティブにします。
 例: SetForegroundWindow( hWnd );
>(3)アクティブにしたウィンドウの中にあるボタンを...続きを読む

Qc言語win32apiで孫ウインドウからメッセージ処理ができません。

c言語win32apiで孫ウインドウからメッセージ処理ができません。
親ウインドウを作りその中に子ウインドウを作りさらに孫ウインドウを作りました。
以下のような感じです。
--
親ウインドウ(A)親はNULL

子ウインドウ(B)親はA

孫ウインドウ(C、プッシュボタン)親はB

で、孫ボタンをクリックしたらwindprocにWM_COMMANDメッセージが飛ぶと思っていたんですが
まったく反応しません。
試しに親をAに変更したらちゃんと動きました。
孫ウインドウからwindprocにメッセージを飛ばすにはどうしたらいいんでしょうか。
それとも何か特別な方法があるんでしょうか。
開発環境はVC++ExpressEdition2008を使っています。

Aベストアンサー

>1の方法ですがそんな事が出来るんですか!?
>具体的な手法かもしくは参考ページとかあったら教えていただけないでしょうかm(_)m

実際のやり方としては2とそんなに違いはないかと思います。
子ウィンドウが具体的には何かが記述されていないので一般的な回答になりますが・・・

1.元の子ウィンドウのwndprocをGetWindowLongで取得する。
2.新しいwndprocを子ウィンドウに対してSetWindowLongで設定する。
3.新しいwndprocでは孫ウィンドウのWM_COMMANDメッセージを処理する。それ以外はCallWindowProcで元のwndprocを呼び出して処理させる。

これでサブクラス化するはずです。
1.の処理は2.のSetWindowLongの戻り値を利用することもできます。

1の方法は、孫ウィンドウのWM_COMMANDメッセージを受け取ったら、親ウィンドウに対してSendMessageでメッセージを送信する・・・という意味です。こちらも結局サブクラス化してますね・・・

2の方法は、何らかの方法で親ウィンドウハンドルを孫ウィンドウでアクセスできるようにしておく必要があります。

>1の方法ですがそんな事が出来るんですか!?
>具体的な手法かもしくは参考ページとかあったら教えていただけないでしょうかm(_)m

実際のやり方としては2とそんなに違いはないかと思います。
子ウィンドウが具体的には何かが記述されていないので一般的な回答になりますが・・・

1.元の子ウィンドウのwndprocをGetWindowLongで取得する。
2.新しいwndprocを子ウィンドウに対してSetWindowLongで設定する。
3.新しいwndprocでは孫ウィンドウのWM_COMMANDメッセージを処理する。それ以外はCallWindo...続きを読む

Qスレッドの安全な終了のさせ方

スレッドの安全な終了のさせ方

 メインスレッドにてCreateThread命令を使い、あるサブスレッドを作りました。
このサブスレッドは内部でmallocを使い動的に配列領域を確保して
その配列領域をforループ等で「かなり時間の掛かる処理」として繰り返し
アクセスしています。
ループが終了した時に「free」を実行してmalloc領域を開放しています。

アプリ終了時にメインスレッドからこのサブスレッドを終了させるのに
メインウインドウにWM_DESTROYメッセージが送られた時、これまで単に
そこで「CloseHandle(hSubThread);」とだけ書いていたのですが、
もしかしたらこれでは場合によっては(サブスレッドがループ処理中だったら)
malloc領域が開放されずにリークしてしまうのではないかと思いました。

 そこでイベントオブジェクトを使い、サブスレッドがループ処理中の
時には非シグナル状態にして、ループが終了しfreeで領域を開放した後
シグナル状態にするということにして、メインスレッドはそれを
WaitForSingleObjectで待つという構造にしました。

ところが「メインスレッドに待ちを作るな」という言葉通り、これでは
上手く行きませんでした。サブスレッドはその時間の掛かる処理の
最中でSendMassage等でメインスレッドの処理を促すような命令を
(例えばその処理の進捗状況を表示するなど)を幾つも行っていたので、
もしWaitFor~でメインを待たせると「サブスレッドの処理も進まなくなり
結果両方がロックして動かなくなってしまう」という悲しい状況に
嵌ってしまうのです。

SendMessageを徹底的に無くすということも考えたのですが、
(例えばPostMessageに書き換えるなどもやってみたのですが、これは
全く意図した動作をしてくれない場合もあり)、別の方法では
どうしても代替できないケースもあって、全て消すというのは
現実的ではないのかもと。。

 このようなサブスレッドを安全に終了させるにはどうしたら良いでしょうか?
あるいは単にデストロイ時にCloseHandleとするだけでも良いのでしょうか?

スレッドの安全な終了のさせ方

 メインスレッドにてCreateThread命令を使い、あるサブスレッドを作りました。
このサブスレッドは内部でmallocを使い動的に配列領域を確保して
その配列領域をforループ等で「かなり時間の掛かる処理」として繰り返し
アクセスしています。
ループが終了した時に「free」を実行してmalloc領域を開放しています。

アプリ終了時にメインスレッドからこのサブスレッドを終了させるのに
メインウインドウにWM_DESTROYメッセージが送られた時、これまで単に
そこで「CloseHandle(hSu...続きを読む

Aベストアンサー

>SetEvent(hEventObject1);//イベントオブジェクトをシグナルに
スレッド終了を判断する場合はスレッドのハンドル自身を見た方が確実です。
HANDLE thread_handle = ::CreateThread(略);
(略)
::WaitForSingleObject( thread_handle , INFINITE );
スレッドは終了時にハンドルがシグナル状態になります。


>SendMessage(hMainWnd,....);
>//メインウインドウに何かのメッセージを送信
>//なってた時に処理が進まなくなる。
名前から察するにhMainWndはメインスレッドで動いているようですが
そのメインスレッドの処理がWaitForSingleObjectによって止まっているのなら処理は返ってきません。
つまりサブスレッドがメインスレッドとなんらかのやりとりをしたいなら、
この時点でメイン側はWaitForSingleObjectで待ってはいけません。

1. Main -> Subに終了前準備しろと通知
2. Sub -> Mainに終了前準備完了を通知
3. Main -> Subに終了しろと通知
4. MainはSubが終了するのをWaitForSingleObjectで待つ。

>SetEvent(hEventObject1);//イベントオブジェクトをシグナルに
スレッド終了を判断する場合はスレッドのハンドル自身を見た方が確実です。
HANDLE thread_handle = ::CreateThread(略);
(略)
::WaitForSingleObject( thread_handle , INFINITE );
スレッドは終了時にハンドルがシグナル状態になります。


>SendMessage(hMainWnd,....);
>//メインウインドウに何かのメッセージを送信
>//なってた時に処理が進まなくなる。
名前から察するにhMainWndはメインスレッドで動いているようですが
そのメインスレッドの...続きを読む

QC++ 子ウィンドウのハンドルを取得したいのですが

C++で別ウィンドウのアプリケーションを動かすというものを作っているのですが、そのウィンドウの子ウィンドウのハンドルを取得するのに困ったことがあるのでアドバイスをいただけると大変ありがたいです。

基本的にSPY++というソフトを使ってウィンドウ名その他を探し、FindWindowExまたはGetDlgItem関数を使って取得という方法をとっているのですが、クラス名、ウィンドウ名が全く同じもので、コントロールIDも0という状態のものがあり、片方を取得したい場合どうしたらよいのかという状態です。

知人にSPY++でみて上から何番目にあるやつと指定して得ることができる方法があるかもしれないと聞いたのですが、よくわかりません。

例としてその画像ものせますので、良い知恵がありましたらお貸しください。

Aベストアンサー

FindeWindowExの二番目の引数を使えば次のウィンドウをとれます。

HWND hFirstWnd = ::FindWindowEx(hParentWnd, NULL, TEXT(""), TEXT(""));
if (hFirstWnd != NULL) {
HWND hSecondWnd = ::FindWindowEx(hParentWnd, hFirstWnd, TEXT(""), TEXT(""));
}

http://msdn.microsoft.com/ja-jp/library/cc410853.aspx
のhwndChildAfterのところを参照。

Qダイアログ間のデータ渡し

開発環境:vista Visual Studio 2012 C言語

メインのダイアログから、他のダイアログにデータを渡したい場合(もしくはその逆)は、どうすればよいのでしょうか。
受け渡しするものを、すべてグローバルにする方法は思いつくのですが、これ以外の方法ではどのようにすればよいのでしょうか。
参考になるサイトやAPIなどを教えてください。

例えば、
アプリケーションで、設定のメニューバーを押すと、ダイアログが出てきて設定をするというイメージです。この場合、ユーザが設定した値をメインのダイアログに渡しているということですよね。

Aベストアンサー

>この値をポインターとして認識させ、構造体に入れる。
>(ここの部分が分からないです。単純にアドレス渡しみたいな感じかなと思いやってみると「二項演算子 '=' : 型 'LPARAM' の右オペランドを扱う演算子が見つかりません」と出てきてしまって。)

普通にキャストするだけです。

static LPSettingData lpSD = NULL;
 case WM_INITDIALOG:
  lpSD = reinterpret_cast<LPSettingData>(lParam);

みたいな感じで。
# DialogBoxParam()で渡してましたな。私の場合。 モーダルダイアログだったので。
# モードレスダイアログの場合はCreateDialogParam()などで渡した構造体変数の寿命に注意する必要があります。
# ローカル変数のような寿命の短いモノを使うとアクセスするときには…なんてコトになりかねませんのでご注意を。


人気Q&Aランキング