友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
狗狗书籍 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

深入浅出MFC第2版(PDF格式)-第192章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!






你设定的一个所谓「滤网函数(filter )」。 



请查阅Win32 API 手册中有关于SetWindowsHook 和SetWindowsHookEx 两函数,以获 



得更多的hook 信息。(可参考Windows 95           A Developer s Guide 一书第6章Hooks ) 



MFC 4。x  的hook 动作是在每一个CWnd 衍生类别之对象产生之际发生,步骤如下: 



// in WINCORE。CPP (MFC 4。x) 



// 请回顾第6章「CFrameWnd::Create产生主窗口」一节 



BOOL CWnd::CreateEx(。。。) 

 { 

     。。。 

     PreCreateWindow(cs);   // 第6章曾经详细讨论过此一函数。 

     AfxHookWindowCreate(this); 

     HWND hWnd = ::CreateWindowEx(。。。); 

     。。。 

 } 



                  (        ) 

 // in WINCORE。CPP  MFC 4。x 

void AFXAPI AfxHookWindowCreate(CWnd* pWnd) 

 { 

    。。。 

    pThreadState…》m_hHookOldCbtFilter =  ::SetWindowsHookEx(WH_CBT; 

            _AfxCbtFilterHook; NULL; ::GetCurrentThreadId()); 

    。。。 

 } 



 WH_CBT 是众多hook 类型中的一种,意味着安装一个puter…Based Training  (CBT ) 



 滤网函数。安装之后,Windows 系统在进行以下任何一个动作之前,会先调用你的滤网 



 函数: 



令一个窗口成为作用中的窗口(HCBT_ACTIVATE ) 



产生或摧毁一个窗口(HCBT_CREATEWND 、HCBT_DESTROYWND ) 



最大化或最小化一个窗口(HCBT_MINMAX ) 



                                                                                563 


…………………………………………………………Page 626……………………………………………………………

                    第篇    深入  MFC  程式設計 



                      搬移或缩放一个窗口(HCBT_MOVESIZE ) 



                      完成一个来自系统菜单的系统命令(HCBT_SYSTEMMAND ) 



                      从系统队列中移去一个鼠标或键盘消息 (HCBT_KEYSKIPPED  、 



                       HCBT_CLICKSKIPPED ) 



                    因此,经过上述hook 安装之后,任何窗口即将产生之前,滤网函数_AfxCbtFilterHook  一 



                    定会先被调用: 



                    _AfxCbtFilterHook(int code; WPARAM wParam; LPARAM lParam) 

                     { 

                        _AFX_THREAD_STATE* pThreadState = AfxGetThreadState(); 

                        if (code != HCBT_CREATEWND) 

                        { 

                                // wait for HCBT_CREATEWND just pass others on。。。 

                                return CallNextHookEx(pThreadState…》m_hHookOldCbtFilter; code; 

                                        wParam; lParam); 

                        } 

                        。。。 

                                if (!afxData。bWin31) 

                                { 

                                        // perform subclassing right away on Win32 

                                        _AfxStandardSubclass((HWND)wParam); 

                                } 

                                else 

                                { 

                                   。。。 

                                } 

                        。。。 

                        LRESULT lResult = CallNextHookEx(pThreadState…》m_hHookOldCbtFilter; code; 

                                wParam; lParam); 

                        return lResult; 

                     } 



                    void AFXAPI _AfxStandardSubclass(HWND hWnd) 

                     { 

                        。。。 

                        // subclass the window with standard AfxWndProc 

                        oldWndProc = (WNDPROC)SetWindowLong (hWnd; GWL_WNDPROC; 

                                (DWORD)AfxGetAfxWndProc ()); 

                     } 



                    WNDPROC AFXAPI AfxGetAfxWndProc() 

                     { 



564 


…………………………………………………………Page 627……………………………………………………………

                                                         第9章   訊息映射與命令繞行   



    。。。 

    return &AfxWndProc; 

} 



啊,非常明显,上面的函数合力做了偷天换日的勾当:把「窗口所属之Windows 窗口类 



别」中所记录的窗口函数,改换为AfxWndProc 。于是,::DispatchMessage 就把消息源源 



推往AfxWndProc  去了。 



这种看起来很迂回又怪异的作法,是为了包容新的3D Controls                         (细节就容我省略了吧), 



并与MFC 2。5 兼容。下图把前述的hook 和subclassing 动作以流程图显示出来: 



  CFrameWnd::LoadFrame 

   CFrameWnd::LoadFrame 



    CFrameWnd::Create 

     CFrameWnd::Create 



      CWnd::CreateEx 

       CWnd::CreateEx                              安装WH_CBT hook ,设定滤网函数 



                                                   为_AfxCbtFilterHook 

                      AfxHookWindowCreate(this) 

                       AfxHookWindowCreate(this) 



                        ::SetWindowsHookEx(WH_CBT; _AfxCbtFilterHook ;。。。) 

                         ::SetWindowsHookEx(WH_CBT; _AfxCbtFilterHook ;。。。) 



     ::CreateWindowEx 

      ::CreateWindowEx 



                        _AfxCbtFilterHook     窗口产生之前一刻,由于曾安装过 

                         _AfxCbtFilterHook     WH_CBT hook,所以滤网函数 



                                              _AfxCbtFilterHook 会先被唤起。 

                       _AfxStandardSubclass 

                       _AfxStandardSubclass 



                     SetWindowLong(hWnd; GWL_WNDPROC;&AfxWndProc) 

                      SetWindowLong(hWnd; GWL_WNDPROC;&AfxWndProc) 



                                                             WND structure 

                                         subclassing 动作;改                   各种消息,来自 

                                           变窗口函数。              extra bytes ::DispatchMessage 



                message mapping and                                        的唧送,或由操作 

                   mand routing                                         系统直接送达。 



                (through message map)                                      CWL_WNDPROC 

                       。 

                                                             &AfxWndProc 



    message handler 

     message handler 



                                                                                
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!