• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            系統(tǒng)理解Win32 API和MFC(下)

            系統(tǒng)理解Win32 API和MFC(下)
            作者: 溫昱
            作者主頁(yè): lcspace.diy.163.com

            系統(tǒng)理解Win32 API和MFC(上)

            二、MFC的概念模型

            前面我們研究了WIN32 API的“領(lǐng)域模型”,對(duì)它有較全面的認(rèn)識(shí)。下面,對(duì)MFC概念模型的研究,我們把重點(diǎn)放在對(duì)app framework的研究上。
            app framework中的message響應(yīng)/傳遞機(jī)制是最重要的。而Hook機(jī)制和Message響應(yīng)/傳遞機(jī)制是密切相關(guān)的,后者以前者為基礎(chǔ)。

            1. Hook機(jī)制

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

            從圖中看到,每個(gè)hook擁有一個(gè)指針隊(duì)列,每個(gè)指針指向一個(gè)稱為的HookProc函數(shù),HookProc將在合適的時(shí)機(jī)被OS調(diào)用執(zhí)行。hook是分不同種類的,其實(shí)正是hook的種類決定了它什么時(shí)機(jī)被OS調(diào)用執(zhí)行。提示,可以看一下“訂閱-發(fā)布”設(shè)計(jì)模式以助理解。

            2 MFC中Message響應(yīng)函數(shù)的安裝

            2.1 回憶API中Message響應(yīng)函數(shù)的安裝

            API中Message響應(yīng)函數(shù)的安裝,是由CreateWindow()實(shí)現(xiàn)的,它將window與一個(gè)windowClass聯(lián)系起來,而后者中記錄了Message響應(yīng)函數(shù)的指針。
            至于細(xì)節(jié),看一下如何用Win32 SDK或Win16 SDK寫程序就清楚了,其中 DefWindowProc()是API函數(shù),負(fù)責(zé)提供缺省的消息處理,所以,程序員只需要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響應(yīng)函數(shù)的安裝

            MFC中Message響應(yīng)函數(shù)的安裝顯然更復(fù)雜,是在CWnd::CreateEx()被調(diào)用時(shí)完成的,其中還用到了Hook機(jī)制。

            我們可以先猜一下MFC是怎么做的。MFC支持massage map,使得對(duì)消息的響應(yīng)份散到多個(gè)message handler函數(shù)中,而不是API開發(fā)是那種集中式的消息處理函數(shù);所以,想必會(huì)有專門的代碼來負(fù)責(zé)“檢索message map table然后調(diào)用message handle”。message map是為了支持程序員處理他關(guān)心的特殊message的,那么缺省的message處理邏輯在哪里呢?答案是MFC創(chuàng)建window obj時(shí)是用的“預(yù)定義的窗口類”,自然已經(jīng)有了缺省的message處理函數(shù)。

            從圖中看到,CWnd有成員變量m_pfnSuper、成員變量m_hWnd、成員函數(shù)OnWndMsg()和成員函數(shù)DefWindowProc()。Wnd::OnWndMsg()負(fù)責(zé)“在message map中定義的message handle”能否處理到來的message,如果處理了要返回true;CWnd::DefWindowProc()負(fù)責(zé)對(duì)message缺省處理。
            執(zhí)行過程是,首先CWnd::CreateEx()被調(diào)用,window obj和window class被相應(yīng)建立,此時(shí)window class的WindowProc字段存儲(chǔ)了預(yù)定義的缺省處理函數(shù)的地址;由于有hook在監(jiān)聽窗口創(chuàng)建消息,所以注冊(cè)的hookProc()會(huì)被調(diào)用執(zhí)行,它將classWindow數(shù)據(jù)結(jié)構(gòu)的WindowProc字段備份到CWnd::m_pfnSuper,再用SetWindowLong()改寫classWindow數(shù)據(jù)結(jié)構(gòu)的WindowProc字段為::AfxWndProc()的地址。當(dāng)任何一個(gè)message到達(dá)時(shí),::AfxWndProc()被調(diào)用,至于它的邏輯,聰明的你一定猜到了,先調(diào)用Wnd::OnWndMsg(),如果返回值為false,還要調(diào)用CWnd::DefWindowProc(),CWnd::m_pfnSuper指向的缺省處理邏輯,也會(huì)在CWnd::DefWindowProc()中被調(diào)用。
            提示,上面其實(shí)有多態(tài)情況發(fā)生。比如你可以在搜一下pWnd->WindowProc(nMsg, wParam, lParam); 另外,OnWndMsg和DefWindowProc都是CWnd類的虛擬函數(shù)。

            要是覺得不太好理解,最好在VC++里創(chuàng)建一個(gè)project實(shí)際跟蹤一下,下面是我跟蹤時(shí)調(diào)用棧映象的截圖。


            3. SubClass機(jī)制


            從圖中看到,SubClass機(jī)制以CWnd自身的m_pfnSuper為基礎(chǔ),和“MFC中Message響應(yīng)函數(shù)的安裝”很象。

            4.frame work中的主要相關(guān)類

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

            5. frame work中的chain of responsability模式

            下圖是一個(gè)對(duì)象樹,注意消息會(huì)在縱向和橫向兩個(gè)方向傳播。


            消息在縱向方向上的傳遞,是在“上溯父類的massge map表”,MFC的message map完全是為了代替虛函數(shù)而采取的手段,而和message route無關(guān)。

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

            三、 總結(jié)
            從上面的討論不難發(fā)現(xiàn),MFC中用到了不少設(shè)計(jì)模式,如上面提到的chain of responsability模式、composite模式和“訂閱-發(fā)布”模式。上面的討論不僅有助于程序員全面掌握Win32 API和MFC,對(duì)architect設(shè)計(jì)architecture也有很大幫助。

            posted on 2008-11-01 15:38 wrh 閱讀(352) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            導(dǎo)航

            <2008年9月>
            31123456
            78910111213
            14151617181920
            21222324252627
            2829301234
            567891011

            統(tǒng)計(jì)

            常用鏈接

            留言簿(19)

            隨筆檔案

            文章檔案

            收藏夾

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久久噜噜噜久久| 噜噜噜色噜噜噜久久| 亚洲性久久久影院| 亚洲国产成人久久一区久久| 99精品国产免费久久久久久下载| 久久久婷婷五月亚洲97号色 | 国内精品久久久久影院老司| 久久久久波多野结衣高潮| 97久久久久人妻精品专区| 日本精品久久久久中文字幕8| 精品国产乱码久久久久久浪潮| 久久亚洲熟女cc98cm| 精品久久无码中文字幕| 久久久久亚洲精品日久生情| 一本色道久久88—综合亚洲精品 | 日产精品99久久久久久| 99久久精品九九亚洲精品| 热RE99久久精品国产66热| 天天爽天天爽天天片a久久网| 久久99精品国产麻豆婷婷| 亚洲AV日韩精品久久久久久| 国内精品伊人久久久久妇| 伊人久久综在合线亚洲2019| 久久精品亚洲日本波多野结衣 | …久久精品99久久香蕉国产| 久久亚洲国产成人影院网站| 久久精品这里热有精品| 精品久久久久久中文字幕大豆网| 久久精品国产精品亚洲人人| 国产综合成人久久大片91| 久久综合久久自在自线精品自 | 日本强好片久久久久久AAA | 久久精品国产99久久久| 久久久久久久久久久精品尤物| 久久精品亚洲欧美日韩久久| 日韩精品久久久久久| 91精品国产色综合久久| 久久99精品久久只有精品| 久久久女人与动物群交毛片| 亚洲精品高清国产一线久久 | 久久久久久国产精品免费免费|