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

            牧光小院

            被約束的日日夜夜,停不下來的時間。

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

            有了消息映射表,如何利用呢?消息如何被分門別類的派發出去的?


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

            MFC中消息分為3類:

            ?1. WM_COMMAND:所有的UI組件和加速鍵都會產生這種消息,所有派生于CCmdTarget的類都有能力處理該消息
            ?2. 標準消息:除WM_COMMAND之外的WM_xx消息都是標準消息,派生于CWnd的類都有能力處理該消息
            ?3. 控件通知消息:用于子窗口控件向父窗口發送的消息

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

            推動消息的泵

            第一階段 窗口過程

            在產生一個窗口的時候,會調用CFrameWnd::Create,所有的故事也都從這里展開。下面的代碼為了簡潔,去掉了不相關的代碼

            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;
            }

            這樣,通過AfxHookWindowCreate,在當前線程中安裝了一個鉤子,用來攔截和窗口相關的事件,每當:

            1. 另一個窗口成為active;
            2. 產生或摧毀一個窗口
            3. Minimize或maximize一個窗口;
            4. 移動或縮放一個窗口;
            5. 完成一個來自系統菜單的命令;
            6. 從系統隊列中取出一個消息;

            時,都會先調用_AfxCbtFilterHook,接下來看看鉤子函數作了什么:

            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的工作總結起來就是通過窗口子類化,把新建的窗口的窗口過程設置成AfxWndProc。
            到這里,我們終于找到了窗口過程。

            結論
            CFrameWnd::Create創建窗口調用CWnd::CreateEx
            CWnd::CreateEx調用AfxHookWindowCreate準備為窗口設置鉤子
            AfxHookWindowCreate調用::SetWindowHookEx為窗口設置了一個WH_CBT類型的鉤子來過濾消息,并把過濾函數設置成_AfxCbtFilterHook
            _AfxCbtFilterHook通過窗口子類化設置窗口的窗口過程為AfxWndProc
            這樣,通過::DispatchMessage發送給窗口的消息就會源源不斷地送到AfxWndProc中來,可以想到,AfxWndProc利用MFC的消息映射表,分門別類的對消息進行分流。

            (待續……)


            posted on 2006-05-18 17:29 nacci 閱讀(3840) 評論(2)  編輯 收藏 引用 所屬分類: C++漫談

            評論

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

            明了,收藏!  回復  更多評論   

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

            字太小了,能大點嗎?  回復  更多評論   

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            導航

            統計

            常用鏈接

            留言簿(2)

            隨筆分類

            收藏夾

            大家的聲音

            積分與排名

            最新評論

            閱讀排行榜

            評論排行榜

            久久久黄片| 久久天天躁狠狠躁夜夜不卡| 老男人久久青草av高清| 亚洲中文字幕伊人久久无码| 伊人久久大香线蕉综合热线| 久久国产精品77777| 精品久久久无码中文字幕天天| 一级a性色生活片久久无| 亚洲精品无码久久久久sm| 国产精品熟女福利久久AV| 区久久AAA片69亚洲| 国产69精品久久久久99尤物| 思思久久好好热精品国产| 国产日产久久高清欧美一区| 一本色道久久综合| 久久99精品久久久久久噜噜| 精品久久久久久无码专区不卡| 久久综合狠狠综合久久97色| 久久青青草原国产精品免费| 国产99久久久国产精品小说| 国产香蕉97碰碰久久人人| 精品乱码久久久久久久| 大香伊人久久精品一区二区| 久久国产乱子伦精品免费午夜| 国产精品免费福利久久| 亚洲精品无码久久久久去q| 一级a性色生活片久久无| 久久国产精品国语对白| 亚洲嫩草影院久久精品| 久久久国产精品福利免费 | 亚洲日本久久久午夜精品| 色综合久久天天综合| 香港aa三级久久三级| 久久免费精品视频| 国产69精品久久久久99| 久久99精品久久久久久| 久久青青草原国产精品免费| 亚洲国产成人久久综合一| 一级做a爱片久久毛片| 久久精品成人一区二区三区| 无码任你躁久久久久久久|