- 追加された行はこの色です。
- 削除された行はこの色です。
メッセージハンドラについて取り扱います
今回はメッセージクラッカーについて取り扱います
メッセージクラッカーはメッセージを横取りするという意味です
メッセージクラッカーを使うことでメッセージの処理がやりやすくなります
次のウィンドウプロシージャをメッセージクラッカーで書きなおします
//-----------------------------------------------------//
// ウィンドウプロシージャ
// デフォルトの処理はDefWindowProc関数で行う
//
// 引数: hWnd ウィンドウハンドル
// msg メッセージ
// wParam パラメータ
// lParam パラメータ
//
// 戻り値:処理結果
//-----------------------------------------------------//
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg){
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
メッセージクラッカーを使って書きなおすと次のようになります
//------------------------------------------------------//
// ウィンドウ破棄メッセージ処理
//
// 引数: hWnd ウィンドウハンドル
//------------------------------------------------------//
void OnDestroy(HWND hWnd){
PostQuitMessage(0);
}
//-----------------------------------------------------//
// ウィンドウプロシージャ
// デフォルトの処理はDefWindowProc関数で行う
//
// 引数: hWnd ウィンドウハンドル
// msg メッセージ
// wParam パラメータ
// lParam パラメータ
//
// 戻り値:処理結果
//-----------------------------------------------------//
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg){
HANDLE_MSG(hWnd,WM_DESTROY,OnDestroy);
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
ここで
HANDLE_MSGというのがメッセージクラッカーと呼ばれるマクロです
使い方は
HANDLE_MSG(ウィンドウハンドル、メッセージの種類、メッセージを処理する関数)
のように使います
HANDLE_MSGで右クリックし、定義へ移動してください
&ref(messagecrack.GIF);
windowsx.hヘッダーに次のように定義されています
#define HANDLE_MSG(hwnd, message, fn) \
case (message): return HANDLE_##message((hwnd), (wParam), (lParam), (fn))
ここで
\は改行されていても一行として認識するために付けてあります
##というマクロはmessageの名前を連結します
つまり、
HANDLE_MSG(hWnd,WM_DESTROY,OnDestroy);
は
case (WM_DESTROY): return HANDLE_WM_DESTROY((hWnd), (wParam), (lParam), (OnDestroy));
のように展開されます
さらに、
編集→検索と置換→クイック検索
もしくはCTRL+Fでwindowsx.hを次のように検索してください
&ref(messagecrack2.GIF);
HANDLE_WM_DESTROYはwindowsx.hに次のように定義されています
/* void Cls_OnDestroy(HWND hwnd) */
#define HANDLE_WM_DESTROY(hwnd, wParam, lParam, fn) \
((fn)(hwnd), 0L)
それをさらに展開したのが最終的な展開結果です
case WM_DESTROY:return ((OnDestroy)(hWnd),0);
HANDLE_WM_DESTROYのように
他のメッセージも同様に「HANDLE_なんとか」とwindowsx.h内に定義がされています
ここで話がそれますが
((OnDestroy)(hWnd),0)
はどうゆう意味でしょうか
「,」はカンマ演算子とよばれ
a = (x, y, z);
とやるとx,y,zと順番に評価され
aには、zが代入されます
つまり、ここでの場合はOnDestroy関数が評価(実行)され、ウィンドウプロシージャの戻り値に0が返ります
では、メッセージクラッカーを使うためにはメッセージごとに
どのような関数を用意してやればいいでしょうか?
答えは
/* void Cls_OnDestroy(HWND hwnd) */
に書いてあるような
引数と戻り値を持つ関数を用意してやればよいことになります
つまり、WM_DESTROYに対しては
void OnDestroy(HWND hWnd)
という関数を用意しました
つまり、基本的にコメントアウトに書いてある関数を作成し
その関数を渡せば、メッセージクラッカーを使うことができます
このようにメッセージクラッカーを使うときは逆引き的に調べます
メッセージクラッカーを使う利点は
メッセージごとに処理をわけることができるので
ウィンドウプロシージャに長々メッセージ処理のコードを書かずに済むという利点があります
また、メッセージのパラメータがメッセージごとに適切な型で明記されているので
メッセージ処理がしやすいという利点があります
全ソースコードは下から
&ref(main.cpp);
|(^ω^)やったお|2|
|何これwww意味不すぎwww|6|
|。(`ω´#)。あぁん?最近、だらしねぇな|0|