|
今回はメッセージクラッカーについて取り扱います //-----------------------------------------------------//
// ウィンドウプロシージャ
// デフォルトの処理は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(ウィンドウハンドル、メッセージの種類、メッセージを処理する関数) のように使います 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)); のように展開されます 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のように ここで話がそれますが 「,」はカンマ演算子とよばれ では、メッセージクラッカーを使うためにはメッセージごとに /* void Cls_OnDestroy(HWND hwnd) */ に書いてあるような つまり、WM_DESTROYに対しては void OnDestroy(HWND hWnd) という関数を用意しました つまり、基本的にコメントアウトに書いてある関数を作成し メッセージクラッカーを使う利点は 全ソースコードは下から
|