今回はメッセージクラッカーについて取り扱います
メッセージクラッカーはメッセージを横取りするという意味です
メッセージクラッカーを使うことでメッセージの処理がやりやすくなります
次のウィンドウプロシージャをメッセージクラッカーで書きなおします

	//-----------------------------------------------------//
	//	ウィンドウプロシージャ
	//	デフォルトの処理は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);

#vote((^ω^)やったお[1],何これwww意味不すぎwww[2],。(`ω´#)。あぁん?最近、だらしねぇな[0])
#vote((^ω^)やったお[1],何これwww意味不すぎwww[4],。(`ω´#)。あぁん?最近、だらしねぇな[0])


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS