>  기사  >  운영 및 유지보수  >  Win32 SDK 기본 사항(10) 몇 가지 일반적인 Windows 메시지 처리 샘플 코드에 대한 자세한 설명

Win32 SDK 기본 사항(10) 몇 가지 일반적인 Windows 메시지 처리 샘플 코드에 대한 자세한 설명

黄舟
黄舟원래의
2017-06-06 10:07:473062검색

소개

이 글에서는 주로 몇 가지 일반적인 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 메시지

앞서 소개했듯이 프로그램 프로세스를 종료하기 위해 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도 창이지만 우리 프로세스에 속하기 때문입니다. 각 창에는 메시지 루프가 있지만 프로세스당 하나의 메시지 큐만 있습니다. MessageBox 창이 닫히면 해당 창 처리 함수도 PostQuitMessage(0)를 호출하여 WM_QUIT 메시지를 보냅니다. 메시지 루프에서 GetMessage는 WM_QUIT 메시지를 받은 후 반환되고 종료됩니다. 이 메시지는 메시지 루프에 의해 캡처되지만 창에서 보낸 메시지가 아니기 때문에 GetMessage가 루프를 종료하기 위해 반환되지는 않습니다. 대신에 전달된 창 처리 함수에 의해 요약되고 처리됩니다. 위의 스크린샷과 같은 대화 상자가 나타납니다.

5. WM_SYSCOMMAND 메시지

시스템 명령 메시지는 최대화, 최소화 및 닫기 명령을 클릭하면 트리거됩니다(따라서 닫기 버튼을 클릭하면 WM_DESTROY 및 WM_SYSCOMMAND 메시지가 동시에 트리거됩니다). wParam 매개변수는 특정 창 작업을 수행합니다:

Close:

SC_CLOSE

Maximize: SC_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消息

        每当我们调整窗口的大小时,都会触发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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.