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

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

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





                也! 



                第3章已经提出动态生成的观念以及实作方式了。主要关键还在于一个「类别型录网」。 



                这个型录网就是CRuntimeClass 组成的一个串行。每一个想要享有动态生成机能的类别, 



                都应该在「类别型录网」上登记有案,登记资料包括对象的构造函数的指针。也就是说, 



                上述那种极不优雅的比对动作,被MFC 巧妙地埋起来了;应用程序可以风姿优雅地, 



514 


…………………………………………………………Page 577……………………………………………………………

                                               第8章    Document…View  深入探討 



单单使用DECLARE_SERIAL 和IMPLEMENT_SERIAL 两个宏,就获得文件读写以及 



动态生成两种机制。 



我将仿效前面对于写档动作的探索,看看读文件的程序如何。 



     【          】 

      File/Open 

                      CScribbleApp 的Message Map 中指定由CWinApp::OnFileOpen() 

                      拦截【File/Open】命令消息 



      BEGIN_MESSAGE_MAP(CScribbleApp; CWinApp) 

      BEGIN_MESSAGE_MAP(CScribbleApp; CWinApp) 

         ON_MAND(ID_APP_ABOUT; OnAppAbout) 

          ON_MAND(ID_APP_ABOUT; OnAppAbout) 

         ON_MAND(ID_FILE_NEW; CWinApp::OnFileNew) 

          ON_MAND(ID_FILE_NEW; CWinApp::OnFileNew) 

         ON_MAND(ID_FILE_OPEN; CWinApp::OnFileOpen) 

          ON_MAND(ID_FILE_OPEN; CWinApp::OnFileOpen) 

         ON_MAND(ID_FILE_PRINT_SETUP; CWinApp::OnFilePrintSetup) 

          ON_MAND(ID_FILE_PRINT_SETUP; CWinApp::OnFilePrintSetup) 

      END_MESSAGE_MAP() 

      END_MESSAGE_MAP() 



                                      void CWinApp::OnFileOpen() 

                                      { 

   m_pDocManager 是个CDocManager            ASSERT(m_pDocManager != NULL); 



   对象,后者是一个未公开的MFC 4。0                    m_pDocManager…》OnFileOpen(); 

   新类别,用来维护一长串的Document               } 



   Template。 



   void CDocManager::OnFileOpen() 

    void CDocManager::OnFileOpen() 

   { 

    { 

       // prompt the user (with all document templates) 

        // prompt the user (with all document templates) 

       CString newName; 

        CString newName; 

       if (!DoPromptFileName (newName; AFX_IDS_OPENFILE; 

        if (!DoPromptFileName (newName; AFX_IDS_OPENFILE; 

         OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; TRUE; NULL)) 

          OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; TRUE; NULL)) 

               return; // open cancelled 

                return; // open cancelled 



       AfxGetApp()…》OpenDocumentFile(newName); 

        AfxGetApp()…》OpenDocumentFile(newName); 

               // if returns NULL; the user has already been alerted 

                // if returns NULL; the user has already been alerted 

   } 

    } 



         下页 



                                                                               515 


…………………………………………………………Page 578……………………………………………………………

                第篇    深入  MFC  程式設計 



                 CDocument* CWinApp::OpenDocumentFile(LPCTSTR lpszFileName) 

                  CDocument* CWinApp::OpenDocumentFile(LPCTSTR lpszFileName) 

                  { 

                  { 

                     ASSERT(m_pDocManager != NULL); 

                      ASSERT(m_pDocManager != NULL); 

                     return m_pDocManager…》OpenDocumentFile (lpszFileName); 

                      return m_pDocManager…》OpenDocumentFile (lpszFileName); 

                  } 

                  } 

                                               很多原先在CWinApp 中做掉的有关于Document 



                                               Template 的工作,如AddDocTemplate、 



                                               OpenDocumentFile 和NewDocumentFile,自从 



                                               MFC 4。0 之后已隔离出来由CDocManager 负责。 



                 CDocument* CDocManager::OpenDocumentFile(LPCTSTR lpszFileName) 

                  { 

                     // find the highest confidence 

                     CDocTemplate* pBestTemplate = NULL; 

                     CDocument* pOpenDocument = NULL; 

                     TCHAR szPath'_MAX_PATH'; 

                     。。。 //从「Document Template 串行」中找出最适当之template, 

                     。。。 //放到pBestTemplate 中。 

                     return pBestTemplate…》OpenDocumentFile (szPath); 

                  } 



                                由于CMultiDocTemplate改写了OpenDocumentFile;所以调用 

                                的是CMultiDocTemplate::OpenDocumentFile。 



                         下页 



516 


…………………………………………………………Page 579……………………………………………………………

                                                第8章    Document…View  深入探討 



CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName; 

            BOOL bMakeVisible) 

{ 

    CDocument* pDocument = CreateNewDocument(); 

    。。。 

    CFrameWnd* pFrame = CreateNewFrame(pDocument; NULL); 

    。。。 

                                     由于CScribbleDoc 改写了OnOpenDocument, 



    if (lpszPathName == NULL)        所以调用的是CScribbleDoc::OnOpenDocument 

    { 

        // create a new document with default document name 

        。。。 

    } 

    else 

    { 

        // open an existing document 

        CWaitCursor wait; 

        if (!pDocument…》OnOpenDocument (lpszPathName)) 

        {                        源代码请见本章前部之“CDocTemplate管理 

            。。。 

                                 CDocument/CView/CFrameWnd” 一节. 

        } 

        pDocument…》SetPathName(lpszPathName); 

               BOOL CScribbleDoc::OnOpenDocument(LPCTSTR lpszPathName) 

    }          {BOOL CScribbleDoc::OnOpenDocument(LPCTSTR lpszPathName) 

                { 

                   if (!CDocument::OnOpenDocument (lpszPathName)) 

                    if (!CDocument::OnOpenDocument (lpszPathName)) 

                           return FALSE; 

                            return FALSE; 

                   InitDocument(); 

                    InitDocument(); 

                   return TRUE; 

                    return TRUE; 

               } 

                } 



    InitialUpdateFrame(pFrame; pDocument; bMakeVisible); 

    return pDocument; 

} 



                                                             下页 



                                                                                 517 


