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

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

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





…………………………………………………………Page 642……………………………………………………………

                 第篇    深入  MFC  程式設計 



             罗塞达碑石:AfxSig_xx 的奥秘 



                大架构建立起来了,但我还没有很仔细地解释在消息映射「网」中的_messageEntries '' 



                数组内容。为什么消息经由推动引擎(上一节谈的那整套家伙)推过这些数组,就可以 



                找到它的处理例程? 



                Paul DiLascia 在他的文章(! ¨ Meandering Through the Maze of MFC Message and mand 



                Routing!  ¨,Microsoft Systems Journal ,1995/07)中形容这些数组之内一笔一笔的记录像 



                是罗塞达碑石,呵呵,就靠它们揭开消息映射的最后谜底了。 



                 罗塞达碑石(Rosetta Stone ),1799 年拿破仑远征埃及时,由一名官员在尼罗河口罗塞 



                 达发现,揭开了古埃及象形文字之谜。石碑是黑色玄武岩,高114 公分,厚28 公分,宽 



                 72 公分。经法国学者Jean…Francois Champollion 研究后,世人因得顺利研读古埃及文献。 



                 消息映射表的每一笔记录是这样的形式: 



                 struct AFX_MSGMAP_ENTRY 

                 { 

                     UINT nMessage;   // windows message 

                     UINT nCode;      // control code or WM_NOTIFY code 

                     UINT nID;        // control ID (or 0 for windows messages) 

                     UINT nLastID;    // used for entries specifying a range of control id's 

                     UINT nSig;       // signature type (action) or pointer to message # 

                     AFX_PMSG pfn;    // routine to call (or special value) 

                 }; 



                 内中包括一个Windows 消息、其控制组件ID  以及通告码(notification code ,对消息的 



                 更多描述,例如EN_CHANGED 或CBN_DROPDIOWN 等)、一个签名记号、以及一个 



                 CCmdTarget 衍生类别的成员函数。任何一个ON_ 宏会把这六个项目初始化起来。例 



                 如: 



                 #define ON_WM_CREATE ()  

                   { WM_CREATE; 0; 0; 0; AfxSig_is;  

                     (AFX_PMSG)(AFX_PMSGW)(int (AFX_MSG_CALL CWnd::*)(LPCREATESTRUCT))OnCreate }; 



                 你看到了可怕的类型转换动作,这完全是为了保持类型安全(type…safe )。 



580 


…………………………………………………………Page 643……………………………………………………………

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



有一个很莫名其妙的东西:AfxSig_ 。要了解它作什么用,你得先停下来几分钟,想想另 



一个问题:当上一节的推动引擎比对消息并发现吻合之后,就调用对应的处理例程,但 



它怎么知道要交给消息处理例程哪些参数呢?要知道,不同的消息处理例程需要不同的 



参数(包括个数和类型),而其函数指针(AFX_PMSG )却都被定义为这付德行: 



   typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void); 



这么简陋的信息无法表现应该传递什么样的参数,而这正是AfxSig_ 要贡献的地方。当 



推动引擎比对完成,欲调用某个消息处理例程lpEntry…》pfn 时,动作是这样子地(出现 



在CWnd::OnWndMsg 和DispatchCmdMsg  中): 



 union MessageMapFunctions mmf; 

 mmf。pfn = lpEntry…》pfn; 



 switch (lpEntry…》nSig) 

 { 

 case AfxSig_is: 

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

         break; 



 case AfxSig_lwl: 

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

         break; 



 case AfxSig_vv: 

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

         break; 

 。。。 

 } 



