Open File& New File之MFC后台代码分析

Open File& New File之MFC后台代码分析

                                    作者:(ECNU)孟庆涛      Email:[email protected]      


       

1CWinApp::OnFileNew

Creating an Empty Document: The CWinApp::OnFileNew Function

开始运行时,CWinApp::ProcessShellCommand会自动调用OnFileNew函数

       After your application class’s InitInstance function calls the AddDocTemplate member function, it calls OnFileNew (indirectly through CWinApp::ProcessShellCommand), another important CWinApp member function. OnFileNew sorts through the web of interconnected class names and does the following:

  1. Constructs the document object but does not attempt to read data from disk.
  2. Constructs the main frame object (of class CMainFrame); it also creates the main frame window but does not show it. The main frame window includes the IDR_MAINFRAME menu, the toolbar, and the status bar.
  3. Constructs the view object; it also creates the view window but doesn’t show it.
  4. Establishes connections among the document, main frame, and view objects. Do not confuse these object connections with the class connections established by the call to AddDocTemplate.
  5. Calls the virtual CDocument::OnNewDocument member function for the document object, which calls the virtual DeleteContents function.
  6. Calls the virtual CView::OnInitialUpdate member function for the view object.
  7. Calls the virtual CFrameWnd::ActivateFrame for the frame object to show the main frame window together with the menus, view window, and control bars.
2OnFileOpen
        

When the MFC Application Wizard generates an application, it maps the File Open menu command to the CWinApp::OnFileOpen member function. When called, this function invokes a sequence of functions to accomplish these steps:

1.     Prompts the user to select a file.

2.     Calls the virtual function CDocument::OnOpenDocument for the already existing document object. This function opens the file, calls CDocument::DeleteContents, and constructs a CArchive object set for loading. It then calls the document’s Serialize function, which loads data from the archive.

3.     Calls the view’s OnInitialUpdate function.

3MFC源代码分析:
注意:表格左边是新建文件过程,右边是打开文件过程,没分左右的则是二者的功用部分。下面都是MFC
后台代码,涉及到序列化问题等。总之,自己品味,其乐无穷。:)

     
       
     

NEW

Open

void CWinApp::OnFileNew()

{

         if (m_pDocManager != NULL)

                   m_pDocManager->OnFileNew();

}

void CWinApp::OnFileOpen()

{

         ASSERT(m_pDocManager != NULL);

         m_pDocManager->OnFileOpen();

}

void CDocManager::OnFileNew()

{

         if (m_templateList.IsEmpty())

         {

         TRACE(traceAppMsg, 0, "Error: no document templates registered with CWinApp./n");      

      AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);

                   return;

         }

         CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();

         if (m_templateList.GetCount() > 1)

         {

         // more than one document template to choose from

         // bring up dialog prompting user

                   CNewTypeDlg dlg(&m_templateList);

                   INT_PTR nID = dlg.DoModal();

                   if (nID == IDOK)

                            pTemplate = dlg.m_pSelectedTemplate;

                   else

                            return;     // none - cancel operation

         }

         ASSERT(pTemplate != NULL);

         ASSERT_KINDOF(CDocTemplate, pTemplate);

         pTemplate->OpenDocumentFile(NULL);

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

}

void CDocManager::OnFileOpen()

{

// prompt the user (with all document templates)

         CString newName;

         if (!DoPromptFileName(newName, AFX_IDS_OPENFILE,

           OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))

                   return; // open cancelled

      AfxGetApp()->OpenDocumentFile(newName);

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

}

 

 

CDocument* CWinApp::OpenDocumentFile(LPCTSTR lpszFileName)

{

         ASSERT(m_pDocManager != NULL);

         return   m_pDocManager->OpenDocumentFile(lpszFileName);

}

 

 

 

 

 

 

 

 

 

 

 

 

CDocument* CDocManager::OpenDocumentFile(LPCTSTR lpszFileName)

