天天看點

過濾視窗消息的時候請謹慎

有兩個API,大家一定十分熟悉:GetMessage和PeekMessage。

我們可以向它們傳遞一個過濾器,就可以限制函數将從消息隊列中檢索的視窗句柄或消息範圍。

雖然可以使用這些過濾器,但請確定你最終要執行一次未過濾消息的調用,以便任何其他未處理的消息都可以得到妥善處理。

一個比較常見的錯誤是,在GetMessage消息循環中使用了一個基于視窗句柄的過濾器,例如之前我們的例子程式:

過濾視窗消息的時候請謹慎

雖然在我們的例子程式中,我們隻建立一個視窗,但是上面的代碼仍然是不正确的。

有些人可能會問了,”這怎麼可能呢?這個程式隻建立了一個視窗,為什麼還會有其他視窗的消息?雖然這裡使用的過濾器看起來有點多餘,但是并沒有任何害處,不是嗎?”

請别忘了。很多系統服務會在背景建立視窗。舉個例子,如果啟用了輸入編輯器,則編輯器可會建立額外的視窗來輔助字元的輸入。

如果你初始化COM庫,則COM可能約會建立一個隐藏的視窗來輔助線程之間的封送。

另外一個例子,如果你隻使用過濾的GetMessage,那麼發往這些幫助視窗的消息将永遠不會被處理,到時你就會摸不着頭腦,想知道為什麼程式在嘗試執行拖放操作時偶爾會挂起。

本文的啟示:確定你的消息循環最終執行未經過濾的消息處理,以便這些服務可以正常運作。

總結

最後