注意两样东西:MessageMapFunctions 和AfxSig_ 。AfxSig_ 定义于AFXMSG_。H 档: 



 enum AfxSig 

 { 

         AfxSig_end = 0;     // 'marks end of message map' 



         AfxSig_bD;      // BOOL (CDC*) 

         AfxSig_bb;      // BOOL (BOOL) 

         AfxSig_bWww;    // BOOL (CWnd*; UINT; UINT) 

         AfxSig_hDWw;    // HBRUSH (CDC*; CWnd*; UINT) 

         AfxSig_hDw;     // HBRUSH (CDC*; UINT) 



                                                                                      581 


…………………………………………………………Page 644……………………………………………………………

                   第篇    深入  MFC  程式設計 



                           AfxSig_iwWw;    // int (UINT; CWnd*; UINT) 

                           AfxSig_iww;     // int (UINT; UINT) 

                           AfxSig_iWww;    // int (CWnd*; UINT; UINT) 

                           AfxSig_is;      // int (LPTSTR) 

                           AfxSig_lwl;     // LRESULT (WPARAM; LPARAM) 

                           AfxSig_lwwM;    // LRESULT (UINT; UINT; CMenu*) 

                           AfxSig_vv;      // void (void) 



                           AfxSig_vw;      // void (UINT) 

                           AfxSig_vww;     // void (UINT; UINT) 

                           AfxSig_vvii;    // void (int; int) // wParam is ignored 

                           AfxSig_vwww;    // void (UINT; UINT; UINT) 

                           AfxSig_vwii;    // void (UINT; int; int) 

                           AfxSig_vwl;     // void (UINT; LPARAM) 

                           AfxSig_vbWW;    // void (BOOL; CWnd*; CWnd*) 

                           AfxSig_vD;      // void (CDC*) 

                           AfxSig_vM;      // void (CMenu*) 

                           AfxSig_vMwb;    // void (CMenu*; UINT; BOOL) 



                           AfxSig_vW;      // void (CWnd*) 

                           AfxSig_vWww;    // void (CWnd*; UINT; UINT) 

                           AfxSig_vWp;     // void (CWnd*; CPoint) 

                           AfxSig_vWh;     // void (CWnd*; HANDLE) 

                           AfxSig_vwW;     // void (UINT; CWnd*) 

                           AfxSig_vwWb;    // void (UINT; CWnd*; BOOL) 

                           AfxSig_vwwW;    // void (UINT; UINT; CWnd*) 

                           AfxSig_vwwx;    // void (UINT; UINT) 

                           AfxSig_vs;      // void (LPTSTR) 

                           AfxSig_vOWNER;  // void (int; LPTSTR); force return TRUE 

                           AfxSig_iis;     // int (int; LPTSTR) 

                           AfxSig_wp;      // UINT (CPoint) 

                           AfxSig_wv;      // UINT (void) 

                           AfxSig_vPOS;    // void (WINDOWPOS*) 

                           AfxSig_vCALC;   // void (BOOL; NCCALCSIZE_PARAMS*) 

                           AfxSig_vNMHDRpl;    // void (NMHDR*; LRESULT*) 

                           AfxSig_bNMHDRpl;    // BOOL (NMHDR*; LRESULT*) 

                           AfxSig_vwNMHDRpl;   // void (UINT; NMHDR*; LRESULT*) 

                           AfxSig_bwNMHDRpl;   // BOOL (UINT; NMHDR*; LRESULT*) 

                           AfxSig_bHELPINFO;   // BOOL (HELPINFO*) 

                           AfxSig_vwSIZING;    // void (UINT; LPRECT) …return TRUE 



                           // signatures specific to CCmdTarget 

                           AfxSig_cmdui;   // void (CCmdUI*) 

                           AfxSig_cmduiw;  // void (CCmdUI*; UINT) 

                           AfxSig_vpv;     // void (void*) 

                           AfxSig_bpv;     // BOOL (void*) 



582 


…………………………………………………………Page 645……………………………………………………………

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



        // Other aliases (based on implementation) 

        AfxSig_vwwh;                // void (UINT; UINT; HANDLE) 

        AfxSig_vwp;                 // void (UINT; CPoint) 

        AfxSig_bw = AfxSig_bb;      // BOOL (UINT) 

        AfxSig_bh = AfxSig_bb;      // BOOL (HANDLE) 

        AfxSig_iw = AfxSig_bb;      // int (UINT) 

        AfxSig_ww = AfxSig_bb;      // UINT (UINT) 

        AfxSig_bv = AfxSig_wv;      // BOOL (void) 

        AfxSig_hv = AfxSig_wv;      // HANDLE (void) 

        AfxSig_vb = AfxSig_vw;      // void (BOOL) 

        AfxSig_vbh = AfxSig_vww;    // void (BOOL; HANDLE) 

        AfxSig_vbw = AfxSig_vww;    // void (BOOL; UINT) 

        AfxSig_vhh = AfxSig_vww;    // void (HANDLE; HANDLE) 

        AfxSig_vh = AfxSig_vw;      // void (HANDLE) 

        AfxSig_viSS = AfxSig_vwl;   // void (int; STYLESTRUCT*) 

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