#include "stdafx.h" #include "MessageTs.h" HINSTANCE g_hInstance = 0; //窗口处理函数 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 break; case WM_CREATE: MessageBox(NULL,"WM_CREATE消息被处理了","消息处理",MB_OK); default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } //注册窗口类 BOOL Register(LPSTR lpClassName, WNDPROC wndProc) { WNDCLASSEX wce = { 0 }; wce.cbSize = sizeof(wce); wce.cbClsExtra = 0; wce.cbWndExtra = 0; wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wce.hCursor = NULL; wce.hIcon = NULL; wce.hIconSm = NULL; wce.hInstance = g_hInstance; wce.lpfnWndProc = wndProc; wce.lpszClassName = lpClassName; wce.lpszMenuName = NULL; wce.style = CS_HREDRAW | CS_VREDRAW; ATOM nAtom = RegisterClassEx(&wce); if (nAtom == 0) return FALSE; return true; } //创建主窗口 HWND CreateMain(LPSTR lpClassName, LPSTR lpWndName) { HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, g_hInstance, NULL); return hWnd; } //显示窗口 void Display(HWND hWnd) { ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); } //消息循环 void Message() { MSG nMsg = { 0 }; while (GetMessage(&nMsg, NULL, 0, 0)) { TranslateMessage(&nMsg); DispatchMessage(&nMsg); } } int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { // TODO: Place code here. g_hInstance = hInstance; BOOL nRet = Register("Main", WndProc); if (!nRet) { MessageBox(NULL, "注册失败", "Infor", MB_OK); return 0; } HWND hWnd = CreateMain("Main", "window"); Display(hWnd); Message(); return 0; }2. WM_CREATE メッセージ WM_CREATE メッセージについても紹介したいと思います。前回の記事では、メッセージ ボックスをポップアップ表示して WM_CREATE メッセージのタイミングを検証しただけで、その他の非常に重要なコンポーネントである WPARAM パラメーターと LPARAM パラメーターについては紹介しなかったためです。メッセージを送信するとき、多くの場合、これら 2 つのパラメーターを通じて何らかの情報を伝えることができます。 WM_CREATE メッセージは、ウィンドウの作成時にシステムによって自動的に送信されるメッセージであり、これら 2 つのパラメーターは情報を伝えるためにも使用されます。 LPARAM は、WPARAM を使用せずに作成したときの CreateWindowEx の 12 個のパラメータ情報を保持します。次に、WM_CREATE メッセージを処理するときに、ポップアップ ダイアログ ボックスにウィンドウ クラスとウィンドウ名を表示します。
//窗口处理函数 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 break; case WM_CREATE: { CREATESTRUCT crt = *((CREATESTRUCT*)lParam); char buf[256] = {0}; sprintf(buf,"创建的窗口类名称是%s,窗口名称是%s",crt.lpszClass,crt.lpszName); MessageBox(NULL, buf, "消息处理", MB_OK); } default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }
をクリックすると、このメッセージが送信されます。前のコードでは、このメッセージを処理する操作は PostQuitMessage(0) でした。これは実際には、次に導入される WM_QUIT メッセージを送信してプログラム プロセスを終了することを意味します。 WM_DESTORY メッセージの LPARAM も WPARAM も使用されません。通常、ウィンドウを閉じる前にリソースのリサイクルとメモリの解放を行うために使用されます。PostQuitMessage(0) は非常に一般的な使用法です。
4. WM_QUIT メッセージ すでに紹介したように、これはプログラムのプロセスを終了するために PostQuitMessage(0) を使用して送信するメッセージです。その WMPARAM は PostQuitMessage で渡されるパラメーターであり、LPARAM パラメーターは使用されません。通常、WM_QUIT を送信すると、メッセージ ループ内の GetMessage 関数が戻り、プロセスが終了します。 WM_QUIT メッセージを独自のウィンドウ処理関数に渡すことはできません。しかし、そのようなメッセージがあることを側から確認できます。まず、コードに WM_QUIT メッセージの処理を追加します。LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 break; case WM_CREATE: { CREATESTRUCT crt = *((CREATESTRUCT*)lParam); char buf[256] = {0}; sprintf(buf,"创建的窗口类名称是%s,窗口名称是%s",crt.lpszClass,crt.lpszName); MessageBox(NULL, buf, "消息处理", MB_OK); } case WM_QUIT: { int param = (int)wParam; char buf[256]; sprintf(buf, "进程退出,退出码:%d", param); MessageBox(NULL, buf, "消息处理", MB_OK); } default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }プログラムを実行すると、WM_CREATE メッセージを処理するためのダイアログ ボックスを閉じた後、WM_QUIT メッセージを確認するためのダイアログ ボックスがポップアップ表示されることがわかりました。
これは、WM_CREATE メッセージを処理するためにポップアップする MessageBox もウィンドウですが、私たちのプロセスに属しているためです。各ウィンドウにはメッセージ ループがありますが、メッセージ キューはプロセスごとに 1 つだけです。MessageBox ウィンドウが閉じられると、そのウィンドウ処理関数も PostQuitMessage(0) を呼び出して WM_QUIT メッセージを送信します。メッセージ ループでは、GetMessage は WM_QUIT メッセージを受信した後に戻り、終了します。このメッセージはメッセージ ループによってキャプチャされますが、ウィンドウによって送信されたメッセージではないため、ループを終了するために GetMessage が返されることはなく、代わりに渡されたウィンドウ処理関数によって要約されて処理されます。上のスクリーンショットに示すダイアログ ボックスが表示されます。 5. WM_SYSCOMMAND メッセージ
システム コマンド メッセージ。このメッセージは、最大化、最小化、および閉じるコマンドをクリックするとトリガーされます (したがって、閉じるボタンをクリックすると、WM_DESTROY メッセージと WM_SYSCOMMAND メッセージの両方が同時にトリガーされます)。その wParam パラメータには特定のウィンドウ操作が含まれます:
Close:SC_CLOSE
Maximize:Minimize: SC_MINIMIZE
这里只列举了三种常见的WM_SYSCOMMAND携带的参数宏,其它的可以参照MSDN。WM_SYSCOMMAND的lParam携带的是产生该消息的鼠标的位置,位置的X和Y坐标分别被存放在lParam的低位和高位字中,我们用下面的代码来验证在窗口最大化时,我们鼠标的位置:
case WM_SYSCOMMAND: { if (wParam == SC_MAXIMIZE) { short x = LOWORD(lParam); short y = HIWORD(lParam); char buf[256]; sprintf(buf, "窗口最大化,x坐标:%d,y坐标:%d", x,y); MessageBox(NULL, buf, "消息处理", MB_OK); } }
当我们点击窗口的最大化按钮时,出现下面的提示:
每当我们调整窗口的大小时,都会触发WM_SIZE消息。它的wParam参数携带的是该消息产生的原因:
SIZE_RESTORED —— 重新调整窗口大小
SIZE_MAXIMIZED —— 最大化显示
SIZE_ MINIMIZED —— 最小化显示
其他参数宏详见MSDN
它的lParam参数携带的是重新调整大小后的窗口的高和宽,其中低字节代表宽,高字节代表高,这里我们通过代码验证,当窗口最大化后窗口的高和宽:
case WM_SIZE: { if (wParam == SIZE_MAXIMIZED) { short width = LOWORD(lParam); short hight = HIWORD(lParam); char buf[256]; sprintf(buf, "窗口最大化,高度:%d,宽度:%d", hight, width); MessageBox(NULL, buf, "消息处理", MB_OK); } }
运行程序,最大化时可以显示最大化后的窗口高度和宽度:
以上がWin32 SDK の基礎 (10) いくつかの一般的な Windows メッセージ処理サンプル コードの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。