八宝书库 > 文学其他电子书 > 深入浅出MFC第2版(PDF格式) >

第43部分

深入浅出MFC第2版(PDF格式)-第43部分

小说: 深入浅出MFC第2版(PDF格式) 字数: 每页4000字

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 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() 

                      }; 



                      // in implementation file 

                      #define CViewid 122 

                       。。。 

                      BEGIN_MESSAGE_MAP(CView; CWnd) 

                        ON_MAND(CViewid; 0) 

                      END_MESSAGE_MAP() 



                    就被展开成为: 



                      // in header file 

                      class CView : public CWnd 

                      { 

                      public: 

                        。。。 

                        static AFX_MSGMAP_ENTRY _messageEntries''; 

                        static AFX_MSGMAP messageMap; 

                        virtual AFX_MSGMAP* GetMessageMap() const; 

                      }; 



                      // in implementation file 

                      AFX_MSGMAP* CView::GetMessageMap() const 

                              { return &CView::messageMap; } 

                      AFX_MSGMAP CView::messageMap = 

                      { &(CWnd::messageMap); 

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

                      AFX_MSGMAP_ENTRY CView::_messageEntries'' = 

                      { 

                        { WM_MAND; 0; (WORD)122; (WORD)122; 1; (AFX_PMSG)0 }; 

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

                      }; 



                    以图表示则为: 



174 


…………………………………………………………Page 237……………………………………………………………

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



                                                       CWnd::messageMap 



                                                         pBaseMessageMap 

                   CView::_messageEntries'' 

                                                              lpEntries 

         WM_MAND;  0;  122;  122;   1;  (AFX_PMSG)0 



                 0; 0; 0; 0; 0; (AFX_PMSG)0             CView::messageMap 



  我们还可以定义各种类似ON_MAND 这样的宏,把各式各样的消息与特定的处 



  理例程关联起来。MFC 里头就有名为ON_ WM_PAINT 、ON_ WM_CREATE、ON_ WM_SIZE。。。 



  等等的宏。 



  我在Frame7 范例程序中为CCmdTarget  的每一衍生类别都产生类似上图的消息映射表: 



// in header files 

class CObject 

{ 

     。。。 // 注意:CObject 并不属于消息流动网的一份子。 

}; 

class CCmdTarget : public CObject 

{ 

。。。 

  DECLARE_MESSAGE_MAP() 

}; 

class CWinThread : public CCmdTarget 

{ 

 。。。 // 注意:CWinThread 并不属于消息流动网的一份子。 

}; 

class CWinApp : public CWinThread 

{ 

。。。 

  DECLARE_MESSAGE_MAP() 

}; 

class CDocument : public CCmdTarget 

{ 

。。。 

  DECLARE_MESSAGE_MAP() 

}; 

class CWnd : public CCmdTarget 

{ 

。。。 

  DECLARE_MESSAGE_MAP() 



                                                                                         175 


…………………………………………………………Page 238……………………………………………………………

                  第篇  勿在浮砂築高台 



                  }; 

                  class CFrameWnd : public CWnd 

                  { 

                  。。。 

                    DECLARE_MESSAGE_MAP() 

                  }; 

                  class CView : public CWnd 

                  { 

                  。。。 

                    DECLARE_MESSAGE_MAP() 

                  }; 

                  class CMyWinApp : public CWinApp 

                  { 

                  。。。 

                    DECLARE_MESSAGE_MAP() 

                  }; 

                  class CMyFrameWnd : public CFrameWnd 

                  { 

                  。。。 

                    DECLARE_MESSAGE_MAP() 

                  }; 

                  class CMyDoc : public CDocument 

                  { 

                  。。。 

                    DECLARE_MESSAGE_MAP() 

                  }; 

                  class CMyView : public CView 

                  { 

                  。。。 

 

返回目录 上一页 下一页 回到顶部 0 0

你可能喜欢的