1. 程式人生 > >Windows訊息響應機制之四:PostQuitMessage和GetMessage函式

Windows訊息響應機制之四:PostQuitMessage和GetMessage函式

 Windows是訊息驅動的作業系統。在Windows環境下程式設計必須熟練掌握Windows訊息響應機制。
 今天在練習Win32程式設計時碰到一個關於GetMessage函式的問題。這個問題之前一直沒有引起過我的注意,但是今天
 在網上搜索發現這個問題很多程式設計師都跟我一樣處於一知半解的狀態。
 在Win32應用程式的主函式中有一段訊息迴圈收發的程式碼:
 while (GetMessage(&Msg, hWnd, 0, 0))
 {
  TranslateMessage(&Msg);
  DispatchMessage(&Msg);
 }
 在Debug環境下啟動程式後點擊關閉按鈕可以正常關閉掉視窗,但是VS2008卻無法正常退出執行狀態(即應用程式沒有正常返回)。於是我按如下步驟進行了Debug:
 (1).在訊息處理函式中WM_DESTORY的處理中設定斷點,點選關閉按鈕case WM_DESROTY程式碼段可以執行;
 (2).當程式執行到case WM_DESROTY程式碼段之後再在主函式的TranslateMessage(&Msg)處設定斷點
 (3).按下F5發現程式可以執行到TranslateMessage(&Msg)處。
 經過上述步驟Debug後發現當在WM_DESTORY訊息處理過程中呼叫PostQuitMessage(0)函式後程序的訊息迴圈程式碼段可以繼續執行,但是按MSDN的描述PostQuitMessage函式會往執行緒的訊息佇列中插入一個WM_QUIT訊息,而GetMessage函式在收到WM_QUIT訊息後會返回一個非正數。
 後來在網上搜索網友克塞前來拜訪的一段解釋:
 對PostQuitMessage而言,它實際上並不傳送WM_QUIT訊息,他所做的實際是設定一些特殊的系統標誌,而佇列存取體系根據這個標誌並結合一些比較複雜的演算法來決定在某時某處引發實際的WM_QUIT。當演算法臨界時,GetMessage(hwnd)照樣能獲取WM_QUIT。而如果你PostThreadMessage(WM_QUIT),那麼一個實際的WM_QUIT訊息會被佇列,GetMessage(hwnd)永遠不會獲得這個退出訊息。一個最簡單的滿足演算法要求的實驗可以是這樣:你在WM_CLOSE訊息裡PostQuitMessage,然後在啟動程式後,首先移動視窗,然後關閉視窗,則程式能夠正常退出,設定斷點除錯可以發現,GetMessage(hwnd)確實捕獲了這個理論上發給執行緒佇列的退出訊息,並且列印記憶體棧可以發現,訊息本身確實是發給執行緒佇列而非視窗佇列的。反之,如果你先使hwnd失效,則無論你如何操作,GetMessage(hwnd)永遠不會收到退出訊息。所以總結起來說,最終能否退出首先取決於hwnd是否失效,雖然這並不是能解釋這個問題的根本原因,但至少是一個正確的部分表象原因。
 現階段由於我個人的水平還無法鑑別其真偽,所以這段解釋暫且先記錄下來作為日後的學習參考。

相關推薦

Windows訊息響應機制PostQuitMessageGetMessage函式

 Windows是訊息驅動的作業系統。在Windows環境下程式設計必須熟練掌握Windows訊息響應機制。  今天在練習Win32程式設計時碰到一個關於GetMessage函式的問題。這個問題之前一直沒有引起過我的注意,但是今天  在網上搜索發現這個問題很多程式設計師都跟

Windows訊息響應機制執行緒與訊息佇列

當一個執行緒第一次被建立時,系統假定執行緒不會用於任何與使用者相關的任務。這樣可以減少執行緒對系統資源的要求。但是,一旦該執行緒呼叫一個與圖形使用者介面有關的函式 ( 如檢查它的訊息佇列或建立一個視窗 ),系統就會為該執行緒分配一些另外的資源,以便它能夠執行與使用者介面有關

【Android 開發】: Android 訊息處理機制: Android 訊息迴圈 Looper 及其原始碼解析

  上一講我們學習Handler和Message的一些使用方式,我們知道Handler它會發送訊息和處理訊息,並且關聯一個子執行緒,如何傳送訊息入隊和出隊處理訊息等這些都是交給Looper去管理分發的,也就是它是負責整個訊息佇列運轉的一個類,這一講我們就來學習一下Andr

《C#圖解教程》讀書筆記繼承

intern html pan 類中訪問 ted obj 小寫 his new 本篇已收錄至《C#圖解教程》讀書筆記目錄貼,點擊訪問該目錄可獲取更多內容。 一、萬物之宗:Object   (1)除了特殊的Object類,其他所有類都是派生類,即使他們沒有顯示基類定義。   

python程式設計入門列表元組

第四章 列表和元組 4.1 建立一個列表 我們之前學過c語言的同學都知道一個數據型別叫做陣列,但是陣列有一個硬性的要求,就是陣列內的資料型別必須一致,但由於python沒有資料型別,所以python便加入了一個強大的列表,並且幾乎可以向裡注入任何型別的元素。 列

