他クラスダイアログからのユーザー定義メッセージ送信

[戻る]
ゆうじ 2002/01/30(水) 16:16:34
ゆうじと申します。VC++は初めて1ヶ月の初心者です。

わからないことがあり、過去ログを見てもはっきりしないので教えてください。

現在メインウィンドをCFormViewクラスを使ってプログラムを書いております。
親ウィンドウから子ウィンドウ(CDilagからの派生)をDo_Modal()にて
開きます。ここの画面にてなにかイベントが起こった時にユーザー定義メッセージを親ウィンド
ウに送信し、親ウィンドウにあるEDITボックス値を変更するようなプログラムを作成したい
のですが、うまくメッセージ送信ができません。

<質問事項>
メッセージを送出するために何らかの方法で子ウィンドウへメインウィンドウのポインタを知ら
せて上げる必要があると思い、次のようなソースを考えました。

 m_Wndを外部変数とし
(親ウィンドウのコンストラクタ上で)
 CWnd* m_Wnd=(CWnd*)this;
 
 (子ウィンドウのメッセージ送出部分)
 m_Wnd->PostMessage(      );

ところが、FatalErrorにて終了してしまいます。ここで、thisポインタを使うのは
まちがっているのでしょうか?また、間違っているとすればthisポインタではなく別の方法で
子ウィンドウへ知らせる方法があったら教えてください。

初歩的な質問で申し訳ありませんがよろしくお願いします。
 

sugar 2002/01/30(水) 16:37:05
CWnd::GetParent()を調べてみてください。
ダイアログからこれを利用すれば、親が認識できるのではないでしょうか。

ゆうじ 2002/01/30(水) 17:19:10
早速のご解答ありがとうございます。

次のようにしてみました。
子ダイアログの方にて

CWnd* m_ParentWnd;

m_ParentWnd=CWnd::GetParent();
m_ParentWnd->PostMessage(       );

と行ったのですが、何の反応もありません。デバッガで見ているとメッセージ関数の
ところまでは行くのですが、その先何かの処理(意味不明なルーチンに入っちゃう)を
して、また最初の所に戻ってしまいます。上の書き方がまずいのでしょうか?

sugar 2002/01/30(水) 18:59:07
> CWnd* m_ParentWnd;
>
> m_ParentWnd=CWnd::GetParent();
> m_ParentWnd->PostMessage(       );
>
子ダイアログの中でですよね、そりゃ、まずいですよ。
CWnd::GetParent()と書いたのは、CWndクラスのGetParent()メソッドですよという意味で、
そのまま書いてはいけません。

単に、
m_ParentWnd=GetParent();
としていただければよろしいかと。

同義として、
m_ParentWnd=this->GetParent();
m_ParentWnd->PostMessage(       );
とか、
GetParent()->PostMessage(       );
とかでもよろしいかと。

ゆうじ 2002/01/31(木) 12:20:08
(長文です。ごめんなさい)
お返事遅くなりました。
いろいろと教えていただいてありがとうございます。

さて、sugarさんのおっしゃるようにやってみてはいるのですがうまく動作しません。
何かメッセージ関数の呼び方が悪いのかも知れないのですが・・・。

少なくともデバッガでみると、最初のCMsgViewの部分のthisポインタの値と
Dlgで取得したポインタの値が違っている所まではわかりましたが・・。

その後がまたいきづまってしまったのでもう少し教えていただけますか?
<プログラムスケルトン>
プロジェクト名:msg
MFC使用、親フレーム:CMsgView(基本クラス:CFormView)
そこから子ダイアログ CDlg_msg(基本クラス:CDialog)をDoModalでよんでおります。

メッセージ関数の実装方法としては
1)msg.h
 に#define WM_USER_MESSAGE (WM_USER+0x1000)を記入
2)msgView.cppに
 BEGIN_MESSAGE_MAP(CMsgView, CFormView)
    //{{AFX_MSG_MAP(CMsgView)
    ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
    //}}AFX_MSG_MAP
    ON_MESSAGE(WM_USER_TEST,OnUserTest)  ←これを記入

    // 標準印刷コマンド
    ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint)
            ・
END_MESSAGE_MAP()
3)msgView.hに
 // 生成されたメッセージ マップ関数
 protected:
    //{{AFX_MSG(CMsgView)
    afx_msg void OnButton1();
    //}}AFX_MSG
    afx_msg LRESULT OnUserTest(WPARAM wParam,LPARAM lParam);←これを記入

    DECLARE_MESSAGE_MAP()
4)msgView.cppに
 LRESULT CMsgView::OnUserTest(UINT wParam,LONG lParam) ←これを追加
 {
    return 0;
 }
