2013-03-28 88 views
0

這個Win32消息循環內究竟發生了什麼?據我所知,TranslateMessage正在將鍵碼轉換爲UTF字符碼併發送WM_CHAR事件,但撥打PeekMessage時會發生什麼情況?它濾除了某種類型的信息,只翻譯這些信息?這個Win32消息循環究竟發生了什麼?

// Application/Player message loop. 
MSG msg; 
ZeroMemory(&msg, sizeof(msg)); 

while(msg.message != WM_QUIT) 
{ 
    if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    // work happens here... 
} 
+1

的PeekMessage(味精,NULL,0U,0U,PM_REMOVE)味精保存消息。這裏的NULL表示它需要窗口消息和線程消息。 OU和OU意味着它接收所有可用的消息並且不進行過濾。 PM_REMOVE表示它在處理後刪除消息。如果有消息,它會返回true。 –

回答

4

正常情況下,消息循環將使用GetMessage而不是PeekMessage。不同的是,PeekMessage立即返回。如果消息已被刪除,則返回TRUE;如果沒有消息被提取,則返回FALSE。另一方面,如果隊列是空的,則GetMessage阻塞,直到消息到達。

該點是註釋說明工作發生在這裏。據推測,作者有一些原因,爲什麼正常的阻塞消息循環不足以滿足要求。問題中非阻塞消息循環代碼的缺點是它是一個繁忙的循環。它不會閒置,因此它將完全消耗CPU,除非您撥打Sleep()或您已刪除的類似內容。

在一個評論中,你說你實際上只想要關閉鍵盤信息,而只是關於特定窗口的信息。你需要調用PeekMessage這樣的:

PeekMessage(&msg, hwnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE) 
2

所有這一切都是一種非阻塞的方式來獲取消息。它檢查是否有消息,如果有消息,則將其從隊列中取出,並將其置於& msg。

檢查the docs

第二個參數說明要查看哪個窗口。在這種情況下,它是「線程中的所有窗口」。

第三個和第四個參數確實允許您指定是要鍵盤還是鼠標事件,但當前設置爲「全部」。

+0

如何更改它,使其僅適用於當前窗口,並且只獲取鍵盤事件? –

+0

請不要在評論中提問。這個問題應該在一個問題中提出。這也很容易回答。 –

+0

'PeekMessage(&msg,HWnd,0U,0U,PM_REMOVE)'過濾這個窗口的消息.... –