{

         // find the highest confidence

         POSITION pos = m_templateList.GetHeadPosition();

         CDocTemplate::Confidence bestMatch = CDocTemplate::noAttempt;

         CDocTemplate* pBestTemplate = NULL;

         CDocument* pOpenDocument = NULL;

         TCHAR szPath[_MAX_PATH];

         ASSERT(lstrlen(lpszFileName) < _countof(szPath));

         TCHAR szTemp[_MAX_PATH];

         if (lpszFileName[0] == '/"')

                   ++lpszFileName;

         lstrcpyn(szTemp, lpszFileName, _MAX_PATH);

         LPTSTR lpszLast = _tcsrchr(szTemp, '/"');

         if (lpszLast != NULL)

                   *lpszLast = 0;        

         if( AfxFullPath(szPath, szTemp) == FALSE )

         {

                   ASSERT(FALSE);

                   return NULL; // We won't open the file. MFC requires paths with

                                // length < _MAX_PATH

         }

         TCHAR szLinkName[_MAX_PATH];

         if (AfxResolveShortcut(AfxGetMainWnd(), szPath, szLinkName, _MAX_PATH))

                   lstrcpy(szPath, szLinkName);

         while (pos != NULL)

         {

               CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(pos);

                   ASSERT_KINDOF(CDocTemplate, pTemplate);

                   CDocTemplate::Confidence match;

                   ASSERT(pOpenDocument == NULL);

                   match = pTemplate->MatchDocType(szPath, pOpenDocument);

                   if (match > bestMatch)

                   {

                            bestMatch = match;

                            pBestTemplate = pTemplate;

                   }

                   if (match == CDocTemplate::yesAlreadyOpen)

                            break;      // stop here

         }

         if (pOpenDocument != NULL)

         {

                   POSITION pos = pOpenDocument->GetFirstViewPosition();

                   if (pos != NULL)

                   {

         CView* pView = pOpenDocument->GetNextView(pos); // get first one

                            ASSERT_VALID(pView);

                            CFrameWnd* pFrame = pView->GetParentFrame()

                            if (pFrame == NULL)

                                     TRACE(traceAppMsg, 0, "Error: Can not find a frame for document to activate./n");

                            else

                            {pFrame->ActivateFrame();

                                     if (pFrame->GetParent() != NULL)

                                     {

                                               CFrameWnd* pAppFrame;

                                               if (pFrame != (pAppFrame = (CFrameWnd*)AfxGetApp()->m_pMainWnd))

                                               {

                                                        ASSERT_KINDOF(CFrameWnd, pAppFrame);

                                                        pAppFrame->ActivateFrame();

                                               }

                                     }

                            }

                   }

                   else

                            TRACE(traceAppMsg, 0, "Error: Can not find a view for document to activate./n");

                   return pOpenDocument;

         }

         if (pBestTemplate == NULL)

         {

                   AfxMessageBox(AFX_IDP_FAILED_TO_OPEN_DOC);

                   return NULL;

         }

         return pBestTemplate->OpenDocumentFile(szPath);

}

 

: 单文档模板

CDocument* CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,BOOL bMakeVisible)

// if lpszPathName == NULL => create new file of this type

{

CDocument* pDocument = NULL;

CFrameWnd* pFrame = NULL;

BOOL bCreated = FALSE;      // => doc and frame created

BOOL bWasModified = FALSE;

 

if (m_pOnlyDoc != NULL)

{

// already have a document - reinit it

pDocument = m_pOnlyDoc;

if (!pDocument->SaveModified())

return NULL;        // leave the original one

 

pFrame = (CFrameWnd*)AfxGetMainWnd();

ASSERT(pFrame != NULL);

ASSERT_KINDOF(CFrameWnd, pFrame);

ASSERT_VALID(pFrame);

}

else

{

// create a new document

pDocument = CreateNewDocument();    //建立一个新的文档对象

ASSERT(pFrame == NULL);     // will be created below

bCreated = TRUE;

}

if (pDocument == NULL)

{

AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);

return NULL;

}

ASSERT(pDocument == m_pOnlyDoc);

 

if (pFrame == NULL)