…………………………………………………………Page 580……………………………………………………………

                   第篇    深入  MFC  程式設計 



                    BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName) 

                    { 

                        CFileException fe; 

                        CFile* pFile = GetFile(lpszPathName; 

                                CFile::modeRead|CFile::shareDenyWrite; &fe); 



                        DeleteContents(); 

                        SetModifiedFlag();  // dirty during de…serialize 



                        CArchive loadArchive (pFile; CArchive::load | 

                                             CArchive::bNoFlushOnDelete); 

                        loadArchive。m_pDocument = this; 

                        loadArchive。m_bForceFlat = FALSE; 

                        TRY 

                        { 

                            CWaitCursor wait; 

                            if (pFile…》GetLength() != 0) 

                                Serialize(loadArchive);     // load me 

                            loadArchive。Close();                由于                     Serialize 

                                                                     CScribbleDoc 改写了  

                            ReleaseFile(pFile; FALSE);          所以调用的是CScribbleDoc::Serialize 

                        } 

                        。。。                 void CScribbleDoc::Serialize(CArchive& ar) 

                    }                        void CScribbleDoc::Serialize(CArchive& ar) 

                                             { 

                                              { 

                                                。。。 

                                                 。。。 

                                                m_strokeList。Serialize (ar); 

                                                 m_strokeList。Serialize (ar); 

                                             } 

                                              } 



                     void CObList::Serialize(CArchive& ar) 

                     { 

                         CObject::Serialize(ar); 

                         if (ar。IsStoring()) 

                         { 

                             。。。 

                         } 

                         else                          本例读入 0004 

                         { 

                             DWORD nNewCount = ar。ReadCount(); 

                             CObject* newData; 

                             while (nNewCount……) 

                             { 

                         for 

                                 ar 》》 newData; 

                        loop 

                                 AddTail(newData);            operator》》 被多载( overloading )化 

                             } 

                         } 

                               _AFX_INLINE CArchive& AFXAPI operator》》 (CArchive& ar;  

                     } 

                                                                       CObject*& pOb) 

                                       { pOb = ar。ReadObject (NULL); return ar; } 



                                                               调用 CArchive::ReadObject 

                                               下页 

                     



518 


…………………………………………………………Page 581……………………………………………………………

                                                                                             第8章    Document…View  深入探討 



                                     CObject* CArchive::ReadObject(const CRuntimeClass* 

                                     pClassRefRequested) 

                                     { 

                                         。。。 

                                         // attempt to load next stream as CRuntimeClass 

                                         UINT nSchema; 

                                         DWORD obTag; 

                                         CRuntimeClass* pClassRef = ReadClass (pClassRefRequested; 

                                                                              &nSchema; &obTag); 



                                         // check to see if tag to already loaded object 

                                                                                                                A 

                                    C    CObject* pOb; 

                                         if (pClassRef == NULL) 

                                         {  。。。  } 

                                         else 

                                         { 

                                             // allocate a new object based on the class just acquired 

                                                                                           IMPLEMENT_SERIAL(CStroke;。。。) 

                                             pOb = pClassRef…》CreateObject(); 

                                                                                            曾展开出一个函数如下,此即动态生 



                                                                                            成的奥秘: 

                                             // Add to mapping array BEFORE de…serializing 

                                             CheckCount(); 

                                                                         CObject* PASCAL CStroke::CreateObject() 

                                             m_pLoadArray…》InsertAt(m_nMapCount++; pOb); 

                                                                          CObject* PASCAL CStroke::CreateObject() 

                                                                          { 

                                                                           { 

                                                                           return new CStroke; 

                                                                            return new CStroke; 

                                                                          } 

                                             // Serialize the object with schema no。 set in the archive 

                                                                           } 

                                             UINT nSchemaSave = m_nObjectSchema; 

                                             m_nObjectSchema = nSchema; 

                                             pOb…》Serialize(*this); 

                                             m_nObjectSchema = nSchemaSave; 

                                         }                                        调用 CStroke::Serialize 



                                         return pOb;                         D 

                                     } 



                                      CRuntimeClass* CArchive::ReadClass(const CRuntimeClass* pClassRefRequested; 

                                   A         UINT* pSchema; DWORD* pObTag) 

                                      { 

                                                                      FFFF 

                                          WORD wTag;        本例读入 

                                          *this 》》 wTag; 

                                          。。。 

                                          CRuntimeClass* pClassRef; 

                                          UINT nSchema; 

                                          if (wTag == wNewClassTag) 

                                          { 

                                              // new object follows a new class id 

                                              if ((                                      (*this; &nSchema)) == NULL) 

                                                     pClassRef = CRuntimeClass::Load 

                                                  。。。 

                                          } 

                                          else 

                                          {                                               B 

                                              DWORD nClassIndex; 

                                              //判断nCLassIndex 为旧类别,于是从类别型录网中取出 

                                              // 其CRuntimeClass,放在pClassRef  

                                                                                    中。 

                                     C 

                                              。。。 

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