이 글에서는 주로 몇 가지 일반적인 Windows 메시지 처리를 소개합니다. "Win32 SDK 기본 사항(8) - Windows 메시지 메커니즘"에서는 창이 생성되기 전에 메시지 처리를 사용합니다. function은 이를 기반으로 WM_DESTROY, WM_SYSCOMMAND, WM_QUIT, WM_SIZE 등과 같은 다른 일반적인 Windows 메시지를 소개합니다. 먼저, 우리는 SDK 기초(8) - Windows 메시지 메커니즘'이 기사의 코드이며 후속 실험은 이 코드를 기반으로 합니다.
#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 메시지를 소개하고 싶습니다. 이전 기사에서는 MessageBox를 팝업하여 WM_CREATE 메시지의 타이밍만 확인했지만 다른 매우 중요한 구성 요소인 WPARAM 및 LPARAM 매개 변수는 소개하지 않았기 때문입니다. 메시지
를 보낼 때 종종 이 두 매개변수를 통해 일부 정보를 전달할 수 있습니다. WM_CREATE 메시지는 창을 생성할 때 시스템이 자동으로 보내는 메시지이며, 이 두 매개변수는 정보를 전달하는 데에도 사용됩니다. LPARAM은 창을 만들 때 CreateWindowEx의 12개 매개 변수 정보를 전달합니다. WPARAM은 사용되지 않습니다. 다음으로 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);
}
프로그램을 실행하면 창이 생성되기 전에 등록된 창 클래스 이름과 창 이름을 성공적으로 캡처하여 대화 상자에 표시한 것을 발견했습니다.
3. WM_DESTROY 메시지
을 클릭하면 이 메시지가 보내집니다. 이전 코드에서 이 메시지를 처리하는 작업은 PostQuitMessage(0)였습니다. 이는 실제로 프로그램 프로세스를 종료하기 위해 다음에 소개될 WM_QUIT 메시지를 보냈다는 것을 의미합니다. WM_DESTORY 메시지의 LPARAM이나 WPARAM은 일반적으로 창이 닫히기 전에 일부 리소스 재활용 및 메모리 해제를 수행하는 데 사용됩니다. PostQuitMessage(0)는 매우 일반적인 사용법입니다. 4. 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도 창이지만 우리 프로세스에 속하기 때문입니다. 각 창에는 메시지 루프가 있지만 프로세스당 하나의 메시지 큐만 있습니다. MessageBox 창이 닫히면 해당 창 처리 함수도 PostQuitMessage(0)를 호출하여 WM_QUIT 메시지를 보냅니다. 메시지 루프에서 GetMessage는 WM_QUIT 메시지를 받은 후 반환되고 종료됩니다. 이 메시지는 메시지 루프에 의해 캡처되지만 창에서 보낸 메시지가 아니기 때문에 GetMessage가 루프를 종료하기 위해 반환되지는 않습니다. 대신에 전달된 창 처리 함수에 의해 요약되고 처리됩니다. 위의 스크린샷과 같은 대화 상자가 나타납니다.5. WM_SYSCOMMAND 메시지
시스템 명령 메시지는 최대화, 최소화 및 닫기 명령을 클릭하면 트리거됩니다(따라서 닫기 버튼을 클릭하면 WM_DESTROY 및 WM_SYSCOMMAND 메시지가 동시에 트리거됩니다). wParam 매개변수는 특정 창 작업을 수행합니다:
SC_CLOSEMaximize: SC_MAXIMIZE
Minimize: SC_MINIMIZE 这里只列举了三种常见的WM_SYSCOMMAND携带的参数宏,其它的可以参照MSDN。WM_SYSCOMMAND的lParam携带的是产生该消息的鼠标的位置,位置的X和Y坐标分别被存放在lParam的低位和高位字中,我们用下面的代码来验证在窗口最大化时,我们鼠标的位置: 当我们点击窗口的最大化按钮时,出现下面的提示: 每当我们调整窗口的大小时,都会触发WM_SIZE消息。它的wParam参数携带的是该消息产生的原因: SIZE_RESTORED —— 重新调整窗口大小 SIZE_MAXIMIZED —— 最大化显示 SIZE_ MINIMIZED —— 最小化显示 其他参数宏详见MSDN 它的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消息
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!