{

ASSERT(bCreated);

 

// create frame - set as main document frame

BOOL bAutoDelete = pDocument->m_bAutoDelete;

pDocument->m_bAutoDelete = FALSE;

// don't destroy if something goes wrong

pFrame = CreateNewFrame(pDocument, NULL);     //在这里建立框架和视图,实现三位一体

pDocument->m_bAutoDelete = bAutoDelete;

if (pFrame == NULL)

{

AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);

delete pDocument;       // explicit delete on error

return NULL;

}

}

if (lpszPathName == NULL)       //  File/NEW而言

{

// create a new document

SetDefaultTitle(pDocument);

 

// avoid creating temporary compound file when starting up invisible

if (!bMakeVisible)

pDocument->m_bEmbedded = TRUE;

 

if (!pDocument->OnNewDocument())//调用前面建立的文档对象的函数,建立新文档

{

// user has been alerted to what failed in OnNewDocument

TRACE(traceAppMsg, 0, "CDocument::OnNewDocument returned FALSE./n");

if (bCreated)

pFrame->DestroyWindow();    // will destroy document

return NULL;

}

}

else                    //File/Open而言

{

CWaitCursor wait;

// open an existing document

bWasModified = pDocument->IsModified();

pDocument->SetModifiedFlag(FALSE);  // not dirty for open

if (!pDocument->OnOpenDocument(lpszPathName))

{

// user has been alerted to what failed in OnOpenDocument

TRACE(traceAppMsg, 0, "CDocument::OnOpenDocument returned FALSE./n");

if (bCreated)

{

pFrame->DestroyWindow();    // will destroy document

}

else if (!pDocument->IsModified())

{

// original document is untouched

   pDocument->SetModifiedFlag(bWasModified);

}

else

{

// we corrupted the original document

SetDefaultTitle(pDocument);

if (!pDocument->OnNewDocument())

{

TRACE(traceAppMsg, 0, "Error: OnNewDocument failed after trying "

"to open a document - trying to continue./n");

// assume we can continue

}

}

return NULL;        // open failed

}

 pDocument->SetPathName(lpszPathName);

}

 

CWinThread* pThread = AfxGetThread();

ASSERT(pThread);

if (bCreated && pThread->m_pMainWnd == NULL)

{

// set as main frame (InitialUpdateFrame will show the window)

pThread->m_pMainWnd = pFrame;

   }

InitialUpdateFrame(pFrame, pDocument, bMakeVisible);

return pDocument;

}

: 多文档模板:

CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,

         BOOL bMakeVisible)

{

         CDocument* pDocument = CreateNewDocument();

         if (pDocument == NULL)

         {

                   TRACE(traceAppMsg, 0, "CDocTemplate::CreateNewDocument returned NULL./n");

                   AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);

                   return NULL;

         }

         ASSERT_VALID(pDocument);

 

         BOOL bAutoDelete = pDocument->m_bAutoDelete;

         pDocument->m_bAutoDelete = FALSE;   // don't destroy if something goes wrong

         CFrameWnd* pFrame = CreateNewFrame(pDocument, NULL);

         pDocument->m_bAutoDelete = bAutoDelete;

         if (pFrame == NULL)

         {

                   AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);

                   delete pDocument;       // explicit delete on error

                   return NULL;

         }

         ASSERT_VALID(pFrame);

 

         if (lpszPathName == NULL)   //建立一个新的文档

         {

                   // create a new document - with default document name

                   SetDefaultTitle(pDocument);

 

                   // avoid creating temporary compound file when starting up invisible

                   if (!bMakeVisible)

                            pDocument->m_bEmbedded = TRUE;

 

                   if (!pDocument->OnNewDocument())

                   {

                            // user has be alerted to what failed in OnNewDocument

                            TRACE(traceAppMsg, 0, "CDocument::OnNewDocument returned FALSE./n");

                            pFrame->DestroyWindow();

                            return NULL;

                   }

 

                   // it worked, now bump untitled count

                   m_nUntitledCount++;

         }

         else

         {                                       //打开一个现有的文档

                   // open an existing document

                   CWaitCursor wait;

                   if (!pDocument->OnOpenDocument(lpszPathName))

                   {

                            // user has be alerted to what failed in OnOpenDocument

                            TRACE(traceAppMsg, 0, "CDocument::OnOpenDocument returned FALSE./n");

                            pFrame->DestroyWindow();

                            return NULL;

                   }

                   pDocument->SetPathName(lpszPathName);

         }

 

         InitialUpdateFrame(pFrame, pDocument, bMakeVisible);

         return pDocument;

}

 

 

