天天看點

MFC消息響應機制

   所有MFC的視窗類都通過鈎子函數_AfxCbtFilterHook截獲消息,并且在鈎子函數_AfxCbtFilterHook中把視窗過程設定為AfxWndProc。原來的視窗過程儲存在成員變量m_pfnSuper中。 ----是以在MFC架構下,一般一個消息的處理過程是這樣的。

  1. 函數AfxWndProc接收Windows作業系統發送的消息。
  2. 函數AfxWndProc調用函數AfxCallWndProc進行消息處理,這裡一個進步是把對句柄的操作轉換成對CWnd對象的操作。
  3. 函數AfxCallWndProc調用CWnd類的方法WindowProc進行消息處理。注意AfxWndProc和AfxCallWndProc都是AFX的API函數。而WindowProc已經是CWnd的一個方法。是以可以注意到在WindowProc中已經沒有關于句柄或者是CWnd的參數了。
  4. 方法WindowProc首先判斷消息是否為WM_COMMAND,如果不是,就把消息往父類送去;如果是則調用方法OnCommand,再由後者調用OnWndMsg進行正式的消息處理,即把消息派送到相關的方法中去處理。消息是如何派送的呢?實際上在CWnd類中都儲存了一個AFX_MSGMAP的結構,而在AFX_MSGMAP結構中儲存有所有我們用ClassWizard生成的消息的數組的入口,我們把傳給OnWndMsg的message和數組中的所有的message進行比較,找到比對的那一個消息。實際上系統是通過函數AfxFindMessageEntry來實作的。找到了那個message,實際上我們就得到一個AFX_MSGMAP_ENTRY結構,而我們在上面已經提到AFX_MSGMAP_ENTRY儲存了和該消息相關的所有資訊,其中主要的是消息的動作辨別和跟消息相關的執行函數。然後我們就可以根據消息的動作辨別調用相關的執行函數,而這個執行函數實際上就是通過ClassWizard在類實作中定義的一個方法。這樣就把消息的處理轉化到類中的一個方法的實作上。
  5. 如果OnWndMsg方法沒有對消息進行處理的話,就調用DefWindowProc對消息進行處理。這是實際上是調用原來的視窗過程進行預設的消息處理。

繼續閱讀