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

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

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


 { 

        DECLARE_DYNCREATE(CMyView) 

 。。。 

 }; 



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

IMPLEMENT_DYNAMIC(CCmdTarget; CObject) 

IMPLEMENT_DYNAMIC(CWinThread; CCmdTarget) 

IMPLEMENT_DYNAMIC(CWinApp; CWinThread) 

IMPLEMENT_DYNCREATE(CWnd; CCmdTarget) 

IMPLEMENT_DYNCREATE(CFrameWnd; CWnd) 

IMPLEMENT_DYNAMIC(CDocument; CCmdTarget) 

IMPLEMENT_DYNAMIC(CView; CWnd) 

IMPLEMENT_DYNCREATE(CMyFrameWnd; CFrameWnd) 

IMPLEMENT_DYNCREATE(CMyDoc; CDocument) 

IMPLEMENT_DYNCREATE(CMyView; CView) 



于是组织出图3…2 这样一个大网。 



                                                                                 147 


…………………………………………………………Page 210……………………………………………………………

                     第篇  勿在浮砂築高台 



                          CObject::classCObject      CCmdTarget::classCCmdTarget       CWinThread::classCWinThread 



                                “CObject”                     “CCmdTarget”                    “CWinThread” 



                                   4                               4                               4 



                            m_pfnCreateObject  NULL         m_pfnCreateObject  NULL         m_pfnCreateObject  NULL 



                              m_pNextClass                    m_pNextClass                    m_pNextClass 



                      NULL 



                        CFrameWnd::classCFrameWnd          CWnd::classCWnd               CWinApp::classCWinApp 



                              “CFrameWnd”                        “CWnd”                        “CWinApp” 



                                   12                              4                               4 



                            m_pfnCreateObject               m_pfnCreateObject               m_pfnCreateObject  NULL 



                              m_pNextClass                    m_pNextClass                    m_pNextClass 



                          CDocument::classCDocument        CView::classCView 



                              “CDocument”                       “CView”                     (static 变量) 

                                   4                               4                        CRuntimeClass::pFirstClass 



                            m_pfnCreateObject  NULL         m_pfnCreateObject  NULL 



                              m_pNextClass                    m_pNextClass 



                      图3…2 以CRuntimeClass 对象构成的 「类别型录网」。本图只列出与动态 



                             生成 (Dynamic Creation)有关系的成员。凡是m_pfnCreateObject 



                     不为NULL 者,  即可动态生成。 



                     现在,我们开始仿真动态生成。首先在main  函数中加上这一段码: 



                     void main() 

                     { 

                       。。。 

                       //Test Dynamic Creation 

                       CRuntimeClass* pClassRef; 

                       CObject* pOb; 

                       while(1) 

                       { 



148 


…………………………………………………………Page 211……………………………………………………………

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



    if ((pClassRef = CRuntimeClass::Load()) == NULL) 

        break; 



    pOb = pClassRef…》CreateObject(); 

    if (pOb != NULL) 

        pOb…》SayHello(); 

  } 

} 



 并设计 

               CRuntimeClass CreateObj ect  CRuntimeClass  Load 

                       ::             和                ::      如: 



// in implementation file 

CObject* CRuntimeClass::CreateObject() 

{ 

        if (m_pfnCreateObject == NULL) 

        { 

                TRACE1(〃Error: Trying to create object which is not 〃 

                         〃DECLARE_DYNCREATE nor DECLARE_SERIAL: %hs。n〃; 

                          m_lpszClassName); 

                return NULL; 

        } 



        CObject* pObject = NULL; 

        pObject = (*m_pfnCreateObject)(); 



        return pObject; 

} 



CRuntimeClass* PASCAL CRuntimeClass::Load() 

{ 

        char szClassName'64'; 

        CRuntimeClass* pClass; 

        // JJHOU : instead of Load from file; we Load from cin。 

        cout 》 szClassName; 



        for (pClass = pFirstClass; pClass != NULL; pClass = pClass…》m_pNextClass) 

        { 

                if (strcmp(szClassName; pClass…》m_lpszClassName) == 0) 

                        return pClass; 

        } 



        TRACE1(〃Error: Class not found: %s n〃; szClassName); 

        return NULL; // not found 

} 



                                                                                                149 


