遭遇Windows訊息迴圈

來源:互聯網
上載者:User
今天跟同事聯調一段代碼,被一個問題鬱悶了很久。

調用過程其實並不複雜,就是他提供一個Dll,並輸出一個函數(姑且叫做Foo()吧),我調用他的函數Foo,其內部產生一個視窗。但是,我每次調用,視窗總是一閃而過!我們於是懷疑,是不是因為主程式是console,不支援MFC的緣故?要不然一定是因為不是在主線程裡調用的緣故?!又是多線程,真是麻煩!

反覆測試,結果如下

                 MFC對話方塊Win32      MFC Console
多線程             失敗                         失敗
單線程             成功                         失敗

為什嗎?難道就不能在普通線程裡建立視窗嗎?什麼是主線程(UI線程),什麼又是背景工作執行緒?以前認為理所當然的事情,現在突然變得很模糊!

開始把目光鎖定到訊息佇列上!是不是因為主線程有訊息佇列?比如MFC對話方塊程式就有訊息佇列,而Console沒有。但是,同樣是線程,為什麼你有而我沒有?難道是WinMain函數和普通的main函數不一樣?到底訊息佇列是什麼時候產生的?

草草瀏覽了CWinApp的代碼,也沒有找到答案。這時候,隱約想起了《Windows核心編程》裡說的,系統在你第一次調用相關函數的時候,自動為線程建立訊息佇列!但是,到底是什麼函數呢?

帶著這個鬱悶回到了家,開啟那本Windows編程寶典,翻到訊息佇列一章。原來,每個視窗歸屬於建立它的線程。一旦線程退出,視窗也將自行銷毀!另外,線程還要進行訊息迴圈,以分發視窗的訊息!注意,訊息迴圈是由線程負責的!線程剛開始建立的時候是不帶訊息佇列的,當線程第一次調用視窗相關的函數時,作業系統自動為其建立訊息佇列!原來,視窗的訊息佇列是歸屬於線程的!

問題終於搞清楚了,在普通的背景工作執行緒裡,我們沒有訊息迴圈,所以建立出來的視窗還沒有沒有機會顯示出來,線程就結束退出了!即使在console程式裡,通過cin.get()讓程式等待,視窗還是沒有機會重新整理(依賴訊息迴圈分發並調用訊息處理函數)而一直處於忙碌等待狀態!而前面的Foo函數,恰恰要依賴於訊息迴圈!

知道問題的真正原因後,就很容易解決了!在調用同事的函數產生視窗後(函數返回了),在同一個線程裡進行訊息迴圈!如下

...in a working thread...

Foo();   //call some function

while (GetMessage(&msg, NULL, 0, 0))
{
    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

...working thread exit...

問題迎刃而解!你看不是MFC的問題,也不是不能在背景工作執行緒裡建立視窗。本來,我一開始就懷疑,這麼依賴MFC,總不能讓主程式都是MFC程式吧!作為一個DLL組件,不能對調用者有太多的限制!而多線程,太尋常了,如果都在主線程裡做,那也太難模組化了吧!當然了,現在說這些都是馬後炮,當時鬱悶的時候,什麼古怪的理由都用上了!

其實,這個問題本來可以解決得更快點的。如果同事事先說明他的Foo函數何時返回(我一直以為它要一直阻塞到其產生的視窗關閉才返回的,結果並不是這樣的,視窗一產生它就返回了),以及是否需要依賴外部的訊息迴圈(他是有提過,但也很模糊,搞不清具體為什麼)。當然,最大的原因還是因為大家對Windows的訊息迴圈機制理解得不是很深入!

現在你搞明白Windows的訊息迴圈到底是如何進行的了嗎?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.