MainFrmクラスからViewクラスへメッセージを送信する




MainFrmクラスからViewクラスへとメッセージを通知する方法です。
ただし、この方法ではデータ部のサイズが大きい場合は不向きですので注意して下さい。

1.メッセージIDを定義します。
プロジェクトの共通インクルードにメッセージIDのdefineを定義します。
WindowsではWM_USERというdefineがあらかじめ定義されており、その値から0x7FFFまでを 使ってもいいことになっています。
なぜか、WM_USER+100から使う事が暗黙の了解になっているらしいので、その通りに 定義します。

(サンプル)
//メッセージID定義
#define  D_MSG_FileOpen      WM_USER + 100

2.次にメッセージを受信した時に実行される関数のプロトタイプをヘッダファイルに 定義します。
(File:WinTailView.h)
// 生成されたメッセージ マップ関数
protected:
    //{{AFX_MSG(CWinTailView)
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    //}}AFX_MSG
    // ファイルオープン通知
    afx_msg void FileOpenOK( WPARAM, LPARAM );
    DECLARE_MESSAGE_MAP()
};

3.そして、メッセージマップに追加したいメッセージIDを登録します。
サンプルではD_MSG_FILEOPENを受信した場合はFileOpenOK()関数をコールします。
(File:WinTailView.cpp)
BEGIN_MESSAGE_MAP(CWinTailView, CEditView)
//{{AFX_MSG_MAP(CWinTailView)
    ON_WM_CREATE()
    ON_WM_RBUTTONDOWN()
    ON_WM_LBUTTONDOWN()
    //}}AFX_MSG_MAP
    // 標準印刷コマンド
    ON_COMMAND(ID_FILE_PRINT, CEditView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, CEditView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CEditView::OnFilePrintPreview)
    // ファイルオープン通知
    ON_MESSAGE(D_MSG_FILEOPEN, FileOpenOK)
END_MESSAGE_MAP()

4.メッセージ受信時に実行される関数を定義します。
(File:WinTailView.cpp)
// ファイルオープン通知受信処理
void CWinTailView::FileOpenOK( WPARAM wParam, LPARAM lParam )
{
    GetEditCtrl().ReplaceSel("File Open",FALSE );
}

5.Viewクラスのウィンドウハンドラを取得します。
ViewクラスのOnCreate時にウィンドウハンドラ取得処理を追加します。
ウィンドウハンドラは外部変数定義しておき、MainFrmクラスからも参照できる ようにしておいてください。
(File:WinTailView.cpp)
int CWinTailView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CEditView::OnCreate(lpCreateStruct) == -1)
        return -1;

    // TODO: この位置に固有の作成用コードを追加してください
    // Viewクラスのウィンドウハンドラを取得する
    E_WinHdl_View = GetSafeHwnd();
}

6.メッセージ送信処理を追加します。
メッセージ送信にはSendMessage()関数を使います。
SendMessage()関数の前にある::が無いと引数不正でコンパイルエラーになります。
::を付けない場合は第一引数のウィンドウハンドルを省略できるらしいのですが、 そうした場合なぜかViewクラスでメッセージを受信してくれません。
第二引数はメッセージIDを指定します。
第三、第四引数はViewクラスでコールされる関数(FileOpenOK)へ渡す引数が入ります。 サンプルでは指定していませんが、指定した場合はそれぞれ受け側関数のWPARAMとLPARAM で参照が可能になります。
SendMessage()関数と同じような関数にPostMessage()関数があるのですが、こちらにすると なぜか、Viewクラスでの受信ができませんでした。ただし、ワーカスレッドを作成して 親スレッドとワーカスレッド間ではPostMessage()関数で動作したので、そこらへんに なにか秘密がある気がします。
(File:MainFrm.cpp)
    // Viewクラスへファイルがオープンされた事を通知する
    Bool_Ret = ::SendMessage( E_WinHdl_View, D_MSG_FILEOPEN, NULL, NULL );




N総研ソフトウェア開発部のTOPに戻る。

このページに関するご意見・質問は
ドンタコスN村 E-mail:wnaka@coco.ned.co.jp
まで送信してください。