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

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

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




#0070                  lpEntry = pMessageMap…》lpEntries; 

#0071                  while ((lpEntry = AfxFindMessageEntry (lpEntry; 0xC000; 0; 0)) 

#0072                      != NULL) 

#0073                  { 

#0074                      UINT* pnID = (UINT*)(lpEntry…》nSig); 

#0075                      ASSERT(*pnID 》= 0xC000); 

#0076                              // must be successfully registered 

#0077                      if (*pnID == message) 

#0078                      { 

#0079                              msgCache。lpEntry = lpEntry; 

#0080                              goto LDispatchRegistered; 

#0081                      } 

#0082                      lpEntry++;      // keep looking past this one 

#0083                  } 

#0084              } 

#0085          } 

#0086          msgCache。lpEntry = NULL; 

#0087          return FALSE; 

#0088      } 

#0089      ASSERT(FALSE);      // not reached 

#0090 

#0091  LDispatch: 

#0092      union MessageMapFunctions mmf; 

#0093      mmf。pfn = lpEntry…》pfn; 

#0094 

#0095      switch (lpEntry…》nSig) 

#0096      { 

#0097      case AfxSig_bD: 

#0098              lResult = (this…》*mmf。pfn_bD)(CDC::FromHandle((HDC)wParam)); 

#0099              break; 

#0100 

#0101      case AfxSig_bb:     // AfxSig_bb; AfxSig_bw; AfxSig_bh 

#0102              lResult = (this…》*mmf。pfn_bb)((BOOL)wParam); 

#0103              break; 

#0104 



                                                                                         569 


…………………………………………………………Page 632……………………………………………………………

                   第篇    深入  MFC  程式設計 



                   #0105      case AfxSig_bWww:   // really AfxSig_bWiw 

                   #0106              lResult = (this…》*mmf。pfn_bWww)(CWnd::FromHandle((HWND)wParam); 

                   #0107                      (short)LOWORD(lParam); HIWORD(lParam)); 

                   #0108              break; 

                   #0109 

                   #0110      case AfxSig_bHELPINFO: 

                   #0111              lResult = (this…》*mmf。pfn_bHELPINFO)((HELPINFO*)lParam); 

                   #0112              break; 

                   #0113 

                   #0114      case AfxSig_is: 

                   #0115              lResult = (this…》*mmf。pfn_is)((LPTSTR)lParam); 

                   #0116              break; 

                   #0117 

                   #0118      case AfxSig_lwl: 

                   #0119              lResult = (this…》*mmf。pfn_lwl)(wParam; lParam); 

                   #0120              break; 

                   #0121 

                   #0122      case AfxSig_vv: 

                   #0123              (this…》*mmf。pfn_vv)(); 

                   #0124              break; 

                   #0125      。。。 

                   #0126      } 

                   #0127      goto LReturnTrue; 

                   #0128 

                   #0129  LDispatchRegistered:    // for registered windows messages 

                   #0130      ASSERT(message 》= 0xC000); 

                   #0131      mmf。pfn = lpEntry…》pfn; 

                   #0132      lResult = (this…》*mmf。pfn_lwl)(wParam; lParam); 

                   #0133 

                   #0134  LReturnTrue: 

                   #0135      if (pResult != NULL) 

                   #0136              *pResult = lResult; 

                   #0137      return TRUE; 

                   #0138  } 



                   #0001  AfxFindMessageEntry (const AFX_MSGMAP_ENTRY* lpEntry; 

                   #0002          UINT nMsg; UINT nCode; UINT nID) 

                   #0003  { 

                   #0004  #if defined(_M_IX86) && !defined(_AFX_PORTABLE) 

                   #0005  // 32…bit Intel 386/486 version。 

                   #0006          。。。 //以汇编语言码处理,加快速度。 

                   #0007  #else  // _AFX_PORTABLE 

                   #0008          // C version of search routine 

                   #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 



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