友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
第三电子书 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

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

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


                  。。。 

                  IMPLEMENT_DYNAMIC(CMyDoc; CDocument) //  

                                                          在    程序中这里其实是  

                                                            MFC               IMPLEMENT_DYNCREATE() 

                                                              // 稍后我便会仿真IMPLEMENT_DYNCREATE() 给你看 

                  。。。 

                                                          在     程序中这里其实是  

                  IMPLEMENT_DYNAMIC(CMyView; CView)     //  MFC               IMPLEMENT_DYNCREATE() 

                                                              // 稍后我便会仿真IMPLEMENT_DYNCREATE() 给你看 



                     我不在此列出Frame4  的源代码,你可以在书附光盘片中找到完整的文件。Frame4  的命 



                     令列编译联结动作是(环境变量必须先设定好,请参考第4章的「安装与设定」一节): 



                                 cl my。cpp mfc。cpp  



                     以下即是Frame4  的执行结果: 



                     pMyDoc…》IsKindOf(RUNTIME_CLASS(CMyDoc))         1 

                     pMyDoc…》IsKindOf(RUNTIME_CLASS(CDocument))      1 

                     pMyDoc…》IsKindOf(RUNTIME_CLASS(CCmdTarget))     1 

                     pMyDoc…》IsKindOf(RUNTIME_CLASS(CObject))        1 

                     pMyDoc…》IsKindOf(RUNTIME_CLASS(CWinApp))        0 

                     pMyDoc…》IsKindOf(RUNTIME_CLASS(CView))          0 



                     pMyView…》IsKindOf(RUNTIME_CLASS(CView))         1 

                     pMyView…》IsKindOf(RUNTIME_CLASS(CObject))       1 

                     pMyView…》IsKindOf(RUNTIME_CLASS(CWnd))          1 

                     pMyView…》IsKindOf(RUNTIME_CLASS(CFrameWnd))     0 



                     pMyWnd…》IsKindOf(RUNTIME_CLASS(CFrameWnd))      1 

                     pMyWnd…》IsKindOf(RUNTIME_CLASS(CWnd))           1 

                     pMyWnd…》IsKindOf(RUNTIME_CLASS(CObject))        1 

                     pMyWnd…》IsKindOf(RUNTIME_CLASS(CDocument))      0 



142 


…………………………………………………………Page 205……………………………………………………………

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



Dynamic Creation (动态生成) 



       基础有了,做什么都好。同样地,有了上述的「类别型录网」,各种应用纷至沓来。其 



       中一个应用就是解决棘手的动态生成问题。 



       我已经在第二章描述过动态生成的困难点:你没有办法在程序执行期间,根据动态获得 



       的一个类别名称(通常来自读档,但我将以屏幕输入为例),要求程序产生一个对象。 



       上述的「类别型录网」虽然透露出解决此一问题的些微曙光,但是技术上还得加把劲儿。 



       如果我能够把类别的大小记录在类别型录中,把构造函数(注意,这里并非指C++ 构造 



       式,而是指即将出现的CRuntimeClass::CreateObject)也记录在类别型录中,当程序在执 



       行时期获得一个类别名称,它就可以在「类别型录网」中找出对应的元素,然后调用其 



       构造函数(这里并非指C++ 构造式),产生出对象。 



       好主意! 



       类别型录网的元素型式CRuntimeClass 于是有了变化: 



       // in MFC。H 

       struct CRuntimeClass 

        { 

       // Attributes 

               LPCSTR m_lpszClassName; 

               int m_nObjectSize; 

               UINT m_wSchema; // schema number of the loaded class 

               CObject* (PASCAL* m_pfnCreateObject)(); // NULL =》 abstract class 

               CRuntimeClass* m_pBaseClass; 



               CObject* CreateObject(); 

               static CRuntimeClass* PASCAL Load(); 



               // CRuntimeClass objects linked together in simple list 

               static CRuntimeClass* pFirstClass; // start of class list 

               CRuntimeClass* m_pNextClass;       // linked list of registered classes 

        }; 



                                                                                    143 


…………………………………………………………Page 206……………………………………………………………

          DECLARE_DYNCREATE  /IMPLEMENT_DYNCREATE  宏 



                   为了因应CRuntimeClass 中新增的成员变量, 我们再添两个宏, 



                   DECLARE_DYNCREATE 和IMPLEMENT_DYNCREATE: 



                   #define DECLARE_DYNCREATE(class_name)  

                           DECLARE_DYNAMIC(class_name)  

                           static CObject* PASCAL CreateObject(); 



                   #define IMPLEMENT_DYNCREATE(class_name; base_class_name)  

                           CObject* PASCAL class_name::CreateObject()  

                                   { return new class_name; }  

                           _IMPLEMENT_RUNTIMECLASS(class_name; base_class_name; 0xFFFF;  

                                   class_name::CreateObject) 



                   于是,以CFrameWnd 为例,下列程序代码: 



                   // in header file 

                   class CFrameWnd : public CWnd 

                   { 

                           DECLARE_DYNCREATE(CFrameWnd) 

                       。。。 

                   }; 



                   // in implementation file 

                   IMPLEMENT_DYNCREATE(CFrameWnd; CWnd) 



                   就被展开如下(注意,编译器选项/P 可得前置处理结果): 



                   // in header file 

                   class CFrameWnd : public CWnd 

                   { 

                   public: 

                           static CRuntimeClass classCFrameWnd; 

                           virtual CRuntimeClass* GetRuntimeClass() const; 

                           static CObject* PASCAL CreateObject(); 

                       。。。 

                   }; 



                   // in implementation file 

                   CObject* PASCAL CFrameWnd::CreateObject() 

                           { return new CFrameWnd; } 



