// // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); // TODO: HDC を使用する描画コードをここに追加してください... EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
ここが処理の心臓部といっても過言ではない箇所。 メニューをクリックしたら何をするか、キーボードを叩いたら何をするかと 処理の機能をほとんど実装、または分岐する関数だ。 RegisterClassExWで、ウィンドウプロシージャを登録した関数はここである。 また、DispatchMessageによって呼ばれる関数でもある。
このコードと実際動作したアプリを比べると何となくわかると思う。 まず、上から見ていくと「WM_COMMAND」というメッセージを受け取ったら メニューバーから選択した項目を受け取って処理をしていることが分かると思う。 「WM_PAINT」は、何も実装していないが、クライアント領域を描画するところ。 「WM_DESTORY」はDestroyWindowなどによって呼ばれるようになる終了処理。 PostQuitMessageでOSに終了通知、wWinMainのGetMessageのループを抜けることになる。 DefWindowProcは、OSが標準的にメッセージに対する処理を行う関数。
// バージョン情報ボックスのメッセージ ハンドラーです。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
この関数は、バージョン情報ダイアログを処理するWindowPorcのような関数。
WM_INITDIALOGは、ダイアログが生成されたときに受け取るメッセージ。 WM_COMMANDは、メニューではなく、ボタンに対してのメッセージ。 EndDialogは、バージョンダイアログを破棄する関数。
これで、自動生成したソースの主要部を一通り見てみた。 これをベースに改造を試みる。