1. 程式人生 > >MFC訊息處理(一)

MFC訊息處理(一)

1、MFC視窗如何與AfxWndProc建立聯絡。

當一個新的CWnd派生類建立時,在呼叫CWnd::CreateEx()過程中,MFC都會安裝AfxCbtFilterHook()。這個Hook將攔截HCBT_CREATEWND,將窗體的訊息處理函式設定為AfxWndProc()。

_AfxCbtFilterHook通過SetWindowLongPtr函式將視窗的處理函式替換成AfxWndProc(),同時,在CWnd::m_pfnSuper中儲存原來的視窗訊息處理函式指標。

微軟不將AfxWndProc()做為註冊視窗過程的原因是DefWindowPorc()可以支援3D控制元件。這些控制元件都在微軟的CTL3D.dll中。如果系統具有CTL3D功能已經是一種迫切需要,那麼應用程式就要覆蓋CTL3D的功能(在處理WM_CTLCOLOR訊息方面)。為了確保這一點,MFC必須按照以下順序呼叫:AfxWndProc()、CTL3D的WndProc()和最後的DefWindowProc()。可見為了確保這一點,微軟不得不允許CTL3D在AfxWndProc()之前分類,這就意味著延遲AfxWndProc()的引入。

2、處理訊息 MFC用兩種方式表示視窗:(1)用統一的系統定義的視窗控制代碼;(2)用表示視窗的C++類。視窗控制代碼由CWnd和CWnd的派生類包裝。因為視窗控制代碼是CWnd的成員變數。
MFC用CMapPtrToPtr物件將視窗控制代碼對映成CWnd物件。MFC在視窗存在期間維護這個連結。如果使用CWnd建立一個視窗,視窗控制代碼就會和CWnd物件關聯在一起,也就是說二者通過控制代碼對映表關聯在一起,MFC這樣做就使得框架可以使用C++物件,而不是視窗控制代碼。 AfxWndProc()處理一個特定訊息:WM_QUERYAFXWNDPROC,如果訊息是WM_QUERYAFXWNDPROC,AfxWndProc()就返回1。應用程式可以通過傳送WM_QUERYAFXWNDPROC訊息來查詢該視窗是否是使用MFC訊息對映系統的MFC視窗。

 

OnWndMsg函式很大,它首先過濾出WM_COMMAND、WM_NOTIFY、WM_ACTIVE和WM_SETCURSOR。對於這幾個訊息,框架有自己的處理方法。如果不是這幾個,OnWndMsg會在訊息對映表中查詢訊息。MFC維護著一個訊息對映表入口快取,可以通過雜湊值訪問它。