BOOL CDocument::OnNewDocument()

{

#ifdef _DEBUG

         if(IsModified())

                   TRACE(traceAppMsg, 0, "Warning: OnNewDocument replaces an unsaved document./n");

#endif

 

         DeleteContents();

         m_strPathName.Empty();      // no path name yet

         SetModifiedFlag(FALSE);     // make clean

         return TRUE;

}

 

BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName)

{

#ifdef _DEBUG

         if (IsModified())

                   TRACE(traceAppMsg, 0, "Warning: OnOpenDocument replaces an unsaved document./n");

#endif

         CFileException fe;

         CFile* pFile = GetFile(lpszPathName,

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

         if (pFile == NULL)

         {

                   ReportSaveLoadException(lpszPathName, &fe,

                            FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);

                   return FALSE;

         }

         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();

                   ReleaseFile(pFile, FALSE);

         }

         CATCH_ALL(e)

         {

                   ReleaseFile(pFile, TRUE);

                   DeleteContents();   // remove failed contents

                   TRY

                   {

                            ReportSaveLoadException(lpszPathName, e,

                                     FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);

                   }

                   END_TRY

                   DELETE_EXCEPTION(e);

                   return FALSE;

         }

         END_CATCH_ALL

         SetModifiedFlag(FALSE);     // start off with unmodified

         return TRUE;

}

 

 

CFrameWnd* CDocTemplate::CreateNewFrame(CDocument* pDoc, CFrameWnd* pOther)

