antenn-a
company profile

MFC航海日記 十七日目(ユーザメッセージ 其の弐)

さて、今日は前回のユーザメッセージの実相方法を解説します。お相手は元評論家の・・・・(謎)
・・・・元気に行きましょう!

メッセージを投げるときには「メッセージ番号」を用意しなければなりません。 受け取った側はこの「メッセージ番号」を見て、どのようなメッセージがを判別しています。 実はもうすでに「ユーザメッセージ」の番号は用意されています。 と、言うのは勝手気ままにメッセージを投げてしまうと他のメッセージ番号と重なったときにおかしな事になるからです。 例えば、滅茶苦茶に投げたメッセージ番号がダイアログの終了を意味する番号だったら? と、言う感じです。 ユーザが勝手につけても良い番号は「WM_USER + ???」です。 ですので、例えばテストメッセージを投げる場合などは、下記のようにすれば良いでしょう。


prev

#define    WM_TESTMSG_1    WM_USER + 100

#define    WM_TESTMSG_2    WM_USER + 101

このようにしておけば自分で間違えない限り他のメッセージを妨害する事は有りません。

では、実際にメッセージを投げてみましょう。 「EButton」の「WM_MOUSEMOVE」イベント中に下記のコードを追加します。


#define   WM_MOUSEMOVE_ONBTN    
WM_USER + 100

void EButton::OnMouseMove(UINT nFlags, CPoint point) 

{

GetParent()->SendMessage
( WM_MOUSEMOVE_ONBTN, ButtonNo );

CButton::OnMouseMove(nFlags, point);

}
まず、WM_MOUSEMOVE_ONBTNメッセージ番号を定義します。
そして、関数中でSendMessage()を呼び出します。
この関数がメッセージを投げる関数です。
今回はメッセージを親に向かって投げるので、GetParent()->となっています。
GetParent()は親のウィンドウハンドルを取得する関数です。
SendMessageの第一引数がメッセージ番号です。
SendMessage関数は、このほかにもう一つ引数を渡す事ができます。
今回の「ButtonNo」は「short」型のメンバーです。
今回の場合はあらかじめ登録しておくべき「ボタンの識別番号」を送ります。
ButtonNoは「EButton」クラスに自分で追加したメンバーで、ボタンの識別番号を登録しておきます。
登録は親ダイアログの「OnInitDialog」関数中でm_Btn・・・.ButtonNo = 1とか2と言う風にして登録しておきます。
こうする事でボタン一つ一つに番号を付けられます。
また、送る際に識別番号を送れば、受け取った際に何番ボタンの上にマウスが有るか分かります。

prev

次に受け取り側です。
受け取り側は4個所付け足さなければなりません。 ●親ダイアログのヘッダファイルを開いてください。 半透明のような薄い色で、「afx_msg void OnPaint();」と書かれている部分が有ると思います。 この領域の一番下に自分が投げたメッセージを受け取ったときに呼ばれる関数名を登録します。 ここでは下記のようにしました。

// インプリメンテーション

protected:

HICON m_hIcon;

// 生成されたメッセージ マップ関数

//{{AFX_MSG(CMessageSampleDlg)

virtual BOOL OnInitDialog();

afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

afx_msg void OnPaint();

afx_msg void OnMouseMoveOnBtn( LPARAM lParam );

afx_msg HCURSOR OnQueryDragIcon();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

}
付け加えたのは「afx_msg void OnMouseMoveOnBtn( LPARAM lParam );」の部分です。 このLPARAM型のlParamに先ほどの「SendMessage」関数の第二引数「ButtonNo」が入ります。

●次に親ダイアログのCPPファイルを開いてください。 まずやらなければならない事はメッセージ番号を定義する事です。ファイルの上のほうに


#define   WM_MOUSEMOVE_ONBTN
WM_USER + 100

を付け足してください。

●次にメッセージの受け皿を用意します。

BEGIN_MESSAGE_MAP
(CMessageSampleDlg, CDialog)

・・・・

END_MESSAGE_MAP()
上記のような部分が有ると思います。 BEGIN・・・とEND・・・の間に書かれているものがこのダイアログでメッセージを受け取るものです。 画面を再描画するときに呼ばれる「ON_WM_PAINT」等が有ると思います。 ここに自分で投げたメッセージを受け取るときの受け皿を用意します。

BEGIN_MESSAGE_MAP(CMessageSampleDlg, CDialog)

//{{AFX_MSG_MAP
(CMessageSampleDlg)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

ON_MESSAGE
(WM_MOUSEMOVE_ON_BTN, OnMouseMoveOnBtn)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()
付け足したのは、「ON_MESSAGE(WM_MOUSEMOVE_ON_BTN, OnMouseMoveOnBtn)」です。 ユーザメッセージを受け取るときには必ずON_MESSAGEと書きます。 第一引数がメッセージ番号。 第二引数がメッセージが来たときに呼び出す関数名です。

●最後にファイルの一番下に関数の実相部を追加します。 今はテストとして、ボタンの上にマウスが乗るとメッセージボックスを出すようにします。


void CMessageSampleDlg::OnMouseMoveOnBtn( LPARAM lparam )

{

MessageBox( "やったね!大成功!",
"初めてのユーザメッセージ", MB_OK );

}
こんな感じでしょうか。 ここまできたらコンパイル・実行してみてください。 ボタンの上にマウスを持っていくとメッセージボックスが出るはずです。 でない場合は、よく確認してください。
  • 自前のボタンクラス(EButton等)を作りましたか?

  • 親ダイアログ上のボタンにメンバーを割り当てましたか?

  • 親ダイアログのヘッダファイルの中で「EButton」はincludeされてますか?

  • 親ダイアログのヘッダファイルの中で「CButton」から「EButton」のオブジェクトに変更しましたか?

  • 本当に私の言った通りにやりましたか?(笑)

もしそれでもできない場合は、私にメールをください。(ファイルを付けてくださいね)

メッセージボックスが出た事を前提に話を進めます。 すると今度は・・・ともう分かりますよね。 後は「lParam」にしたがってスタティックテキストを書き換えるだけです。


prev

さて、ユーザメッセージどうだったでしょうか? この知識はWindowsプログラムをやって行けば必ずぶつかるものです。 がんばって物にしてください。

今回のサンプルプログラムはここからダウンロードできます。
(注)このサンプルコードには嘘が含まれているためダウンロード中止しました。詳しくは19日目を参照のこと(^^;;;;



antenn-a

prev next


antenn-a