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

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

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






               当窗口函数做消息的比对时,我们就可以想办法导引它沿着这条路走过去: 



170 


…………………………………………………………Page 233……………………………………………………………

                                                           第3章    MFC 六大關鍵技術之模擬 



  CObject 

   CObject 



      CCmdTarget 

       CCmdTarget 



         CWinThread 

          CWinThread 



             CWinApp 

             CWinApp 



                CMyWinApp 

                 CMyWinApp 



         CWnd 

          CWnd 



             CView 



                CMyView 

                 CMyView 



             CFrameWnd 

             CFrameWnd 



                CMyFrameWnd 

                 CMyFrameWnd 



         CDocument 

          CDocument 



             CMyDoc 

             CMyDoc 



但是,MFC 之中用来处理消息的C++ 类别,并不呈单鞭发展。作为application framework 



的重要架构之一的document/view ,也具有处理消息的能力(你现在可能还不清楚什么是 



document/view ,没有关系)。因此,消息藉以攀爬的路线应该有横流的机会: 



  CObject 

   CObject 



      CCmdTarget 

       CCmdTarget 



          CWinThread 

           CWinThread 



              CWinApp 

              CWinApp 



                 CMyWinApp 

                  CMyWinApp 



          CWnd 

           CWnd 



              CView 



                 CMyView 

                  CMyView 



              CFrameWnd 

              CFrameWnd 



                 CMyFrameWnd 

                  CMyFrameWnd 



          CDocument 

           CDocument 



              CMyDoc 

              CMyDoc 



                                                                                                    171 


…………………………………………………………Page 234……………………………………………………………

                  第篇  勿在浮砂築高台 



                  消息如何流动,我们暂时先不管。是直线前进,或是中途换跑道,我们都暂时不管,本 



                  节先把这个攀爬路线网建立起来再说。这整个攀爬路线网就是所谓的消息映射表 



                   (Message Map );说它是一张地图,当然也没有错。将消息与表格中的元素比对,然后 



                  调用对应的处理例程,这种动作我们也称之为消息映射(Message Mapping)。 



                  为了尽量降低对正常(一般)类别声明和定义的影响,我们希望,最好能够像RTTI 和 



                  Dynamic Creation 一样,用一两个宏就完成这巨大蜘蛛网的构造。最好能够像 



                  DECLARE_DYNAMIC 和IMPLEMENT_DYNAMIC 宏那么方便。 



                  首先定义一个数据结构: 



                     struct AFX_MSGMAP 

                      { 

                             AFX_MSGMAP* pBaseMessageMap; 

                             AFX_MSGMAP_ENTRY* lpEntries; 

                      }; 



                   其中的 AFX_MSGMAP_ENTRY 又是另一个数据结构: 



                     struct AFX_MSGMAP_ENTRY  // MFC 4。0 format 

                      { 

                             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) 

                      }; 



                    其中的AFX_PMSG 定义为函数指针: 



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



                     然后我们定义一个宏: 



                     #define DECLARE_MESSAGE_MAP()  

                             static AFX_MSGMAP_ENTRY _messageEntries'';  

                             static AFX_MSGMAP messageMap;  

                             virtual AFX_MSGMAP* GetMessageMap() const; 



172 


…………………………………………………………Page 235……………………………………………………………

                                                       第3章    MFC 六大關鍵技術之模擬 



 于是,DECLARE_MESSAGE_MAP 就相当于声明了这样一个数据结构: 



                                                        pBaseMessageMap 

                         _messageEntries'' 

                                                            lpEntries 

                nMessage; nCode; nID; nLastID; nSig; pfn 



                                                          messageMap 



这个数据结构的内容填塞工作由三个宏完成: 



#define BEGIN_MESSAGE_MAP (theClass; baseClass)  

        AFX_MSGMAP* theClass::GetMessageMap() const  

                { return &theClass::messageMap; }  

        AFX_MSGMAP theClass::messageMap =  

        { &(baseClass::messageMap);  

                (AFX_MSGMAP_ENTRY*) &(theClass::_messageEntries) };  

        AFX_MSGMAP_ENTRY theClass::_messageEntries'' =  

        { 



#define ON_MAND (id; memberFxn)  

        { WM_MAND; 0; (WORD)id; (WORD)id; AfxSig_vv; (AFX_PMSG)memberFxn }; 



#define END_MESSAGE_MAP ()  

        { 0; 0; 0; 0; AfxSig_end; (AFX_PMSG)0 }  

        }; 



其中的AfxSig_end 定义为: 



enum AfxSig 

{ 

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

        AfxSig_vv;    

}; 



 AfxSig_xx 用来描述消息处理例程memberFxn  的类型(参数与回返值)。本例纯为仿真 



 与简化,所以不在这上面作文章。真正讲到MFC 时(第四篇p580 ),我会再解释它。 



                                                                                             173 


…………………………………………………………Page 236……………………………………………………………

                   第篇  勿在浮砂築高台 



                    于是,以CView 为例,下面的源代码: 



                      // in header file 

                      class CView : public CWnd 

                      { 

                      public: 

                        。。。 

                        DECLARE_MESSAGE_MAP() 

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