hadoop完全分散式叢集搭建全部流程ssh指令碼補充

SSH無密碼登入 1)配置ssh:配置ssh無密碼登入主要 是為了方便叢集之間進行通訊,方便運算。 (1)基本語法 ssh 另一臺電腦的ip地址 (2)ssh連線時出現Host key verif

轉深入Java虛擬機 類加載機制

method jre 聲明 常量 資源 inittest java開發 啟動 由於 轉載請註明出處:http://blog.csdn.net/ns_code/article/details/17881581 類加載過程 類從被加載到虛擬機內存中開始,到卸載出內存

VC程式設計Windows訊息處理機制、阻塞試驗、SetTimer、MessageBox、小心訊息響應處理函式

VC6標準WIN32程式,Windows訊息處理機制: 1.在註冊視窗類時,指定了訊息處理函式WndProc()。 2.WinMain()裡有訊息迴圈:     while (GetMessage(&msg, NULL, 0, 0))     {    

tomcat學習tomcat的類載入機制

        tomcat的類載入機制遵循了java類載入機制中經典的雙親委派模型。所以要了解tomcat的類載入機制需要先了解雙親委派模型。         在程式中用到的類需要由類載入器將類的class檔案載入到記憶體中,然後經由JVM驗證、解析、初始化後才能使用,

【深入Java虛擬機器】類載入機制

    我們來看得到該結果的步驟。首先在準備階段為類變數分配記憶體並設定類變數初始值,這樣A和B均被賦值為預設值0,而後再在呼叫<clinit>()方法時給他們賦予程式中指定的值。當我們呼叫Child.b時,觸發Child的<clinit>()方法,根據規則2,在此之前,要先執行完其父

【只怕沒有幾個人能說清楚】系列碰撞信息、觸發信息的檢測

col lis 至少 one ati spa nbsp 觸發 trigge 碰撞器分為三種: static collider              靜態碰撞器 rigidbody collider            剛體碰撞器 kinematic rigidbody

Linux時間子系統定時器的引擎clock_event_device

到來 開始 register 工作模式 統一 10個 net 說過 序列 早期的內核版本中,進程的調度基於一個稱之為tick的時鐘滴答,通常使用時鐘中斷來定時地產生tick信號,每次tick定時中斷都會進行進程的統計和調度,並對tick進行計數,記錄在一個jiffies變量

MongoDB初探系列MongoDB與Java共舞

ever 文件 basic query find man mongodb next() 入學 因為版本號不同,可能API也有所不同。本次學習用的是3.0版本號。 1、使用的mongodb的jdbc驅動版本號為:mongo-java-driver-3.0.0.jar

面向對象設計原則依賴倒置原則

ron 通過 發生 需要 系統 面向對象設計 啟動 模塊 == 依賴倒置原則 所謂依賴倒置原則(Dependence Inversion Principle )就是要依賴於抽象,不要依賴於具體。簡單的說就是對抽象進行編程,不要對實現進行編程,這樣就降低了客戶與實

機器學習入門機器學習的方法-神經網絡(轉載)

轉載 bsp 圖像 src nbsp 加速 數值 str 我們   轉自 飛鳥各投林   神經網絡      神經網絡(也稱之為人工神經網絡,ANN)算法是80年代機器學習界非常流行的算法,不過在90年代中途衰落。現在,攜著“深度學習”之勢,神

Django運維後臺的搭建用bootstrap模板讓運維前臺變得更漂亮

html django bootstrap 靜態資源 我對於PHP和ajax是屬於二把刀的水平,所以做網頁前端肯定是比上天還難,但是我又想把網頁做的漂亮可愛,怎麽辦呢?我就只好去download別人的模板,在這裏我使用了bootstrap框架做的模板。各位可以去https://wrapboot

Modbus庫開發筆記Modbus TCP Client開發

creat 需要 修改 status command 協議格式 sin 服務器端 這一 這一次我們封裝Modbus TCP Client應用。同樣的我們也不是做具體的應用,而是實現TCP客戶端的基本功能。我們將TCP客戶端的功能封裝為函數,以便在開發具體應用時調用。 對於T

網絡相關系列數據解析SAX方式解析XML數據

request nco nodename 新建 作用 call 其他 auto 文件內容 一、XML和Json數據的引入: 通常情況下。每一個須要訪問網絡的應用程序都會有一個自己的server。我們能夠向server提交數據,也能夠從server獲取數據。

Android異步載入學習筆記利用緩存優化網絡載入圖片及ListView載入優化

角度 thread 下午 出發 easy code cat height back 假設不做不論什麽處理。直接用網絡載入圖片在網速快的情況下可能沒什麽不好的感覺。可是假設使用移動流量或是網絡不好的時候。問題就來了,要麽用戶會抱怨流量使用太多。要麽抱怨圖

異步IO實戰異步IO的單個處理批量處理

c語言 異步io aio_write 異步IO由於它的非阻塞特性和強大的並發能力,非常適合用在要求高並發和高吞吐率的場景,比如用在提供SAN存儲的塊設備讀寫的實現上。和傳統IO模式類似,異步IO提供了一次提交一個IO請求的模式,還提供了一次提交一組IO請求的方式。下面將分別介紹這兩種模式的使用方法