{

      if (pDoc != NULL)

           ASSERT_VALID(pDoc);

      // create a frame wired to the specified document

 

      ASSERT(m_nIDResource != 0); // must have a resource ID to load from

      CCreateContext context;

      context.m_pCurrentFrame = pOther;

      context.m_pCurrentDoc = pDoc;

      context.m_pNewViewClass = m_pViewClass;

      context.m_pNewDocTemplate = this;

 

      if (m_pFrameClass == NULL)

      {

           TRACE(traceAppMsg, 0, "Error: you must override CDocTemplate::CreateNewFrame./n");

           ASSERT(FALSE);

           return NULL;

      }

      CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();   //动态创建

      if (pFrame == NULL)

      {

           TRACE(traceAppMsg, 0, "Warning: Dynamic create of frame %hs failed./n",m_pFrameClass->m_lpszClassName);

           return NULL;

      }

      ASSERT_KINDOF(CFrameWnd, pFrame);

 

      if (context.m_pNewViewClass == NULL)

           TRACE(traceAppMsg, 0, "Warning: creating frame with no default view./n");

 

      // create new from resource

      if (!pFrame->LoadFrame(m_nIDResource,             WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,   // default frame stylesNULL, &context)) 

      {

           TRACE(traceAppMsg, 0, "Warning: CDocTemplate couldn't create a frame./n");

           // frame will be deleted in PostNcDestroy cleanup

           return NULL;

      }

 

      // it worked !

      return pFrame;

}

CDocument* CDocTemplate::CreateNewDocument()

{

      // default implementation constructs one from CRuntimeClass

      if (m_pDocClass == NULL)

      {

     TRACE(traceAppMsg, 0, "Error: you must override CDocTemplate::CreateNewDocument./n");

           ASSERT(FALSE);

           return NULL;

      }

 CDocument* pDocument = (CDocument*)m_pDocClass->CreateObject();

//动态创建(在运行的时候创建);

      if (pDocument == NULL)

      {

      TRACE(traceAppMsg, 0, "Warning: Dynamic create of document type %hs failed./n",m_pDocClass->m_lpszClassName);

           return NULL;

      }

      ASSERT_KINDOF(CDocument, pDocument);

      AddDocument(pDocument);

      return pDocument;

}

 

BOOL CWinApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo)

{

     BOOL bResult = TRUE;

     switch (rCmdInfo.m_nShellCommand)

     {

     case CCommandLineInfo::FileNew:

         if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL))

              OnFileNew();

         if (m_pMainWnd == NULL)

              bResult = FALSE;

         break;

 

         // If we've been asked to open a file, call OpenDocumentFile()

 

     case CCommandLineInfo::FileOpen:

         if (!OpenDocumentFile(rCmdInfo.m_strFileName))

              bResult = FALSE;

         break;

 

         // If the user wanted to print, hide our main window and

         // fire a message to ourselves to start the printing

 

     case CCommandLineInfo::FilePrintTo:

     case CCommandLineInfo::FilePrint:

         m_nCmdShow = SW_HIDE;

         ASSERT(m_pCmdInfo == NULL);

         if(OpenDocumentFile(rCmdInfo.m_strFileName))

         {

              m_pCmdInfo = &rCmdInfo;

              m_pMainWnd->SendMessage(WM_COMMAND, ID_FILE_PRINT_DIRECT);

              m_pCmdInfo = NULL;

         }

         bResult = FALSE;

         break;

 

         // If we're doing DDE, hide ourselves

 

     case CCommandLineInfo::FileDDE:

         m_pCmdInfo = (CCommandLineInfo*)(UINT_PTR)m_nCmdShow;

         m_nCmdShow = SW_HIDE;

         break;

 

     // If we've been asked to register, exit without showing UI.

     // Registration was already done in InitInstance().

     case CCommandLineInfo::AppRegister:

         {

              BOOL bRegistered = Register();

              bResult = FALSE;

              if (!rCmdInfo.m_bRunEmbedded)

              {

                   bRegistered;

//                 if (bRegistered)

//                     AfxMessageBox(AFX_IDP_REG_DONE);

//                 else

//                     AfxMessageBox(AFX_IDP_REG_FAILURE);

              }

              bResult = FALSE;    // that's all we do

 

              // If nobody is using it already, we can use it.

              // We'll flag that we're unregistering and not save our state

              // on the way out. This new object gets deleted by the

              // app object destructor.

 

              if (m_pCmdInfo == NULL)

              {

                   m_pCmdInfo = new CCommandLineInfo;

                   m_pCmdInfo->m_nShellCommand = CCommandLineInfo::AppUnregister;

              }

              break;

         }

 

     // If we've been asked to unregister, unregister and then terminate

     case CCommandLineInfo::AppUnregister:

         {

              BOOL bUnregistered = Unregister();

 

              // if you specify /EMBEDDED, we won't make an success/failure box

              // this use of /EMBEDDED is not related to OLE

 

              if (!rCmdInfo.m_bRunEmbedded)

              {

                   if (bUnregistered)

                       AfxMessageBox(AFX_IDP_UNREG_DONE);

                   else

                       AfxMessageBox(AFX_IDP_UNREG_FAILURE);

              }

              bResult = FALSE;    // that's all we do

 

              // If nobody is using it already, we can use it.

              // We'll flag that we're unregistering and not save our state

              // on the way out. This new object gets deleted by the

              // app object destructor.

 

              if (m_pCmdInfo == NULL)

              {

                   m_pCmdInfo = new CCommandLineInfo;

                   m_pCmdInfo->m_nShellCommand = CCommandLineInfo::AppUnregister;

              }

         }

         break;

     }

     return bResult;

}

 

 

4:File/Save &File/Save As

     When the MFC Application Wizard generates an application, it maps the File Save menu command to the OnFileSave member function of the CDocument class. OnFileSave calls the CDocument function OnSaveDocument, which in turn calls your document’s Serialize function with an archive object set for storing. The File Save As menu command is handled in a similar manner: It is mapped to the CDocument function OnFileSaveAs, which calls OnSaveDocument. Here the application framework does all the file management necessary to save a document on disk.

Save

Save As

void CDocument::OnFileSave()

{

         DoFileSave();

}

void CDocument::OnFileSaveAs()

{

         if(!DoSave(NULL))

                   TRACE(traceAppMsg, 0, "Warning: File save-as failed./n");

}

BOOL CDocument::DoFileSave()