5)Dlg_msg.cppに
 void CDlg_msg::OnButton1() 
 {
    // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
    CWnd* m_Parent;

    m_Parent=this->GetParent();

    if(m_Parent!=NULL)
    {
        m_Parent->PostMessage(WM_USER_TEST,0x5678,0x1234);
    }
 }

以上のように実装しているのですが何かまずい点がありましたらご指摘願います。
長文で失礼致しました。

sugar 2002/01/31(木) 15:26:35
Viewですか...
このケースの場合、CDlg_msgの親はCMainFrameになると思います。
なので、CMsgViewにハンドラを追加しても、反応しないのではないのでしょうか。
OnUserTestをCMainFrameに実装しなおして試してみてください。

あと、
> #define WM_USER_MESSAGE (WM_USER+0x1000)
>
ということですが、
2)以降ではWM_USER_TESTというメッセージを使っているようです。
この食い違いもあるとか?

ゆうじ 2002/01/31(木) 15:52:24
sugarさんありがとうございました。
>Viewですか...
>このケースの場合、CDlg_msgの親はCMainFrameになると思います。
>なので、CMsgViewにハンドラを追加しても、反応しないのではないのでしょうか。
>OnUserTestをCMainFrameに実装しなおして試してみてください。
上記やり方でうまくいきました。

>Viewですか...
何しろ何をお伝えすればいいのかもよくわからなくて申し訳ありません。

>> #define WM_USER_MESSAGE (WM_USER+0x1000)
>>
>ということですが、
これは、掲示板に載せる時に書き間違えました。

あと、追加で申し訳ないのですが例えばViewクラスにあるエディットボックス値
をメッセージを投げて変更するとすればどのようにViewクラスのポインタを
取得すればいいのでしょうか?
具体的なアプリケーションとしては、子ダイアログで値を入力し、あるボタンが
押されたらメインWindowのエディットボックスの値を変更するというような
ものです。
それから、何かVC++に関して技術的にわかりやすい本があったら教えていただきたい
のですが・・。

度重なるたくさんの質問申し訳ありませんがよろしくお願いします。

sugar 2002/01/31(木) 17:35:02
> 例えばViewクラスにあるエディットボックス値
> をメッセージを投げて変更するとすればどのようにViewクラスのポインタを
> 取得すればいいのでしょうか?
> 
これまでの話の経緯を踏まえ、CMainFrameからViewクラスを取得する方法でよいですか?
(特に明記されていないようなので、SDIだと仮定して、)
CFrameWnd::GetActiveView()が使えると思います。
戻り値はCView*なので、CMsgView*にキャストしてあげてください。

> 具体的なアプリケーションとしては、子ダイアログで値を入力し、あるボタンが
> 押されたらメインWindowのエディットボックスの値を変更するというような
> ものです。
> 
アプリケーションにもよりますが、
この手のインタフェースは、ダイアログで色々入力させ、
OKボタン押下でダイアログを終了させた時に親画面に反映させる、
というパターンが多いようです。

> それから、何かVC++に関して技術的にわかりやすい本があったら教えていただきたい
> のですが・・。
> 
そうですね、本に関しては、仮に私が「よい」と感じた本でも、
他の人が「よい」と感じるとは限りませんからね...
一応個人的には、林晴比古氏の本によくお世話になっています。
SOFTBANK社から出版されているものが多いようです。
ただ書籍は、あくまで基本をサポートする目的で利用したほうがいいです。
応用編は、Webサイトからサンプルをダウンロードして解析する方法をお勧めします。

ゆうじ 2002/01/31(木) 17:47:21
[[解決]]
Sugarさんありがとうございました。
VC++を周りでいじれる人が誰もいなくて非常に心細い&わけわからない状態で
やっていて、どうしようと思っていたのですが非常にありがたかったです。

何冊か本も読んでみたのですが、そこに書いてあることはわかるのですが実際
プログラムを自分で書いていこうとするとつまずいていたので・・・。

>他の人が「よい」と感じるとは限りませんからね...
>一応個人的には、林晴比古氏の本によくお世話になっています。
>SOFTBANK社から出版されているものが多いようです。
>ただ書籍は、あくまで基本をサポートする目的で利用したほうがいいです
>応用編は、Webサイトからサンプルをダウンロードして解析する方法をお勧めします。
確かにそうかもしれませんね。会社でMSDNに入っていいことになったので
気合をいれてサンプル等を一杯見てみることにします。

いろいろありがとうございました。
また、わからないことがあればよろしくお願いいたします。

古いスレッドには追加発言できません。