Home >Operation and Maintenance >Windows Operation and Maintenance >Win32 SDK Basics (11) Detailed explanation of message queue and GetMessage/PeekMessage, SendMessage/Postmesage
Message queue is a queue used to store messages. Messages are first in, first out in the queue. All windows All programs have a message queue, and the program can obtain messages from the queue.
System message queue: A message queue maintained by the operating system, which stores messages generated by the system, such as mouse and keyboard messages, etc.
Program message queue: A message queue belonging to each application (thread), maintained by the application.
When a mouse, keyboard, etc. message is generated, the message is first stored in the system message queue, and then the operating system finds the message queue of the corresponding window based on the stored message, and delivers the message to the window's message queue.
Queue messages: After the message is sent, it is first put into the queue and then obtained through the message loop. Common queue messages: keyboard, mouse, timer messages, etc.
Non-queue message: After the message is sent, directly find the message processing function of the window , and call the message processing function for processing without going through the message queue. Common non-queue messages: WM_PAINT, WM_SIZE, etc.
The general message loop is as follows:
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: Message from the program Get messages from the queue.
TranslateMessage: Translate messages such as keystrokes on the keyboard into character messages.
DispatchMessage: Put the translated message into the program’s message queue again.
GetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax )
lpMsg: Pointer to the MSG structure, which receives message information from the thread's message queue.
hWnd: The handle of the window whose message is obtained. When its value is NULL, GetMessage retrieves messages for any window belonging to the calling thread, and the thread message is sent to the calling thread through PostThreadMessage.
wMsgFilterMin: An integer that specifies the minimum message value to be retrieved.
wMsgFilterMax: An integer specifying the maximum message value to be retrieved.
Return value: If the function obtains other messages other than WM_QUIT, it returns a non-zero value. If the function gets a WM_QUIT message, the return value is zero. If an error occurs, the return value is -1. For example, when hWnd is an invalid window handle or lpMsg is an invalid pointer. If you want to get more error information, please call the GetLastError function.
BOOL PeekMessage( LPMSG IpMsg, HWND hWnd, UINT wMSGfilterMin, UINT wMsgFilterMax, UINT wRemoveMsg );
lpMsg: MSG structure pointer to receive message information.
hWnd: The window handle whose message is checked.
wMsgFilterMin: Specifies the first message in the message range to be checked.
wMsgFilterMax: Specifies the last message in the message range to be checked.
wRemoveMsg: Determines how the message is processed. This parameter can take one of the following values:
Value |
Meaning |
---|---|
PM_NOREMOVE |
After PeekMessage is processed, the message is not removed from the queue. |
PM_REMOVE |
After the PeekMessage is processed, the message is removed from the queue. |
PM_NOYIELD |
This flag causes the system not to release threads waiting for the calling program to become idle. PM_NOYIELD can be freely combined into PM_NOREMOVE or PM_REMOVE. |
GetMessage和PeekMessage的主要区别在于:GetMessage是阻塞函数,它会在消息循环中会一直阻塞直到消息队列中出现了消息可以被获取,而PeekMessage是非阻塞函数,不管有没有获取到消息队列中的消息,它都会返回。PeekMessage更多用来检测消息队里中是否有消息,它的最后一个参数可以用来指定获取到消息后要不要把消息从消息队列中移除,通常情况下通过PeekMessage检测到消息队列有消息之后,再调用GetMessage区获取。
1、先在程序的消息队列中查找消息,如果有队列消息,就取出消息。
2、如果程序的消息队列中没有消息,向系统的消息队列获取属于本程序的消息。如果系统的消息队列中有属于本程序的消息,系统的消息队列会将消息分发到本程序的消息队列中。
3、如果系统的消息队列也没有消息,检查窗口需要绘制的区域是否需要重绘,如果发现有需要重绘的区域,产生WM_PAINT消息。
4、如果没有重新绘制区域,检查是否具有到时的定时器,如果有产生WM_TIMER定时器消息。
5、如果没有到时的定时器,整理程序的资源、内存等等。
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
发送消息到程序的消息队列,不管消息有没有被处理都会立即返回,用于队列消息的发送
The above is the detailed content of Win32 SDK Basics (11) Detailed explanation of message queue and GetMessage/PeekMessage, SendMessage/Postmesage. For more information, please follow other related articles on the PHP Chinese website!