由於視類視窗始終覆蓋在框架類視窗之上,因此所有操作,包括滑鼠單擊、滑鼠移動等操作都只能由視類視窗捕獲。乙個mfc訊息響應函式在程式中有三處相關資訊:函式原型、函式實現和以及用來關聯訊息和訊息響應函式的巨集。
(1)在訊息響應函式的原型**中,函式宣告的前部有乙個afx_msg限定符,也是乙個巨集,該巨集表明這個函式是乙個訊息響應函式的宣告。
(2)訊息對映巨集:在檢視類的原始檔中,begin_message_map()和end_massage_map()這兩個巨集之間定義了訊息對映表,例如對於畫線,其中有乙個on_wm_lbuttondown()訊息對映巨集,這個巨集的作用就是把滑鼠左鍵按下訊息(wm_lbuttondown)與乙個訊息響應函式關聯起來,通過這種機制,一旦有訊息產生,程式就會呼叫相應的訊息響應函式來進行處理。
(3)訊息響應函式的定義:在檢視類的原始檔中,可以看到onlbuttondown函式的定義。標頭檔案中在兩個afx_msg注釋巨集之間是訊息響應函式原型的宣告。原始檔中有兩處:一處是在兩個afx_msg_map注釋巨集之間的訊息對映巨集,通過這個巨集把訊息與訊息響應函式關聯起來;另一處是原始檔中的訊息響應函式的實現**。
在win32應用程式中,當有訊息產生時,作業系統會把這條訊息放到應用程式的訊息佇列中,應用程式通過getmessage函式從這個佇列中取出一條具體的訊息,並通過dispatchmessage 函式把訊息交給作業系統,呼叫的是應用程式的視窗過程,即視窗過程函式wndproc進行處理,然而在mfc程式中,並不是按這種途徑進行處理的, 只要定義了與訊息有關的三處資訊後,便可實現訊息的響應處理.mfc中採用的這種訊息處理機制稱為mfc訊息對映機制.
mfc訊息對映機制的具體實現方法是:在每個能接收和處理訊息的類中,定義乙個訊息和訊息函式靜態對照表,即訊息對映表.在訊息對映表中,訊息與對應的訊息處理函式指標是成對出現的.某個類能處理的所有訊息及其對應的訊息處理函式的位址都列在這個類所對應的靜態表中.當有訊息需要處理時,程式只要搜尋該訊息靜態表,檢視表中是否含有該訊息,就可知道該類能否處理此訊息.如果能處理此訊息,則同樣依照靜態錶能很容易找到並呼叫對應的訊息處理函式.
mfc訊息對映機制的實際實現過程:mfc在後台維護了乙個視窗控制代碼與對應的c++物件指標的對照表,以例中的cdrawview類為例,與cdrawview物件相關的有乙個視窗,視窗當然有它的視窗控制代碼,該控制代碼與cdrawview物件的乙個指標(即cdrawview*)存在一一對應關係,在視窗控制代碼與c++物件對照表中就維護了這種對應關係.當收到某乙個訊息時,訊息的第乙個引數就指明了該訊息與哪個視窗控制代碼相關,通過對照表,就可以找到與之相關的c++物件指標.然後把這個指標傳遞給應用程式框架視窗類的基類,後者會呼叫乙個名為windowproc函式,該函式定義位於wincore.cpp中.cwnd::windowproc函式內部呼叫了乙個onwndmsg函式,真正的訊息路由,也就是訊息對映是由此函式完成的.onwndmsg函式的處理過程:首先判斷訊息是否有訊息響應函式.判斷方法是在相應視窗類中查詢所需的訊息響應函式.因為傳遞給windowproc的是視窗子類指標,onwndmsg會到相應的子類標頭檔案中查詢,看看declare_message_map()巨集之上,兩個afx_msg注釋巨集之間是否有相應的訊息響應函式原型的宣告;再到子類的原始檔中,看看begin_message_map()和end_message_map()兩個巨集之間是否有相應的訊息對映巨集.如果通過上述步驟,找到了訊息響應函式,接著就呼叫該響應函式,對訊息進行處理.如果在子類中沒有找到,那麼就交由基類進行處理.通過以上步驟,mfc就實現了具體的訊息對映,從而完成對訊息的響應
MFC訊息響應機制分析
一 引言 vc 的mfc類庫實際上是windows下c 程式設計的一套最為流行的類庫。mfc的框架結構大大方便了程式設計師 的程式設計工作,但是為了更加有效 靈活的使用mfc程式設計,了解mfc的體系結構往往可以使程式設計工作事半功倍。它合理的封裝了win32 api函式,並設計了一套方便的訊息對映...
MFC訊息響應機制(一)
由於視類視窗始終覆蓋在框架類視窗之上,因此所有操作,包括滑鼠單擊 滑鼠移動等操作都只能由視類視窗捕獲。乙個mfc訊息響應函式在程式中有三處相關資訊 函式原型 函式實現和以及用來關聯訊息和訊息響應函式的巨集。1 在訊息響應函式的原型 中,函式宣告的前部有乙個afx msg限定符,也是乙個巨集,該巨集表...
MFC中訊息對映機制
背景 父對話方塊下的幾個子對話方塊之間互相通訊,更改各自的控制項狀態 解決 1是通知父對話方塊,讓父對話方塊來處理。2是直接和子對話方塊通訊。都要用到訊息對映 1 子對話方塊在設定為child 無邊框之後是沒有名字的,我在通過父對話方塊來獲取子對話方塊控制代碼的時候一直失敗,所以考慮在uesd子對話...