>  기사  >  운영 및 유지보수  >  Win32 SDK 기초 (11) 메시지 큐 및 GetMessage/PeekMessage, SendMessage/Postmesage에 대한 자세한 설명

Win32 SDK 기초 (11) 메시지 큐 및 GetMessage/PeekMessage, SendMessage/Postmesage에 대한 자세한 설명

黄舟
黄舟원래의
2017-06-06 10:09:435605검색

1. MessageQueue

1.1 메시지 대기열

메시지 대기열은 메시지를 저장하는 데 사용되는 대기열입니다. 모든 창 프로그램에는 메시지 대기열이 있으며 프로그램은 메시지를 얻을 수 있습니다. 대기열.

1.2 메시지 대기열 유형

시스템 메시지 대기열: 운영 체제에서 유지 관리하는 메시지 대기열로, 마우스 및 키보드 메시지 등과 같이 시스템에서 생성된 메시지를 저장합니다.

프로그램 메시지 큐: 각 애플리케이션(스레드)에 속하며 애플리케이션에 의해 유지되는 메시지 큐입니다.

마우스, 키보드 등의 메시지가 발생하면 먼저 시스템 메시지 큐에 메시지가 저장되고, 운영체제는 저장된 메시지를 기반으로 해당 창의 메시지 큐를 찾아 메시지를 시스템 메시지 큐에 전달한다. 창의 메시지 큐.

1.3 대기열 메시지 및 대기열이 아닌 메시지

대기열 메시지: 메시지가 전송된 후 먼저 대기열에 들어간 다음 메시지 루프 를 통해 획득됩니다. 일반적인 대기열 메시지: 키보드, 마우스, timer메시지 등

비대기열 메시지: 메시지 전송 후 창의 메시지 처리 기능을 직접 찾아 메시지 대기열을 거치지 않고 메시지 처리 기능을 호출하여 처리합니다. 일반적인 비큐 메시지: WM_PAINT, WM_SIZE 등

2. 메시지 루프 및 GetMessage/PeekMessage

2.1 메시지 루프

일반적인 메시지 루프는 다음과 같습니다.

void Message(HWND hWnd)  
{  
	MSG nMsg = { 0 };
	while (GetMessage(&nMsg, hWnd, 0, 0))  
	{  
		TranslateMessage(&nMsg);  
		DispatchMessage(&nMsg);  

		if(nMsg.message == WM_PAINT)
		{
			char buff[30]={};
			sprintf(buff,"处理消息%d\n",nMsg.message);
			WriteConsole(hOutput,buff,sizeof(buff),NULL,NULL);
		}
	}  
}

GetMessage/PeekMessage: 프로그램의 메시지 대기열에서 메시지를 가져옵니다.

TranslateMessage: 키보드의 키 누르기 등의 메시지를 문자 메시지로 번역합니다.

DispatchMessage: 번역된 메시지를 프로그램의 메시지 대기열에 다시 넣습니다.

2.2 GetMessage 및 PeekMessage

GetMessage(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax
)

lpMsg: 스레드의 메시지 대기열에서 메시지 정보를 받는 MSG 구조에 대한 포인터입니다. hWnd: 메시지를 얻은 창의 핸들입니다. 값이 NULL이면 GetMessage는 호출 스레드에 속한 모든 창에 대한 메시지를 검색하고 스레드 메시지는 PostThreadMessage를 통해 호출 스레드로 전송됩니다. wMsgFilterMin: 검색할 최소 메시지 값을 지정하는
정수
입니다. wMsgFilterMax: 검색할 최대 메시지 값을 지정하는 정수입니다. 반환 값: 함수가 WM_QUIT 이외의 다른 메시지를 받으면 0이 아닌 값을 반환합니다. 함수가 WM_QUIT 메시지를 받으면 반환 값은 0입니다. 오류가 발생하면 반환 값은 -1입니다. 예를 들어 hWnd가 잘못된 창 핸들이거나 lpMsg가 잘못된 포인터인 경우입니다. 더 많은
오류 정보
를 얻으려면 GetLastError 함수를 호출하세요.