144 


…………………………………………………………Page 207……………………………………………………………

 static char _lpszCFrameWnd'' = 〃CFrameWnd〃; 

 CRuntimeClass CFrameWnd::classCFrameWnd = { 

         _lpszCFrameWnd; sizeof(CFrameWnd); 0xFFFF; CFrameWnd::CreateObject; 

                 RUNTIME_CLASS(CWnd); NULL }; 

 static AFX_CLASSINIT _init_CFrameWnd(&CFrameWnd::classCFrameWnd); 

 CRuntimeClass* CFrameWnd::GetRuntimeClass() const 

         { return &CFrameWnd::classCFrameWnd; } 



 图示如下: 



        C O  b j e c t : : c l a s s C  O b j e c t C C  m  d T a r g e t : : c l a s s C  C m  d T a r g e t C W  i n T h r e a d : : c l a s s C  W  i n T h r e a d 



                “ C O  b j e c t ”                        “ C C  m  d T a r g e t ”                   “ C W in T h r e a d ” 



             m  _ p B a s e C la s s                     m  _ p B a s e C la s s                      m  _ p B a s e C la s s 

             m  _ p N e x t C  la s s                     m  _ p N e x t C  la s s                    m  _ p N e x t C  la s s 



                                   N U  L L 

  N U  L L 



     C F r a m  e W  n d : : c l a s s C F r a m  e W  n d C W  n d : : c l a s s C W  n d     C W  i n A p p : : c l a s s C W  i n A p p 



             “ C F r a m  e W  n d ”                          “ C W n d ”                               “ C W in A p p ” 



             m  _ p B a s e C la s s                     m  _ p B a s e C la s s                      m  _ p B a s e C la s s 

             m  _ p N e x t C  la s s                     m  _ p N e x t C  la s s                    m  _ p N e x t C  la s s 



        C D  o c u m  e n t : : c l a s s C D  o c u m  e n t C V i e w  : : c l a s s C  V i e w 



              “ C D  o c u m  e n t ”                        “ C V ie w ” 



                                                                                                   (s t a t i c 变量) 

                                                                                                   C R  u n t i m  e C l a s s : : p F i r s t C l a s s 



             m  _ p B a s e C la s s                     m  _ p B a s e C la s s 

             m  _ p N e x t C  la s s                     m  _ p N e x t C  la s s 



  「对象生成器」CreateObject 函数很简单,只要说new 就好。 



从宏的定义我们很清楚可以看出,拥有动态生成(Dynamic Creation )能力的类别库, 



必然亦拥有执行时期类型识别(RTTI )能力,因为_DYNCREATE 宏涵盖了_DYNAMIC 



宏。 



注意:以下范例直接跳到Frame6 。本书第一版有一个Frame5 程序,用以仿真MFC 2。5 



对动态生成的作法。往事已矣,读者曾经来函表示没有必要提过去的东西,徒增脑力负 



荷。我想也是,况且MFC 4。x  的作法更好更容易了解,所以我把Frame5 拿掉了,但仍 



保留着序号。 



                                                                                                                                                                              145 


…………………………………………………………Page 208……………………………………………………………

                  第篇  勿在浮砂築高台 



                   范例程序Frame6 在。h 档中有这些类别声明: 



                  class CObject 

                   { 

                   。。。 

                   }; 

                  class CCmdTarget : public CObject 

                   { 

                          DECLARE_DYNAMIC(CCmdTarget) 

                   。。。 

                   }; 

                  class CWinThread : public CCmdTarget 

                   { 

                          DECLARE_DYNAMIC(CWinThread) 

                   。。。 

                   }; 

                  class CWinApp : public CWinThread 

                   { 

                          DECLARE_DYNAMIC(CWinApp) 

                   。。。 

                   }; 

                  class CDocument : public CCmdTarget 

                   { 

                          DECLARE_DYNAMIC(CDocument) 

                   。。。 

                   }; 

                  class CWnd : public CCmdTarget 

                   { 

                          DECLARE_DYNCREATE(CWnd) 

                   。。。 

                   }; 

                  class CFrameWnd : public CWnd 

                   { 

                          DECLARE_DYNCREATE(CFrameWnd) 

                   。。。 

                   }; 

                  class CView : public CWnd 

                   { 

                          DECLARE_DYNAMIC(CView) 

                   。。。 

                   }; 

                  class CMyWinApp : public CWinApp 

                   { 

                   。。。 

                   }; 

                  class CMyFrameWnd : public CFrameWnd 



146 


…………………………………………………………Page 209……………………………………………………………

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



 { 

        DECLARE_DYNCREATE(CMyFrameWnd) 

 。。。 

 }; 

class CMyDoc : public CDocument 

 { 

        DECLARE_DYNCREATE(CMyDoc) 

 。。。 

 }; 

class CMyView : public CView 

 { 

        DECLARE_DYNCREATE(CMyView) 

 。。。 

 }; 



在。cpp 档中又有这些动作: 

IMPLEMENT_DYNAMIC(CCmdTarget; CObject) 

IMPLEMENT_DYNAMIC(CWinThread; C
返回目录 上一页 下一页 回到顶部 0 0
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!