{

         DWORD dwAttrib = GetFileAttributes(m_strPathName);

         if (dwAttrib & FILE_ATTRIBUTE_READONLY)

         {

                   // we do not have read-write access or the file does not (now) exist

                   if (!DoSave(NULL))

                   {

         TRACE(traceAppMsg, 0, "Warning: File save with new name failed./n");

                            return FALSE;

                   }

         }

         else

         {

                   if (!DoSave(m_strPathName))

                   {

                            TRACE(traceAppMsg, 0, "Warning: File save failed./n");

                            return FALSE;

                   }

         }

      return TRUE;}

 

 

 

 

 

BOOL CDocument::DoSave(LPCTSTR lpszPathName, BOOL bReplace)

         // Save the document data to a file

         // lpszPathName = path name where to save document file

         // if lpszPathName is NULL then the user will be prompted (SaveAs)

         // note: lpszPathName can be different than 'm_strPathName'

         // if 'bReplace' is TRUE will change file name if successful (SaveAs)

         // if 'bReplace' is FALSE will not change path name (SaveCopyAs)

{

         CString newName = lpszPathName;

         if (newName.IsEmpty())

         {

                   CDocTemplate* pTemplate = GetDocTemplate();

                   ASSERT(pTemplate != NULL);

 

                   newName = m_strPathName;

                   if (bReplace && newName.IsEmpty())

                   {

                            newName = m_strTitle;

                            // check for dubious filename

                            int iBad = newName.FindOneOf(_T(":///"));

                            if (iBad != -1)

                                     newName.ReleaseBuffer(iBad);

 

                            // append the default suffix if there is one

                            CString strExt;

                            if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) &&

                              !strExt.IsEmpty())

                            {

                                     ASSERT(strExt[0] == '.');

                                     int iStart = 0;

                                     newName += strExt.Tokenize(_T(";"), iStart);

                            }

                   }

                   if (!AfxGetApp()->DoPromptFileName(newName,

                     bReplace ? AFX_IDS_SAVEFILE : AFX_IDS_SAVEFILECOPY,

                     OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, FALSE, pTemplate))

                            return FALSE;       // don't even attempt to save

         }

         CWaitCursor wait;

         if (!OnSaveDocument(newName))

         {

                   if (lpszPathName == NULL)

                   {

                            // be sure to delete the file

                            TRY

                            {

                                     CFile::Remove(newName);

                            }

                            CATCH_ALL(e)

                            {

                                     TRACE(traceAppMsg, 0, "Warning: failed to delete file after failed SaveAs./n");

                                     DELETE_EXCEPTION(e);

                            }

                            END_CATCH_ALL

                   }

                   return FALSE;

         }

         // reset the title and change the document name

         if (bReplace)

                   SetPathName(newName);

         return TRUE;        // success

}

BOOL CDocument::OnSaveDocument(LPCTSTR lpszPathName)

{

         CFileException fe;

         CFile* pFile = NULL;

         pFile = GetFile(lpszPathName, CFile::modeCreate |

                   CFile::modeReadWrite | CFile::shareExclusive, &fe);

         if (pFile == NULL)

         {

                   ReportSaveLoadException(lpszPathName, &fe,

                            TRUE, AFX_IDP_INVALID_FILENAME);

                   return FALSE;

         }

         CArchive saveArchive(pFile, CArchive::store | CArchive::bNoFlushOnDelete);

         saveArchive.m_pDocument = this;

         saveArchive.m_bForceFlat = FALSE;

         TRY

         {

                   CWaitCursor wait;

                   Serialize(saveArchive);     // save me

                   saveArchive.Close();

                   ReleaseFile(pFile, FALSE);

         }

         CATCH_ALL(e)

         {

                   ReleaseFile(pFile, TRUE);

                   TRY

                   {

                            ReportSaveLoadException(lpszPathName, e,

                                     TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);

                   }

                   END_TRY

                   DELETE_EXCEPTION(e);

                   return FALSE;

         }

         END_CATCH_ALL

         SetModifiedFlag(FALSE);     // back to unmodified

         return TRUE;        // success

}

 

 

你可能感兴趣的:(Open File& New File之MFC后台代码分析)