…………………………………………………………Page 212……………………………………………………………

                  第篇  勿在浮砂築高台 



                  然后,为了验证这样的动态生成机制的确有效(也就是对象的确被产生了),我让许多 



                  个类别的构造式都输出一段文字,而且在取得对象指针后,真的去调用该对象的一个成 



                  员函数SayHello 。我把SayHello 设计为虚拟函数,所以根据不同的对象类型,会调用 



                  到不同的SayHello  函数,出现不同的输出字符串。 



                  请注意,main  函数中的while 循环必须等到CRuntimeClass::Load 传回NULL 才会停 



                  止,而CRuntimeClass::Load  是在它从整个「类别型录网」中找不到它要找的那个类别 



                  名称时,才传回NULL 。这些都是我为了仿真与示范,所采取的权宜设计。 



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



                  定」一节): 



                              cl my。cpp mfc。cpp  



                  下面是Frame6  的执行结果。粗体表示我(程序执行者)在屏幕上输入的类别名称: 



                  enter a class name。。。  CObject 

                  Error: Trying to create object which is not DECLARE_DYNCREATE 

                  or DECLARE_SERIAL: CObject。 



                  enter a class name。。。  CView 

                  Error: Trying to create object which is not DECLARE_DYNCREATE 

                  or DECLARE_SERIAL: CView。 



                  enter a class name。。。  CMyView 

                  CWnd Constructor 

                  CMyView Constructor 

                  Hello CMyView 



                  enter a class name。。。  CMyFrameWnd 

                  CWnd Constructor 

                  CFrameWnd Constructor 

                  CMyFrameWnd Constructor 

                  Hello CMyFrameWnd 



                  enter a class name。。。  CMyDoc 

                  CMyDoc Constructor 

                  Hello CMyDoc 



150 


…………………………………………………………Page 213……………………………………………………………

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



      enter a class name。。。  CWinApp 

      Error: Trying to create object which is not DECLARE_DYNCREATE 

      or DECLARE_SERIAL: CWinApp。 



      enter a class name。。。 CJjhou  (故意输入一个不在「类别型录网」中的类别名称) 



      Error: Class not found: CJjhou  (程序结束) 



Frame6  范例程序 



      MFC。H 



      #0001  #define BOOL int 

      #0002  #define TRUE 1 

      #0003  #define FALSE 0 

      #0004  #define LPCSTR  LPSTR 

      #0005  typedef char*   LPSTR; 

      #0006  #define UINT int 

      #0007  #define PASCAL _stdcall 

      #0008  #define TRACE1 printf 

      #0009 

      #0010  #include  

      #0011  #include  

      #0012  #include  

      #0013 

      #0014  class CObject; 

      #0015 

      #0016  struct CRuntimeClass 

      #0017  { 

      #0018  // Attributes 

      #0019     LPCSTR m_lpszClassName; 

      #0020     int m_nObjectSize; 

      #0021     UINT m_wSchema; // schema number of the loaded class 

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

      #0023     CRuntimeClass* m_pBaseClass; 

      #0024 

      #0025     CObject* CreateObject(); 

      #0026     static CRuntimeClass* PASCAL Load(); 

      #0027 

      #0028     // CRuntimeClass objects linked together in simple list 

      #0029     static CRuntimeClass* pFirstClass; // start of class list 

      #0030     CRuntimeClass* m_pNextClass;    // linked list of registered classes 

      #0031  }; 

      #0032 

      #0033  struct AFX_CLASSINIT 



                                                                                       151 


…………………………………………………………Page 214……………………………………………………………

                    第篇  勿在浮砂築高台 



                    #0034          { AFX_CLASSINIT(CRuntimeClass* pNewClass); }; 

                    #0035 

                    #0036  #define RUNTIME_CLASS(class_name)  

                    #0037          (&class_name::class##class_name) 

                    #0038 

                    #0039  #define DECLARE_DYNAMIC(class_name)  

                    #0040  public:  

                    #0041          static CRuntimeClass class##class_name;  

                    #0042          virtual CRuntimeClass* GetRuntimeClass() const; 

                    #0043 

                    #0044  #define DECLARE_DYNCREATE(class_name)  

                    #0045          DECLARE_DYNAMIC(class_name)  

                    #0046          static CObject* PASCAL CreateObject(); 

                    #0047 

                    #0048  #define _IMPLEMENT_RUNTIMECLASS(class_name; base_class_name; wSchema; pfnNew)  

                    #0049          static char _lpsz##class_name'' = #class_name;  

                    #0050          CRuntimeClass class_name::class##class_name = {  

                    #0051                  _lpsz##class_name; sizeof(class_name); wSchema; pfnNew;  

                    #0052                          RUNTIME_CLASS(base_class_name); NULL };  

                    #0053          static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name);  

                    #0054          CRuntimeClass* class_name::GetRuntimeClass() const  

                    #0055                  { return &class_name::class##class_name; }  

                    #0056 

                    #0057  #define IMPLEMENT_DYNAMIC(class_name; base_class_name)  

                    #0058          _IMPLEMENT_RUNTIMECLASS(class_name; base_class_name; 0xFFFF; NULL) 

                    #0059 

                    #0060  #define IMPLEMENT_DYNCREATE(class_name; base_class_name)  

                    #0061          CObject* PASCAL class_name::CreateObject()  

                    #0062                  { return new class_name; }  

                    #0063          _IMPLEMENT_RUNTIMECLASS(class_name; base_class_name; 0xFFFF;  

                    #0064                  class_name::CreateObject) 

                    #0065 

                    #0066  class CObject 

                    #0067  { 

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