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

第37部分

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

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

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






                       IsKindOf  的参数其实就是&CWinApp::classCWinApp 。函数内利用GetRuntimeClass 



                       先取得&CView::classCView,然后循线而上(从图3…1 来看,所谓循线分别是指 



                       CView、CWnd、CCmdTarget、CObject),每获得一个CRuntimeClass 对象指针,就 



                       拿来和CView::classCView  的指针比对。靠这个土方法,完成了IsKindOf  能力。 



140 


…………………………………………………………Page 203……………………………………………………………

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



   2。  IsKindOf   的使用方式如: 



       CMyDoc* pMyDoc = new CMyDoc; 

       CMyView* pMyView = new CMyView; 



       cout IsKindOf(RUNTIME_CLASS(CMyDoc));      // 應該獲得 TRUE 

       cout IsKindOf(RUNTIME_CLASS(CDocument));   // 應該獲得 TRUE 

       cout IsKindOf(RUNTIME_CLASS(CCmdTarget));  // 應該獲得 TRUE 

       cout IsKindOf(RUNTIME_CLASS(CObject));     // 應該獲得 TRUE 

       cout IsKindOf(RUNTIME_CLASS(CWinApp));     // 應該獲得 FALSE 

       cout IsKindOf(RUNTIME_CLASS(CView));       // 應該獲得 FALSE 



       cout IsKindOf(RUNTIME_CLASS(CView));      // 應該獲得 TRUE 

       cout IsKindOf(RUNTIME_CLASS(CObject));    // 應該獲得 TRUE 

       cout IsKindOf(RUNTIME_CLASS(CWnd));       // 應該獲得 TRUE 

       cout IsKindOf(RUNTIME_CLASS(CFrameWnd)); // 应该获得FALSE 



      IsKindOf  的完整范例放在Frame4  中。 



Frame4  范例程序 



      Frame4 与Frame3 大同小异,唯一不同的就是前面所说的,在CObject 中加上IsKindOf  函 



      数的声明与定义,并将私有类别(non…MFC 类别)也挂到「类别型录网」中: 



      // in header file 



      class CMyFrameWnd : public CFrameWnd 



       { 



      DECLARE_DYNAMIC(CMyFrameWnd) // 在MFC 程序中这里其实是DECLARE_DYNCREATE() 



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



       }; 



      class CMyDoc : public CDocument 



       { 



      DECLARE_DYNAMIC(CMyDoc) // 在MFC 程序中这里其实是DECLARE_DYNCREATE() 



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



       }; 



      class CMyView : public CView 



       { 



      DECLARE_DYNAMIC(CMyView) // 在MFC 程序中这里其实是DECLARE_DYNCREATE() 



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



       }; 



                                                                                  141 


…………………………………………………………Page 204……………………………………………………………

                  第篇  勿在浮砂築高台 



                  // in implementation file 

                  。。。 

                                                               在    程序中这里其实是  

                   IMPLEMENT_DYNAMIC(CMyFrameWnd; CFrameWnd) //  MFC               IMPLEMENT_DYNCREATE () 

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

                  。。。 

                  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 :

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

你可能喜欢的