windows佇列訊息和非佇列訊息的詳細解釋

2021-06-20 08:07:18 字數 1898 閱讀 5908

我們已經談到過,windows給視窗傳送訊息,這意味著windows呼叫視窗訊息處理程式。但是,windows程式也有乙個訊息迴圈,它呼叫getmessage從訊息佇列中取出訊息,並且呼叫dispatchmessage將訊息傳送給視窗訊息處理程式。

那麼,windows程式是依次等待訊息(類似於普通程式中相同的鍵盤輸入),然後將訊息送到某地方去的嗎?或者,它是直接從程式外面接收訊息的嗎?實際上,兩種情況都存在。

訊息能夠被分為「佇列化的」和「非佇列化的」。佇列化的訊息是由windows放入程式訊息佇列中的。在程式的訊息迴圈中,重新傳回並分配給視窗訊息處理程式。非佇列化的訊息在windows呼叫視窗時直接送給視窗訊息處理程式。也就是說,佇列化的訊息被「傳送」給訊息佇列,而非佇列化的訊息則「傳送」給視窗訊息處理程式。任何情況下,視窗訊息處理程式都將獲得視窗所有的訊息--包括佇列化的和非佇列化的。視窗訊息處理程式是視窗的「訊息中心」。

佇列化訊息基本上是使用者輸入的結果,以擊鍵(如wm_keydown和wm_keyup訊息)、擊鍵產生的字元(wm_char)、滑鼠移動(wm_mousemove)和滑鼠按鈕(wm_lbuttondown)的形式給出。佇列化訊息還包含時鐘訊息(wm_timer)、更新訊息(wm_paint)和退出訊息(wm_quit)。

非佇列化訊息則是其它訊息。在許多情況下,非佇列化訊息來自呼叫特定的windows函式。例如,當winmain呼叫createwindow時,windows將建立視窗並在處理中給視窗訊息處理程式傳送乙個wm_create訊息。當winmain呼叫showwindow時,windows將給視窗訊息處理程式傳送wm_size和wm_showwindow訊息。當winmain呼叫updatewindow時,windows將給視窗訊息處理程式傳送wm_paint訊息。鍵盤或滑鼠輸入時發出的佇列化訊息訊號,也能在非佇列化訊息中出現。例如,用鍵盤或滑鼠選擇了乙個選單項時,鍵盤或滑鼠訊息就是佇列化的,而說明選單項已選中的wm_command訊息則可能就是非佇列化的。

這一過程顯然很複雜,但幸運的是,其中的大部分是由windows解決的,不關我們的程式的事。從視窗訊息處理程式的角度來看,這些訊息是以一種有序的、同步的方式進出的。視窗訊息處理程式可以處理它們,也可以不處理。

當我說訊息是以一種有序的同步的方式進出時,我是說首先訊息與硬體的中斷不同。在乙個視窗訊息處理程式中處理訊息時,程式不會被其它訊息突然中斷。

雖然windows程式可以多執行緒執行,但每個執行緒的訊息佇列只為視窗訊息處理程式在該執行緒中執行的視窗處理訊息。換句話說,訊息迴圈和視窗訊息處理程式不是併發執行的。當乙個訊息迴圈從其訊息佇列中接收乙個訊息,然後呼叫dispatchmessage將訊息傳送給視窗訊息處理程式時,直到視窗訊息處理程式將控制傳回給windows,dispatchmessage才能結束執行。

當然,視窗訊息處理程式能呼叫給視窗訊息處理程式傳送另乙個訊息的函式。這時,視窗訊息處理程式必須在函式呼叫傳回之前完成對第二個訊息的處理。那時視窗訊息處理程式將處理最初的訊息。例如,當視窗過程呼叫updatewindow時,windows將呼叫視窗訊息處理程式來處理wm_paint訊息。視窗訊息處理程式處理wm_paint訊息結束以後,updatewindow呼叫將把控制傳回給視窗訊息處理程式。

這也就是說視窗訊息處理程式必須是可重入。在大多數情況下,這不會帶來問題,但是程式寫作者應該意識到這一點。例如,假設您在視窗訊息處理程式中處理乙個訊息時設定了乙個靜態變數,然後呼叫了乙個windows函式。在這個函式傳回時,您還能保證那個變數的值還是原來那個嗎?難說--很可能您呼叫的windows函式產生了另外乙個訊息,並且視窗訊息處理程式在處理這個訊息時改變了該變數的值。這也是在編譯windows程式時,有些編譯最佳化選項必須關閉的原因之一。

在許多情況下,視窗訊息處理程式必須儲存它從訊息中取得的資訊,並在處理另乙個訊息時使用這些資訊。這些資訊可以儲存在視窗的靜態(static)變數或整體變數中。

當然,讀者將在下面幾章對此有乙個更清楚的了解,因為視窗訊息處理程式將處理更多的訊息

3 2 2 佇列訊息和非佇列訊息

摘錄於 windows程式 第5版,珍藏版 charles.petzold 著 p60 前面提過 windows 將訊息傳送給乙個視窗,意思是說 windows 呼叫了該視窗的視窗過程。但是,乙個 windows 程式同時還具有乙個訊息迴圈使用者從訊息佇列中檢索和分發訊息,其中檢索訊息是通過呼叫 g...

Windows訊息佇列

輸入首先給出正整數n 1 0 5 隨後n行,每行給出乙個指令 get或put,分別表示從佇列中取出訊息或將訊息新增到佇列中。如果指令是put,後面就有乙個訊息名稱 以及乙個正整數表示訊息的優先順序,此數越小表示優先順序越高。訊息名稱是長度不超過10個字元且不含空格的字串 題目保證佇列中訊息的優先順序...

windows訊息佇列

windows訊息佇列 windows中 佇列訊息和非佇列訊息。訊息佇列由可以分成系統訊息佇列和執行緒訊息佇列。系統訊息佇列由windows維護,執行緒訊息佇列則由每個gui執行緒自己進行維護,僅當執行緒第一次呼叫gdi函式時系統才給執行緒建立乙個訊息佇列,佇列訊息送到系統訊息佇列,然後到執行緒訊息...