BOOL PeekMessage(
LPMSG IpMsg,
HWND hWnd,
UINT wMSGfilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg
);
lpMsg: 메시지 정보를 수신하기 위한 MSG 구조 포인터입니다.

hWnd: 메시지가 확인된 창 핸들입니다.

wMsgFilterMin: 확인할 메시지 범위의 첫 번째 메시지를 지정합니다.
wMsgFilterMax: 확인할 메시지 범위의 마지막 메시지를 지정합니다.
wRemoveMsg: 메시지 처리 방법을 결정합니다. 이 매개변수는 다음 값 중 하나를 사용할 수 있습니다.

값 의미 PM_NOREMOVE메시지는 대기열에서 제거되지 않습니다.

PM_REMOVE

PeekMessage가 처리된 후 메시지가 대기열에서 제거됩니다.

PM_NOYIELD

이 플래그는 시스템이 호출 프로그램이 유휴 상태가 될 때까지 기다리는 스레드를 해제하지 않도록 합니다. PM_NOYIELD는 PM_NOREMOVE 또는 PM_REMOVE로 자유롭게 결합될 수 있습니다.


GetMessage和PeekMessage的主要区别在于:GetMessage是阻塞函数,它会在消息循环中会一直阻塞直到消息队列中出现了消息可以被获取,而PeekMessage是非阻塞函数,不管有没有获取到消息队列中的消息,它都会返回。PeekMessage更多用来检测消息队里中是否有消息,它的最后一个参数可以用来指定获取到消息后要不要把消息从消息队列中移除,通常情况下通过PeekMessage检测到消息队列有消息之后,再调用GetMessage区获取。

2.3 GetMessage/PeekMessage获取消息的过程

1、先在程序的消息队列中查找消息,如果有队列消息,就取出消息。

2、如果程序的消息队列中没有消息,向系统的消息队列获取属于本程序的消息。如果系统的消息队列中有属于本程序的消息,系统的消息队列会将消息分发到本程序的消息队列中。

3、如果系统的消息队列也没有消息,检查窗口需要绘制的区域是否需要重绘,如果发现有需要重绘的区域,产生WM_PAINT消息。

4、如果没有重新绘制区域,检查是否具有到时的定时器,如果有产生WM_TIMER定时器消息。

5、如果没有到时的定时器,整理程序的资源、内存等等。

三、SendMessage和PostMessage

LRESULT SendMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM IParam
)

hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。
Msg:指定被发送的消息。
wParam:指定附加的消息特定信息。
IParam:指定附加的消息特定信息。

返回值:返回值指定消息处理的结果,依赖于所发送的消息。

BOOL WINAPI PostMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);

hWnd:其窗口程序接收消息的窗口的句柄。可取有特定含义的两个值:
HWND_BROADCAST:消息被寄送到系统的所有顶层窗口,包括无效或不可见的非自身拥有的窗口、 被覆盖的窗口和弹出式窗口。消息不被寄送到子窗口
NULL:此函数的操作和调用参数dwThread设置为当前线程的标识符PostThreadMessage函数一样
Msg:指定被寄送的消息。
wParam:指定附加的消息特定的信息。
LParam:指定附加的消息特定的信息。
返回值:如果函数调用成功,返回非零,否则函数调用返回值为零

1、SendMessage

       发送消息到指定的窗口,并等候对方将消息处理,为阻塞函数,获取消息的执行结果后返回。主要需要发送非队列消息,发送的消息不经过消息队列。

2、PostMessage

        发送消息到程序的消息队列,不管消息有没有被处理都会立即返回,用于队列消息的发送

위 내용은 Win32 SDK 기초 (11) 메시지 큐 및 GetMessage/PeekMessage, SendMessage/Postmesage에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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