• <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>

            牧光小院

            被約束的日日夜夜,停不下來(lái)的時(shí)間。

            MFC漫談(四)——消息的路由

            有了消息映射表,如何利用呢?消息如何被分門(mén)別類(lèi)的派發(fā)出去的?


            用最基本的一句話概述,鉤子函數(shù)起了很大作用。故事是這樣的,有些漫長(zhǎng),也需要些耐心。

            MFC中消息分為3類(lèi):

            ?1. WM_COMMAND:所有的UI組件和加速鍵都會(huì)產(chǎn)生這種消息,所有派生于CCmdTarget的類(lèi)都有能力處理該消息
            ?2. 標(biāo)準(zhǔn)消息:除WM_COMMAND之外的WM_xx消息都是標(biāo)準(zhǔn)消息,派生于CWnd的類(lèi)都有能力處理該消息
            ?3. 控件通知消息:用于子窗口控件向父窗口發(fā)送的消息

            在MFC的消息映射表的建立中,通過(guò)一組宏,你就可以讓自己的類(lèi)先于父類(lèi)處理某些Windows消息,這種行為很像虛函數(shù),只是我們重載的內(nèi)容不是虛函數(shù),而是消息。

            推動(dòng)消息的泵

            第一階段 窗口過(guò)程

            在產(chǎn)生一個(gè)窗口的時(shí)候,會(huì)調(diào)用CFrameWnd::Create,所有的故事也都從這里展開(kāi)。下面的代碼為了簡(jiǎn)潔,去掉了不相關(guān)的代碼

            BOOL?CFrameWnd::Create(…)? {
            ????
            // ?…

            ???? if ?( ! CreateEx(…))? {
            ????????
            // ?…

            ????}

            ????
            // ?…
            }


            BOOL?CWnd::CreateEx(…)?
            {
            ????
            // ?…

            ????AfxHookWindowCreate( this );
            ????HWND?hWnd?
            =
            ?::CreateWindowEx(…);
            ????
            // ?…

            }


            void ?AFXAPI?AfxHookWindowCreate(CWnd * ?pWnd)? {
            ????
            // ?…

            ???? if ?(pThreadState -> m_hHookOldCbtFilter? == ?NULL)? {
            ????????pThreadState
            -> m_hHookOldCbtFilter? =
            ?::SetWindowsHookEx(WH_CBT,
            ????????_AfxCbtFilterHook,?NULL,?::GetCurrentThreadId());
            ????????
            // ?…

            ????}

            ????
            // ?…
            ????pThreadState -> m_pWndInit? = ?pWnd;
            }

            這樣,通過(guò)AfxHookWindowCreate,在當(dāng)前線程中安裝了一個(gè)鉤子,用來(lái)攔截和窗口相關(guān)的事件,每當(dāng):

            1. 另一個(gè)窗口成為active;
            2. 產(chǎn)生或摧毀一個(gè)窗口
            3. Minimize或maximize一個(gè)窗口;
            4. 移動(dòng)或縮放一個(gè)窗口;
            5. 完成一個(gè)來(lái)自系統(tǒng)菜單的命令;
            6. 從系統(tǒng)隊(duì)列中取出一個(gè)消息;

            時(shí),都會(huì)先調(diào)用_AfxCbtFilterHook,接下來(lái)看看鉤子函數(shù)作了什么:

            LRESULT?CALLBACK
            _AfxCbtFilterHook(
            int ?code,?WPARAM?wParam,?LPARAM?lParam)?
            {
            ????
            // ?…

            ????WNDPROC?afxWndProc? = ?AfxGetAfxWndProc();
            ????oldWndProc?
            =
            ?(WNDPROC)SetWindowLongPtr(hWnd,?GWLP_WNDPROC,(DWORD_PTR)afxWndProc);
            ????
            // ?…

            }


            WNDPROC?AFXAPI?AfxGetAfxWndProc()?
            {
            ????
            // ?…

            ???? return ? & AfxWndProc;
            }

            這樣,_AfxCbtFilterHook的工作總結(jié)起來(lái)就是通過(guò)窗口子類(lèi)化,把新建的窗口的窗口過(guò)程設(shè)置成AfxWndProc。
            到這里,我們終于找到了窗口過(guò)程。

            結(jié)論
            CFrameWnd::Create創(chuàng)建窗口調(diào)用CWnd::CreateEx
            CWnd::CreateEx調(diào)用AfxHookWindowCreate準(zhǔn)備為窗口設(shè)置鉤子
            AfxHookWindowCreate調(diào)用::SetWindowHookEx為窗口設(shè)置了一個(gè)WH_CBT類(lèi)型的鉤子來(lái)過(guò)濾消息,并把過(guò)濾函數(shù)設(shè)置成_AfxCbtFilterHook
            _AfxCbtFilterHook通過(guò)窗口子類(lèi)化設(shè)置窗口的窗口過(guò)程為AfxWndProc
            這樣,通過(guò)::DispatchMessage發(fā)送給窗口的消息就會(huì)源源不斷地送到AfxWndProc中來(lái),可以想到,AfxWndProc利用MFC的消息映射表,分門(mén)別類(lèi)的對(duì)消息進(jìn)行分流。

            (待續(xù)……)


            posted on 2006-05-18 17:29 nacci 閱讀(3864) 評(píng)論(2)  編輯 收藏 引用 所屬分類(lèi): C++漫談

            評(píng)論

            # re: MFC漫談(四)——消息的路由 2007-10-11 15:41 seamonst

            明了,收藏!  回復(fù)  更多評(píng)論   

            # re: MFC漫談(四)——消息的路由 2007-12-27 22:04 秦歌

            字太小了,能大點(diǎn)嗎?  回復(fù)  更多評(píng)論   

            <2007年10月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿(2)

            隨筆分類(lèi)

            收藏夾

            大家的聲音

            積分與排名

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            欧美精品一区二区久久| 国产成人精品久久亚洲| 久久人妻AV中文字幕| 久久久久久久97| 精品久久久久久亚洲| 精品无码久久久久久久久久| 日本高清无卡码一区二区久久| 久久久亚洲AV波多野结衣 | 成人精品一区二区久久| 久久久这里有精品中文字幕| 2021最新久久久视精品爱| 久久精品国产亚洲精品2020| 国产亚州精品女人久久久久久 | 色播久久人人爽人人爽人人片aV| 中文字幕热久久久久久久| 精品国产乱码久久久久久1区2区| 久久99精品国产99久久6| 亚洲AV成人无码久久精品老人| 国产精品青草久久久久福利99| 伊人久久大香线蕉av不卡| 99久久国产免费福利| 色妞色综合久久夜夜| 久久青青草视频| 久久亚洲天堂| 久久精品国产亚洲7777| 欧美激情精品久久久久| 久久精品国产亚洲av水果派| 久久精品国产免费观看三人同眠| 精品久久久久国产免费| 久久青青草原国产精品免费| 久久久久久久97| 日韩久久久久久中文人妻| 伊人久久综合成人网| 中文字幕无码av激情不卡久久| 久久久久成人精品无码| 国内精品久久久久久久亚洲| 久久综合九色综合精品| 欧美综合天天夜夜久久| 爱做久久久久久| 日韩欧美亚洲国产精品字幕久久久 | 久久久精品无码专区不卡|