Thinking in MFC 訊息機制1

2021-06-13 06:23:07 字數 2915 閱讀 2576

在使用較長時間的mfc之後,感覺自己需要將零散的mfc知識整合一下,所以開始推出這個系列的博文,首先就從mfc經典的訊息機制入手,來介紹mfc是怎麼運作的。這篇主要介紹一下訊息機制中幾個基礎概念。

這篇主要介紹訊息如何路由到主視窗。

寫過win32程式,肯定只要我們要展示乙個視窗,需要這個入口函式,這個就像控制台程式中main函式,是程式的入口。但是在mfc專案建立之後,我們在專案工程卻找不到這個函式。

其實mfc已經將這個函式內部寫好了,具體在下面這個檔案中。

microsoft visual studio10.0\vc\atlmfc\src\mfc\winmain.cpp

以下winmain函式中的內容,這些**中的大部分我們暫時不做詳細介紹,在之後的篇章中會來討論這些**。

assert(hprevinstance == null);

int nreturncode = -1;

cwinthread*pthread = afxgetthread();

// afx internal initialization

if (!afxwininit(hinstance, hprevinstance, lpcmdline,ncmdshow))

goto initfailure;

goto initfailure;

// perform specific initializations

if (!pthread->initinstance())

nreturncode= pthread->exitinstance();

goto initfailure;

}nreturncode =pthread->run();

initfailure:

#ifdef _debug

// check for missing afxlocktempmap calls

if (afxgetmodulethreadstate()->m_ntempmaplock !=0)

afxlocktempmaps();

afxunlocktempmaps(-1);

#endif

afxwinterm();

return nreturncode;

上訴**中第27行**,我們需要找的訊息迴圈就在run函式中,接下來就看一下這個run函式。

這個類微軟用來封裝mfc的執行緒。

這裡我們主要來討論這個類中的run函式

virtual int cwinthread::run()

do// 空閒處理接觸,進行訊息處理

} while (::peekmessage(&m_msgcur, null, null, null,pm_noremove));

}assert(false);//

}

這裡先說明,以上**包括下面的**都是筆者從網上找到的,所以對於其準確性不能夠保證,但是作為介紹性說明,應該是沒有問題的。

我們按照函式執行順序往下看,首先我們發現了乙個死迴圈,這個死迴圈便是我們要的訊息迴圈。

接下來我們便是idle狀態的處理,沒有訊息處理的時候,執行緒進入idle狀態。其中peekmessage,便是用來判斷訊息佇列中是否有訊息。

再往下看,我們會發現乙個叫pumpmessage,這個函式便是這裡的乙個關鍵函式(從run函式的**中看,好像也沒有其對隊訊息進行處理的函式了)。

接下來就看一下pumpmessage函式的原始碼

bool cwinthread::pumpmessage()

return true;

}

按照執行順序看,我們會注意到getmessage,這個函式這裡暫時不做介紹,就是從執行緒的訊息佇列中獲取訊息,並把訊息內容放入乙個結構的物件中(這裡就放入msgcur)。

接下來便是判斷訊息是否是idle訊息,如果不是就交給pretranslatemessage,這個函式又是乙個關鍵函式,所以我們有必要再次去找到它的原始碼進行分析。

bool cwinthread::pretranslatemessage(msg* pmsg)

return false; // no special processing

}

我們按照函式的執行順序來看,首先判斷一下這個訊息是否是發給視窗的。如果不是,那麼就是乙個執行緒訊息,就交給dispatchthreadmessageex(這裡也暫時不介紹這個函式,不是這篇討論的重點)。

接下面,我們獲得主視窗物件,就把訊息交給walkpretranslatetree處理。

繼續**,我們有需要找到walkpretranslatetree的原始碼。(很抱歉,要看這麼多**)

bool pascal cwnd::walkpretranslatetree(hwnd hwndstop,msg* pmsg)

// got to hwndstop window without interest

if (hwnd == hwndstop)

break;

}return false; // no specialprocessing

}

略去一些空值的檢查,我們看到訊息最後是交給了主視窗的pretranslatemessage函式處理了。接下來就交給主視窗進行訊息處理了。

這裡我們就大致了解了乙個訊息怎麼路由到主視窗的流程。

開始程式設計不久,便接觸到了mfc。用了mfc寫了自己第乙個視窗程式,寫了第乙個遊戲,在學校課題演示的時候也是喜歡用mfc做演示。

現在工作了,專案的介面部分也在使用mfc開發的,值得慶幸的是,現在微軟對於mfc的介面做了很大的改善,想起剛開始不斷重寫控制項類,那個真是記憶猶新。

在平時程式設計的時候,vs這個整合工具確實很方便。但現在想把一些mfc零零碎碎的知識整合起來。所以這個系列可能會深入地去介紹mfc。

訊息和訊息處理之訊息迴圈

在win32程式設計中,訊息迴圈是相當重要的乙個概念,看似很難,但使用起來卻是非常簡單。在winmain函式的最後,有下列 while getmessage msg,null,0,0 windows應用程式可以接收以各種形式輸入的資訊,這包括鍵盤 滑鼠動作 計時器產生的訊息,也可以是其他應用程式發來...

訊息和訊息佇列

在傳統的c 程式當中,我們呼叫 fopen 函式開啟檔案,這個庫函式最終呼叫作業系統 提供的函式 來開啟檔案。而在 windows 中,不僅使用者程式可以呼叫系統的 api函式,反回來,系統也會呼叫使用者程式,這個呼叫是通過訊息來進行的。windows程式設計是一種完全不同於傳統的 dos方式的程式...

訊息佇列 訊息複製

訊息複製需要解決 高效能,高可用,資料一致性 高效能 寫的副本越多,寫的效能越低,讀取不影響 資料一致性,必須採用主從模式的複製方式,同時需要保證在任何時刻,集群的主節點不能超過乙個。高可用 在主節點宕機後,可以盡快選出新的主節點 一 rocketmq 1 傳統複製 複製的基本單位是broker,也...