- ベストアンサー
ダイアログ間のメッセージの送信について
いつもお世話になっております。 現在、Visual Studio 2005にてMFCのダイアログベースのアプリケーションを作成しており、メッセージの送信の件で詰まった箇所があり質問させて頂きました。 現在のアプリケーションの全体像なのですが、 ダイアログベースなので、アプリケーション立ち上げ時に1つメインダイアログが表示されます。 そのメインダイアログ内にボタンを設置したとして、それぞれのボタン1,ボタン2からダイアログ1,ダイアログ2をDoModal()で表示させます。 それぞれのダイアログ1,2にはボタンが1つずつ設置されているとします。 質問させて頂きたいことは メインダイアログへダイアログ1,2からメッセージ送信をする場合には ::SendMessage(GetParent()->GetSafeHwnd(),MYMSG,0); でメッセージ送信をすることは出来ました。 しかしメインダイアログから呼び出されるダイアログ1,2間でメッセージを送信する場合に,例えばダイアログ1からダイアログ2へメッセージを送信させたいときに void C****1Dlg::OnBnClicked(){ C****2Dlg m_dlg2; ::SendMessage(m_dlg2.GetSafeHwnd(),MYMSG,0); とダイアログ1のボタンクリック時の関数内にコードを入力してもダイアログ2へメッセージは送信されず(ダイアログ2内のメッセージ受信関数OnMyMsg()が呼ばれず)、そのままスルーされるようなのです。 上述のコードで何か間違えている箇所があるでしょうか? メッセージを扱うのは初めてで、とにかく相手先のウィンドウのハンドルを取得できればいいのかなと思ってコードを書いてみたのですが。。 ご存知の方がいらっしゃいましたら、ご意見宜しくお願い致します。 尚、開発環境は Windows CE 6.0 Visual Studio 2005 です。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
ダイアログ1とダイアログ2は同時に表示されることがないようにとれ、 何がしたいのか?メッセージで処理するのは無理な気はしますが void C****1Dlg::OnBnClicked(){ C****2Dlg m_dlg2; <-ローカル変数にm_つけるのは紛らわしい <-ここにDoModal()がない=ウィンドウはない=ハンドルもない (ここでダイアログ2を表示させたいわけではないとは思うけど) ::SendMessage(m_dlg2.GetSafeHwnd(),MYMSG,0); <-無理 ーーーーーーーー メインダイアログのメンバーにダイアログ1,ダイアログ2のポインタを追加。 コンストラクタでNewする。他いくつか変更。 void C****1Dlg::OnBnClicked(){ C***MainDlg* pDlg0 = (C***MainDlg*)GetParent(); <-ちょっと手抜き ASSERT(pDlg0->m_dlg1 == this); <-おまけ C****2Dlg* pDlg2 = pDlg0->m_dlg2; <-ダイアログ2のポインタ if ( pDlg2 ) ::SendMessage(pDlg2->GetSafeHwnd(),MYMSG,0); ーーーーーーーー メッセージ送信しなくてもpublicかfriend利用で if ( pDlg2 ) pDlg->OnMyMsg(); のほうが好きだけど。
その他の回答 (2)
- 1108435
- ベストアンサー率43% (94/217)
VisualStudioの環境がよくわからない(なにせこちらはC++Builder派)ので、大きいことはいえませんが、modalで表示中のダイアログ1から開いていないmodalで動作するダイアログ2にメッセージを送ると言う部分を、発想的に変換して、ダイアログ1からメインウインドウへメッセージを送り、そのメッセージを受け取ったメインウインドウからダイアログ2へダイアログ1から受け取ったメッセージを送るではだめなのですか?
お礼
ご回答ありがとうございます。 前の方にも教えて頂いたとおり、開いてないダイアログのハンドルをとることは出来ないのを知らず考えていました。 そのことを踏まえて、1108435様のおっしゃるように、一度メインダイアログにメッセージを送った後で、ダイアログ2へメッセージを送り処理をさせるように致しました。 ご意見ありがとうございました。
- machongola
- ベストアンサー率60% (434/720)
こんにちは。 C****2Dlgのポインタをつまみ出さないといけないのではないでしょうか。 void C****1Dlg::OnBnClicked(){ C****2Dlg* pDlg2 = //どうにかして取ってくる; ::SendMessage(pDlg2->GetSafeHwnd(), MYMSG, 0);
お礼
ご回答ありがとうございます。 ご指摘の通り、 C***2Dlgのポインタを取得するように以下のようにコードを変更してみました void C*****1Dlg::OnBnClicked() { C*****2Dlg* pDlg2 = new C******2Dlg; ::SendMessage(pDlg2->GetSafeHwnd(),MYMSG,0); } しかし、Dlg2にメッセージは届かず、エラーが発生するということもなくメッセージ送信がスルーされたようになりました。。 試しにC***Dlg2にWindowProcを呼び出して、メッセージが来ていないか 確認してみたのですが、こちらにもMYMSGがきた様子はありませんでした。 コンストラクタを読んで、ポインタを得るというのは間違っているのでしょうか? 重ねての質問ですが、宜しくお願い致します。
お礼
ご回答ありがとうございます。 開いていないウィンドウのハンドルを取得することは無理なのですか。。それすら知りませんでした。 確かに、メッセージを送るよりも直接OnMyMsgの関数を読んでしまったほうが手っ取り早いですね、盲点でした。 ご意見ありがとうございました。