windows的視窗訊息.處理流程本質.

來源:互聯網
上載者:User

 今日第一次看 <<Windows核心編程>>第26章, 關於視窗訊息的內容.
收穫甚大, 解決了以往的很多煩惱.

1: 如果有很多個WM_TIMER訊息. 如果WM_TIMER訊息沒有來得及處理, 那麼其將被合并為一個訊息.
2: WM_PAINT同理.  WM_TIMER訊息是優先順序最低的訊息.

 

別的線程給自己線程中的視窗發的訊息,是優先順序最高的訊息.
線程給自己建立的視窗發送的訊息,是次優先順序的訊息.
其次是鍵盤/滑鼠輸入訊息.
再其次是 WM_PAINT和WM_TIMER訊息.

 

別的認識:

一個視窗對應一個視窗訊息處理函數(也可能多個視窗,對應一個視窗處理函數,看你建立視窗時怎麼指定了)
一個線程對應著一個訊息佇列.
       ( 這個訊息佇列又分為3個子隊列: 登記訊息佇列(自己給自己發送的訊息), 發送訊息佇列(別人發送給子的訊息), 反饋訊息佇列(自己給別人發送的訊息的反饋通知) )

/////////////////////////////////

另外, 一個背景工作執行緒, 如果其調用了PeekMessage() 那麼其就變成了 UI線程!!!
只不過, 由於這個背景工作執行緒的訊息佇列裡面沒有任何訊息!!!
如果這個背景工作執行緒建立了視窗, 那麼其訊息佇列裡面自然就有了windows給這個視窗投遞的訊息.

記住下面的定理:
1: 若且唯若 一個線程裡面調用了PeekMessage/GetMessage, DispatchMessage()等幾個訊息分配函數, 一個線程才是使用介面執行緒. 但是預設線程的訊息佇列裡面是沒有訊息的.

2:  當線程內部建立了一個視窗之後, 或者, 別的線程往這個線程投遞了訊息了, 線程的訊息佇列裡面才有訊息可取.

/////////////
解惑1:
不難理解為何, TXDATA()由背景工作執行緒搖身一變, 變成了UI線程. 這是因為,
1:cvNameWindow()內部建立了視窗,
2:cvWaitKey()內部調用了訊息指派.
導致這個背景工作執行緒擁有了訊息迴圈, 也擁有了訊息.

解惑2:
當向一個僅有訊息指派沒有視窗的線程投遞訊息時, 這個訊息由那個視窗的訊息處理函數處理???
答案是: 不由哪個視窗的處理函數處理, 而是在GetMessage時, 就可以處理, 也就是, 線上程裡面直接處理, 當然, 你仍然可以把該視窗控制代碼為NULL的訊息進一步 Dispatch, 然後, 如果該線程有視窗, 所有的視窗的視窗處理函數還想都能夠處理該訊息. 呼呼

解惑3:
SendMessage(HWND), 的第一個參數是視窗控制代碼, 那麼訊息怎麼進入線程的訊息佇列裡了呢?
windows內部會檢查, 這個hwnd這個視窗是有誰建立的, 然後把訊息放入對應線程的訊息佇列裡.
假如SendMessage的訊息發送方, 和訊息接收方, 屬於不同的兩個線程, 那麼由於SendMessage是同步的, windows會進行線程的環境切換, 也就是, 發送方的線程將失去CPU資源, 直到訊息被處理返回.

為了防止接收方線程掛掉, 導致發送方線程也跟著掛掉, windows提供了 SendMessageTimeout()API, 可以指定等待的時間.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.