PeekMessage 调用的一个例子:
PeekMessage(&msg,NULL,0,0,PM_REMOVE);
前面的4个参数(一个指向 MSG 结构的指针、一个窗口的句柄、两个值指示消息范围)与 GetMessage 的参数相同。
将第二、三、四个参数设置为 NULL 或 0时,表明我们想让 PeekMessage 返回程序中所有窗口的所有消息。
如果要将消息从消息队列中删除,则将 PeekMessage 的最后一个参数设置为 PM_REMOVE。
如果不希望删除消息,则将最后一个参数设置为 PM_NOREMOVE,这使得程序可以检查程序的消息队列中的下一个消息,而不实际删除它。
GetMessage 不将控制返回给程序,直到从程序的消息队列中获取消息,但是 PeekMessage 总是立刻返回,而不论一个消息是否出现。
当(应用程序的)消息队列中有一个消息时,PeekMessage 的返回值为 TRUE(非0),并且将按通常方式处理消息。当队列中没有消息时,PeekMessage 返回 FALSE(0)。
考虑如下例子:
// 普通的消息循环
while( GetMessage(&msg,NULL,0,0) )
{
TranslateMessage(&msg);
DispatchMessage (&msg);
}
return msg.wParam;
// 等价于
while( TRUE )
{
if( PeekMessage(&msg,NULL,0,0,PM_REMOVE) )
{
if(msg.message == WM_QUIT)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// Other program lines to do some work
}
}
return msg.wParam;
如果 PeekMessage 的返回值为 TRUE,则消息按通常方式进行处理。如果返回值为 FALSE,则在将控制返回给Windows(操作系统) 之前,还可以做一点工作(如显示另一个随机矩形)。
PeekMessage 不能从消息队列中删除 WM_PAINT 消息。
从队列中删除 WM_PAINT 消息的唯一方法是令窗口客户区的失效区域变得有效,这可以用 ValidateRect 和 ValidateRgn 或者 BeginPaint 和 EndPaint 对来完成。
不能使用如下所示的代码来清除消息队列中的所有消息:
while( PeekMessage(&msg,NULL,0,0,PM_REMOVE) );
这条语句从消息队列中删除 WM_PAINT 之外的所有消息。如果队列中有一个 WM_PAINT 消息,程序就会永远地陷在 while 循环中。