系統理解Win32 API和MFC 2

來源:互聯網
上載者:User

二、MFC的概念性模型

前面我們研究了WIN32 API的“領域模型”,對它有較全面的認識。下面,對MFC概念性模型的研究,我們把重點放在對app framework的研究上。
app framework中的message響應/傳遞機制是最重要的。而Hook機制和Message響應/傳遞機制是密切相關的,後者以前者為基礎。

1. Hook機制

也許有些程式員只知道hook機制可以編寫很“牛”的應用,孰不知MFC本身也是依靠hook機制的。

看到,每個hook擁有一個指標隊列,每個指標指向一個稱為的HookProc函數,HookProc將在合適的時機被OS調用執行。hook是分
不同種類的,其實正是hook的種類決定了它什麼時機被OS調用執行。提示,可以看一下“訂閱-發布”設計模式以助理解。

2 MFC中Message響應函數的安裝

2.1 回憶API中Message響應函數的安裝

API中Message響應函數的安裝,是由CreateWindow()實現的,它將window與一個windowClass聯絡起來,而後者中記錄了Message響應函數的指標。
至於細節,看一下如何用Win32 SDK或Win16 SDK寫程式就清楚了,其中 DefWindowProc()是API函數,負責提供預設的訊息處理,所以,程式員只需要handle需要特殊處理的訊息。

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
WNDCLASS wndclass;
...
wndclass.lpfnWndProc =WndProc;
wndclass.lpszClassName = szWindowClass;
...
RegisterClass(&wndclass);
hWnd = CreateWindow( szWindowClass, ...);
...
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
...
return;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}

2.2 MFC中Message響應函數的安裝

MFC中Message響應函數的安裝顯然更複雜,是在CWnd::CreateEx()被調用時完成的,其中還用到了Hook機制。

我們可以先猜一下MFC是怎麼做的。MFC支援massage map,使得對訊息的響應份散到多個message handler函數中,而不是API開發是那種集中式的訊息處理函數;所以,想必會有專門的代碼來負責“檢索message
map table然後調用message handle”。message map是為了支援程式員處理他關心的特殊message的,那麼預設的message處理邏輯在哪裡呢?答案是MFC建立window
obj時是用的“預定義的視窗類別”,自然已經有了預設的message處理函數。

看到,CWnd有成員變數m_pfnSuper、成員變數m_hWnd、成員函數OnWndMsg()和成員函數DefWindowProc()。Wnd::OnWndMsg()負責“在message
map中定義的message handle”能否處理到來的message,如果處理了要返回true;CWnd::DefWindowProc()負責對message預設處理。
執行過程是,首先CWnd::CreateEx()被調用,window obj和window class被相應建立,此時window
class的WindowProc欄位儲存了預定義的預設處理函數的地址;由於有hook在監聽視窗建立訊息,所以註冊的hookProc()會被調用執
行,它將classWindow資料結構的WindowProc欄位備份到CWnd::m_pfnSuper,再用SetWindowLong()改寫
classWindow資料結構的WindowProc欄位為::AfxWndProc()的地址。當任何一個message到達
時,::AfxWndProc()被調用,至於它的邏輯,聰明的你一定猜到了,先調用Wnd::OnWndMsg(),如果傳回值為false,還要調用
CWnd::DefWindowProc(),CWnd::m_pfnSuper指向的預設處理邏輯,也會在CWnd::DefWindowProc()
中被調用。
提示,上面其實有多態情況發生。比如你可以在搜一下pWnd->WindowProc(nMsg, wParam, lParam); 另外,OnWndMsg和DefWindowProc都是CWnd類的虛擬函數。

要是覺得不太好理解,最好在VC++裡建立一個project實際跟蹤一下,下面是我跟蹤時調用棧映象的。

3. SubClass機制


看到,SubClass機制以CWnd自身的m_pfnSuper為基礎,和“MFC中Message響應函數的安裝”很象。

4.frame work中的主要相關類


frame work中的主要相關類 就是 message route的候選人,正是它們的OnCmdMsg()共同完成了message route,形成了chain
of responsability模式。

5. frame work中的chain of responsability模式

是一個對象樹,注意訊息會在縱向和橫向兩個方向傳播。


訊息在縱向方向上的傳遞,是在“上溯父類的massge map表”,MFC的message map完全是為了代替虛函數而採取的手段,而和message
route無關。

訊息在橫向方向上的傳遞,才是message route,才是chain of responsability模式,由多個相關類的OnCmdMsg()共同完成。


三、
總結


從上面的討論不難發現,MFC中用到了不少設計模式,如上面提到的chain of responsability模式、composite模式和“訂閱-發布”模式。上面的討論不僅有助於程式員全面掌握Win32
API和MFC,對architect設計architecture也有很大協助。

聯繫我們

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