2010-06-30 85 views

回答

16

比較傳統的消息循環是這樣的:

while (GetMessage(&msg, 0, 0, 0)) 
{ 
    if (!TranslateAccelerator(hwndMain, haccel, &msg)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
} 

這是一個相當大的提示你想要什麼分派消息之前做的事情:那應該被攔截捕獲的消息和特殊治療前窗戶看到他們。鍵盤快捷鍵是一個典型的例子,無論窗口有什麼焦點,都需要檢測它們。

任何GUI類庫都會公開一個名爲類似App.PreProcessMessage的虛擬方法,這是一個可以被覆蓋的虛擬函數,因此您的程序可以實現自己的快捷方式和其他東西。

+0

這是一個很好的實例,謝謝。 :) – 2010-06-30 20:48:09

+1

僅僅需要確認兩年後... – 2012-08-30 23:06:41

+0

如果我翻譯和發送一條消息不止一次,或者根本不翻譯和發送消息,可以嗎? - 我已經測試過並沒有發現問題,但我只是想確保它確實沒有問題。 – 123iamking 2017-04-06 14:18:43

8

它們是不同的野獸。

對於TranslateMessage function

平移虛擬鍵的信息到 字符消息。字符 消息被髮布到調用 線程的消息隊列中,待下一次線程調用 GetMessage或PeekMessage函數時讀取 。 [...] TranslateMessage函數不會 修改 lpMsg參數指向的消息。

DispatchMessage另一方面,將消息發送到窗口過程。

所以DispatchMessage做了處理消息的實際工作。 TranslateMessage可能或可能不會向線程隊列發佈新消息。如果消息被翻譯,則字符消息被髮布到線程的消息隊列中。

的TranslateMessage函數不 修改消息由 LPMSG參數指向。

它們是分開的調用,所以程序員可以避免由TranslateMessage提供的消息轉換。

+0

在翻譯完消息後,虛擬鍵消息是否仍然會由DispatchMessage調度? – 2014-08-06 12:11:50

0

TranslateMessage()將虛擬鍵消息轉換爲字符輸入消息。

這是一個遠程機會的單獨調用,在某些情況下,您希望而不是爲某些虛擬鍵生成字符輸入消息。

1

那麼從MSDN舉一個例子:

您可以修改各種方式的消息循環。例如,您可以從隊列中檢索消息,而不必將其分派到窗口。這對於發佈消息而不指定窗口的應用程序很有用。您還可以指示GetMessage搜索特定的消息,並將其他消息留在隊列中。如果您必須暫時繞過消息隊列的通常FIFO順序,這非常有用。

如果您不需要轉換鍵盤輸入控制代碼,您也可以避免調用翻譯消息。