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

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

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




                   #0009          while (lpEntry…》nSig != AfxSig_end) 

                   #0010          { 

                   #0011              if (lpEntry…》nMessage == nMsg && lpEntry…》nCode == nCode && 



570 


…………………………………………………………Page 633……………………………………………………………

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



#0012                  nID 》= lpEntry…》nID && nID nLastID) 

#0013              { 

#0014                  return lpEntry; 

#0015              } 

#0016              lpEntry++; 

#0017          } 

#0018          return NULL;    // not found 

#0019  #endif  // _AFX_PORTABLE 

#0020  } 



 直线上溯的逻辑实在是相当单纯的了,唯一做的动作就是比对消息映射表,如果吻合就 



 调用表中项目所记录的函数。比对的对象有二,一个是原原本本的消息映射表(那个巨 



 大的结构),另一个是MFC 为求快速所设计的一个cache                                         (cache  的实作太过复杂,我并 



 没有把它的源代码表现出来)。比对成功后,调用对应之函数时,有一个巨大的switch/case 



 动作,那是为了确保类型安全(type…safe )。稍后我有一个小节详细讨论之。 



                          CWinThread        CWinApp         CMyWinApp 



                                                                                这就是在CMyView 窗口 



                                                                                所发生的WM_PAINT消 

                                                ; ; ; ; ;        ; ; ; ; ;       息的流动路线 



                                              0;0;0;0;0;0      0;0;0;0;0;0 

                                                                              CView           CMyView 



                                                                                                                   m 

                                                                                                                    e 

  CCmdTarget                 CWnd          CFrameWnd        CMyFrameWnd 

                                                                                                                    s 

                                                                                  ; ; ; ; ;       ; ; ; ; ; 



                                                                                                                    s 

                                                                               0;0;0;0;0;0      0;0;0;0;0;0         a 



                                ; ; ; ; ;       ; ; ; ; ;        ; ; ; ; ; 

        ; ; ; ; ;                                                                                                  g 

                              0;0;0;0;0;0     0;0;0;0;0;0      0;0;0;0;0;0                                          e 

     0;0;0;0;0;0 



                          CDocument       CMyDocument 



                                ; ; ; ; ;       ; ; ; ; ; 



                              0;0;0;0;0;0     0;0;0;0;0;0 



                       图9…3 当WM_PAINT 发生于View 窗口, 消息的流动路线。 



                                                                                                                     571 


…………………………………………………………Page 634……………………………………………………………

                   第篇    深入  MFC  程式設計 



             拐弯上溯(WM_MAND 命令消息) 



                   如果消息是WM_MAND,你看到了,CWnd::OnWndMsg                   (上节所述)另辟蹊跷,交 



                   由Onmand 来处理。这并不一定就指的是CWnd::Onmand,得视this 指针指向 



                   哪一种对象而定。在MFC 之中,以下数个类别都改写了Onmand 虚拟函数: 



                       class CWnd : public CCmdTarget 

                       class CFrameWnd : public CWnd 

                       class CMDIFrameWnd : public CFrameWnd 

                       class CSplitterWnd : public CWnd 

                       class CPropertySheet : public CWnd 

                       class COlePropertyPage : public CDialog 



                   我们挑一个例子来看。假设消息是从CFrameWnd 进来的好了,于是: 



                                     (        ) 

                   // in FRMWND。CPP  MFC 4。0 

                   BOOL CFrameWnd::Onmand (WPARAM wParam; LPARAM lParam) 

                    { 

                           。。。 



                           // route as normal mand 

                           return CWnd::Onmand (wParam; lParam); 

                    } 

                                       (       ) 

                   // in WINCORE。CPP  MFC 4。0 

                   BOOL CWnd::Onmand (WPARAM wParam; LPARAM lParam) 

                    { 

                           。。。 

                           return OnCmdMsg (nID; nCode; NULL; NULL); 

                    } 



                   这里调用的OnCmdMsg 并不一定就是指CWnd::OnCmdMsg,得看this 指针指向哪一种 



                   对象而定。目前情况是指向一个CFrameWnd 对象,而MFC 之中「拥有」OnCmdMsg 的 



                   类别(注意,此话有语病,我应该说MFC 之中「曾经改写」过OnCmdMsg 的类别)是: 



                       class CCmdTarget : public CObject 

                       class CFrameWnd : public CWnd 

                       class CMDIFrameWnd : public CFrameWnd 

                       class CView : public CWnd 

                       class CPropertySheet : public CWnd 

                       class CDialog : public CWnd 

                       class CDocument : public CCmdTarget 

                       class COleDocument : public CDocument 



572 


…………………………………………………………Page 635……………………………………………………………

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



显然我们应该往CFrameWnd 追踪: 



                   (        ) 

// in FRMWND。CPP  MFC 4。0 

BOOL CFrameWnd::OnCmdMsg (UINT nID; int nCode; void* pExtra; 

        AFX_CMDHANDLERINFO* pHandlerInfo) 

{ 

        // pump through current view FIRST 

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