PeekMessage使用方法


原型:

BOOL PeekMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg);


前面的四個參數(一個指向MSG結構的指標、一個視窗代號、兩個值指示消息范圍)與GetMessage的參數相同。將第二、三、四個參數設定為NULL或0時,表明我們想讓PeekMessage傳回程式中所有視窗的所有消息。如果要將消息從消息佇列中刪除,則將PeekMessage的最後一個參數設定為PM_REMOVE。如果您不希望刪除消息,那么您可以將這個參數設定為PM_NOREMOVE。這就是為什么Peek_Message是「偷看」而不是「取得」的原因,它使得程式可以檢查程式的佇列中的下一個消息,而不實際刪除它。

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
{
// 完成某些工作的其他行程式
}
}
return msg.wParam ;

如果PeekMessage的傳回值為TRUE,則消息按通常方式進行處理。如果傳回值為FALSE,則在將控制傳回給Windows之前,還可以作一點工作(如顯示另一個隨機矩形)。(盡管Windows 文件上說,您不能用PeekMessage 從消息佇列中刪除WM_PAINT消息,但是這並不是什么大不了的問題。畢竟,GetMessage並不從消息佇列中刪除WM_PAINT消息。從佇列中刪除WM_PAINT消息的唯一方法是令視窗顯示區域的失效區域變得有效,這可以用ValidateRect和ValidateRgn或者BeginPaint和EndPaint對來完成。如果您在使用PeekMessage從佇列中取出WM_PAINT消息後,同平常一樣處理它,那么就不會有問題了。所不能作的是使用如下所示的程式碼來清除消息佇列中的所有消息:

while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) ; 

這行敘述從消息佇列中刪除WM_PAINT之外的所有消息。如果佇列中有一個WM_PAINT消息,程式就會永遠地陷在while循環中。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM