天天看點

windows 消息循環(二)

    又查閱了些資料,發現下面這張圖,能夠很好的解釋windows的消息循環機制。圖很簡單明了,就不作過多的解釋了。

windows 消息循環(二)

1、消息隊列

(1)消息隊列的容量有多大?

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\ 下 USERPostMessageLimit 定義了隊列的最大長度,預設為10000;

(2)消息來源分為Hardware event或者是application,application一般會指定視窗或者線程發送消息,hardware event, 比如滑鼠移動,鍵盤輸入,都是由相應的裝置驅動将這些event,轉換成消息,放入系統消息隊列。

(3)是不是所有的消息都要經過消息隊列呢?

答案是,NO! 消息分為隊列消息和非隊列消息。隊列消息需要經過消息隊列,非隊列消息不需要,他們直接被傳入指定視窗的視窗過程進行處理。PostMessage發送的消息是隊列消息,它會把消息Post到消息隊列中;SendMessage發送的消息是非隊列消息, 被直接送到視窗過程處理。

(4)消息隊列中,大部分消息都是按照FIFO的方式進行處理,但也有例外。WM_PAINT,WM_TIMER, WM_QUIT隻有在Queue中沒有其他消息的時候才會被處理,WM_PAINT消息還會被合并以提高效率。

2、消息循環

(1)取消息GetMessage / PeekMessage,GetMessage屬于阻塞式API。這兩個API除了可以取消息,還可以對消息做一些過濾,隻需要傳入相應的參數就可以了。

(2)TranslateMessage 翻譯消息,注意,在包含有熱鍵和模态視窗消息的時候,還需要調用IsDialogMessage和TranslateAccelarator進行消息的翻譯;

(3)DispatchMessage将控制權交給系統,系統将消息分發給對應的視窗過程。發送給視窗過程的消息不包括消息發送時間和坐标位置,如果需要的話,可以通過API函數擷取;

3、視窗過程

視窗過程對所有的消息都會做處理,application可以選擇自己關系的消息做一些特殊處理,其餘的消息可以交給windows的預設視窗過程DefWindowProc。

經過以上了解後,對上文,gtest單元測試中遇到的問題就可以解決了。

在main()中建立一個工作線程,線程中建立一個視窗,定義視窗過程,建立消息循環。

主線程執行gtest用例,工作線程,執行相應的被測代碼。

問題得到解決。

繼續閱讀