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

	//-----------------------------------------------------//
	//	ウィンドウプロシージャ
	//	デフォルトの処理は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で右クリックし、定義へ移動してください
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を次のように検索してください
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)

という関数を用意しました

つまり、基本的にコメントアウトに書いてある関数を作成し
その関数を渡せば、メッセージクラッカーを使うことができます
このようにメッセージクラッカーを使うときは逆引き的に調べます

メッセージクラッカーを使う利点は
メッセージごとに処理をわけることができるので
ウィンドウプロシージャに長々メッセージ処理のコードを書かずに済むという利点があります
また、メッセージのパラメータがメッセージごとに適切な型で明記されているので
メッセージ処理がしやすいという利点があります

全ソースコードは下から
filemain.cpp

選択肢 投票
(^ω^)やったお 1  
何これwww意味不すぎwww 5  
。(`ω´#)。あぁん?最近、だらしねぇな 0  

添付ファイル: filemain.cpp 318件 [詳細] filemessagecrack2.GIF 237件 [詳細] filemessagecrack.GIF 291件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-10-11 (水) 19:51:56