首先来看来GetMessage与PeekMessage这两个API的函数原型:
BOOL WINAPI GetMessage(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax
);
BOOL WINAPI PeekMessage(LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg
);
可以看到它们的前4个参数与是一模一样的。
第一个参数是MSG结构体变量的地址,用来填充从消息队列中获取的一个消息结构体。
第二、三和四个参数一般我们可以设为NULL或者0,以表示从任意的窗体中接收任何有效的消息。详情可以参考MSDN。
最后一个是PeekMessage中才有的wRemoveMsg参数,根据MSDN的描述有下面3个标记:
-
Value Meaning -
PM_NOREMOVE
0x0000
Messages are not removed from the queue after processing byPeekMessage.
-
PM_REMOVE
0x0001
Messages are removed from the queue after processing byPeekMessage.
-
PM_NOYIELD
0x0002
Prevents the system from releasing any thread that is waitingfor the caller to Go idle (see WaitForInputIdle).
Combine this value with either PM_NOREMOVE or PM_REMOVE.
在说明上面3个标记之前,先说明一下GetMessage和PeekMessage的作用。它们都是用来从消息队列从取下一个消息来填充MSG结构体变量,但是有一点不同的是,GetMessage是阻塞的,而PeekMessage是非阻塞的。也就是说,如果消息队列现在是没有消息,GetMessage这个函数是不会返回值然后结束,而PeekMessage是无论消息队列现在有没有消息它都立刻返回一个值然后结束。这就是他们的区别!
一般是这样用GetMessage和PeekMessage:
GetMessage用法:
while(GetMessage(&msg, NULL, 0, 0))//若消息队列无消息,while是不会进入函数体的
{
}
PeekMessage用法:
while(TRUE)
在这里,提醒下GetMessage和PeekMessage的返回值略有不同,GetMessage除了收到WM_QUIT消息会返回0值外,其他消息都返回非0值。而PeekMessage是若收到一个有效消息就返回非0值,否则返回0值。
最后说下PeekMessage的最后一个参数,这里我使用了PM_REMOVE,意思是收到一个消息后,将这个消息从消息队列中移除,而令一个PM_NOREMOVE顾名思义就是不移除该消息了。