OnFileNew()/OnFileOpen()的MFC代码跟踪简析

来源:互联网 发布:声雨竹羽绒服淘宝 编辑:程序博客网 时间:2024/05/03 04:43

对OnFileNew()/OnFileOpen()的MFC代码跟踪简析,简析可能也谈不上了,为了快速的理解MFC的实现思路以及文档视图架构的应用,在学习的过程当中我也没有进行学习理解的注解。不过细细阅读整个的实现流程,相信你我都能理解掌握MFC的整体思路。以后有机会再进行注解吧。
A) OnFileNew()执行过程分析
1.     void CWinApp::OnFileNew()
{

       if (m_pDocManager != NULL)

              m_pDocManager->OnFileNew();

}

注释:MFC对ID_FILE_NEW菜单的响应函数,系统默认操作.

2.     void CDocManager::OnFileNew()
{

       if (m_templateList.IsEmpty())

       {

              TRACE0("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 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

}

注:如果跳过此函数而手动操作直接进入pTemplate->OpenDocumentFile(),那么文档模版列表选择对话框也就不会出现了.

3.1       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)

      {

             // 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

      {

             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;

}

3.1.1      BOOL CDocument::SaveModified()

{

      if (!IsModified())

             return TRUE;        // ok to continue

 

      // get name/title of document

      CString name;

      if (m_strPathName.IsEmpty())

      {

             // get name based on caption

             name = m_strTitle;

             if (name.IsEmpty())

                    ENSURE(name.LoadString(AFX_IDS_UNTITLED));

      }

      else

      {

             // get name based on file title of path name

             name = m_strPathName;

             AfxGetFileTitle(m_strPathName, name.GetBuffer(_MAX_PATH), _MAX_PATH);

             name.ReleaseBuffer();

      }

 

      CString prompt;

      AfxFormatString1(prompt, AFX_IDP_ASK_TO_SAVE, name);

      switch (AfxMessageBox(prompt, MB_YESNOCANCEL, AFX_IDP_ASK_TO_SAVE))

      {

      case IDCANCEL:

             return FALSE;       // don't continue

 

      case IDYES:

             // If so, either Save or Update, as appropriate

             if (!DoFileSave())

                    return FALSE;      // don't continue

             break;

 

      case IDNO:

             // If not saving changes, revert the document

             break;

 

      default:

             ASSERT(FALSE);

             break;

      }

      return TRUE;    // keep going

}

 

 

3.1.2      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;

}

 

3.1.3      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

}

 

 

 

3.1.4      BOOL CDocument::OnSaveDocument(LPCTSTR lpszPathName)

{

      ENSURE(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

}

 

 

 

3.2     CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,BOOL bMakeVisible)
{

       CDocument* pDocument = CreateNewDocument();

       if (pDocument == NULL)

       {

              TRACE0("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

                     TRACE0("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

                     TRACE0("CDocument::OnOpenDocument returned FALSE./n");

                     pFrame->DestroyWindow();

                     return NULL;

              }

              pDocument->SetPathName(lpszPathName);

       }

 

       InitialUpdateFrame(pFrame, pDocument, bMakeVisible);

       return pDocument;

}

 

4.     CDocument* CDocTemplate::CreateNewDocument()
{

       // default implementation constructs one from CRuntimeClass

       if (m_pDocClass == NULL)

       {

              TRACE0("Error: you must override CDocTemplate::CreateNewDocument./n");

              ASSERT(FALSE);

              return NULL;

       }

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

       if (pDocument == NULL)

       {

              TRACE1("Warning: Dynamic create of document type %hs failed./n",

                     m_pDocClass->m_lpszClassName);

              return NULL;

       }

       ASSERT_KINDOF(CDocument, pDocument);

       AddDocument(pDocument);

       return pDocument;

}

 

5.     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)

       {

              TRACE0("Error: you must override CDocTemplate::CreateNewFrame./n");

              ASSERT(FALSE);

              return NULL;

       }

       CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();

       if (pFrame == NULL)

       {

              TRACE1("Warning: Dynamic create of frame %hs failed./n",

                     m_pFrameClass->m_lpszClassName);

              return NULL;

       }

       ASSERT_KINDOF(CFrameWnd, pFrame);

 

       if (context.m_pNewViewClass == NULL)

              TRACE0("Warning: creating frame with no default view./n");

 

       // create new from resource

       if (!pFrame->LoadFrame(m_nIDResource,

                     WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,   // default frame styles

                     NULL, &context))

       {

              TRACE0("Warning: CDocTemplate couldn't create a frame./n");

              // frame will be deleted in PostNcDestroy cleanup

              return NULL;

       }

 

       // it worked !

       return pFrame;

}

 

6.     BOOL CDocument::OnNewDocument()
{

       if (IsModified())

              TRACE0("Warning: OnNewDocument replaces an unsaved document./n");

 

       DeleteContents();

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

       SetModifiedFlag(FALSE);     // make clean

 

       return TRUE;

}

 

7.     BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName)
{

       if (IsModified())

              TRACE0("Warning: OnOpenDocument replaces an unsaved document./n");

 

       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;

}

 

8.     BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,  CWnd* pParentWnd, CCreateContext* pContext)
{

       // only do this once

       ASSERT_VALID_IDR(nIDResource);

       ASSERT(m_nIDHelp == 0 || m_nIDHelp == nIDResource);

 

       m_nIDHelp = nIDResource;    // ID for help context (+HID_BASE_RESOURCE)

 

       CString strFullString;

       if (strFullString.LoadString(nIDResource))

              AfxExtractSubString(m_strTitle, strFullString, 0);    // first sub-string

 

       VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));

 

       // attempt to create the window

       LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource);

       LPCTSTR lpszTitle = m_strTitle;

       if (!Create(lpszClass, lpszTitle, dwDefaultStyle, rectDefault,

         pParentWnd, MAKEINTRESOURCE(nIDResource), 0L, pContext))

       {

              return FALSE;   // will self destruct on failure normally

       }

 

       // save the default menu handle

       ASSERT(m_hWnd != NULL);

       m_hMenuDefault = ::GetMenu(m_hWnd);

 

       // load accelerator resource

       LoadAccelTable(MAKEINTRESOURCE(nIDResource));

 

       if (pContext == NULL)   // send initial update

              SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);

 

       return TRUE;

}

 

9.     void DocTemplate::InitialUpdateFrame(CFrameWnd* pFrame, CDocument* pDoc,BOOL bMakeVisible)
{

       // just delagate to implementation in CFrameWnd

       pFrame->InitialUpdateFrame(pDoc, bMakeVisible);

}

 

10.     void CFrameWnd::InitialUpdateFrame(CDocument* pDoc, BOOL bMakeVisible)

{

       // if the frame does not have an active view, set to first pane

       CView* pView = NULL;

       if (GetActiveView() == NULL)

       {

              CWnd* pWnd = GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);

              if (pWnd != NULL && pWnd->IsKindOf(RUNTIME_CLASS(CView)))

              {

                     pView = (CView*)pWnd;

                     SetActiveView(pView, FALSE);

              }

       }

 

       if (bMakeVisible)

       {

              // send initial update to all views (and other controls) in the frame

              SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);

 

              // give view a chance to save the focus (CFormView needs this)

              if (pView != NULL)

                     pView->OnActivateFrame(WA_INACTIVE, this);

 

              // finally, activate the frame

              // (send the default show command unless the main desktop window)

              int nCmdShow = -1;      // default

              CWinApp* pApp = AfxGetApp();

              if (pApp != NULL && pApp->m_pMainWnd == this)

              {

                     nCmdShow = pApp->m_nCmdShow; // use the parameter from WinMain

                     pApp->m_nCmdShow = -1; // set to default after first time

              }

              ActivateFrame(nCmdShow);

              if (pView != NULL)

                     pView->OnActivateView(TRUE, pView, pView);

       }

 

       // update frame counts and frame title (may already have been visible)

       if (pDoc != NULL)

              pDoc->UpdateFrameCounts();

       OnUpdateFrameTitle(TRUE);

}

B) OnFileOpen()执行过程分析
11.             void CWinApp::OnFileOpen()
{

       ASSERT(m_pDocManager != NULL);

       m_pDocManager->OnFileOpen();

}

 

12.             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

}

 

13.             CDocument* CWinApp::OpenDocumentFile(LPCTSTR lpszFileName)
{

       ASSERT(m_pDocManager != NULL);

       return m_pDocManager->OpenDocumentFile(lpszFileName);

}

 

14.             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;

       AfxFullPath(szPath, szTemp);

       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)

                            pFrame->ActivateFrame();

                     else

                            TRACE0("Error: Can not find a frame for document to activate./n");

                     CFrameWnd* pAppFrame;

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

                     {

                            ASSERT_KINDOF(CFrameWnd, pAppFrame);

                            pAppFrame->ActivateFrame();

                     }

              }

              else

              {

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

}

 

15.             CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,BOOL bMakeVisible)
{

       CDocument* pDocument = CreateNewDocument();

       if (pDocument == NULL)

       {

              TRACE0("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

                     TRACE0("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

                     TRACE0("CDocument::OnOpenDocument returned FALSE./n");

                     pFrame->DestroyWindow();

                     return NULL;

              }

              pDocument->SetPathName(lpszPathName);

       }

 

       InitialUpdateFrame(pFrame, pDocument, bMakeVisible);

       return pDocument;

}

 

16.             CDocument* CDocTemplate::CreateNewDocument()
{

       // default implementation constructs one from CRuntimeClass

       if (m_pDocClass == NULL)

       {

              TRACE0("Error: you must override CDocTemplate::CreateNewDocument./n");

              ASSERT(FALSE);

              return NULL;

       }

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

       if (pDocument == NULL)

       {

              TRACE1("Warning: Dynamic create of document type %hs failed./n",

                     m_pDocClass->m_lpszClassName);

              return NULL;

       }

       ASSERT_KINDOF(CDocument, pDocument);

       AddDocument(pDocument);

       return pDocument;

}

 

17.             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)

       {

              TRACE0("Error: you must override CDocTemplate::CreateNewFrame./n");

              ASSERT(FALSE);

              return NULL;

       }

       CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();

       if (pFrame == NULL)

       {

              TRACE1("Warning: Dynamic create of frame %hs failed./n",

                     m_pFrameClass->m_lpszClassName);

              return NULL;

       }

       ASSERT_KINDOF(CFrameWnd, pFrame);

 

       if (context.m_pNewViewClass == NULL)

              TRACE0("Warning: creating frame with no default view./n");

 

       // create new from resource

       if (!pFrame->LoadFrame(m_nIDResource,

                     WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,   // default frame styles

                     NULL, &context))

       {

              TRACE0("Warning: CDocTemplate couldn't create a frame./n");

              // frame will be deleted in PostNcDestroy cleanup

              return NULL;

       }

 

       // it worked !

       return pFrame;

}

 

18.             BOOL CDocument::OnNewDocument()
{

       if (IsModified())

              TRACE0("Warning: OnNewDocument replaces an unsaved document./n");

 

       DeleteContents();

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

       SetModifiedFlag(FALSE);     // make clean

 

       return TRUE;

}

 

19.             BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName)
{

       if (IsModified())

              TRACE0("Warning: OnOpenDocument replaces an unsaved document./n");

 

       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;

}

 

20.             void DocTemplate::InitialUpdateFrame(CFrameWnd* pFrame, CDocument* pDoc,BOOL bMakeVisible)
{

       // just delagate to implementation in CFrameWnd

       pFrame->InitialUpdateFrame(pDoc, bMakeVisible);

}

 

21.     void CFrameWnd::InitialUpdateFrame(CDocument* pDoc, BOOL bMakeVisible)

{

       // if the frame does not have an active view, set to first pane

       CView* pView = NULL;

       if (GetActiveView() == NULL)

       {

              CWnd* pWnd = GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);

              if (pWnd != NULL && pWnd->IsKindOf(RUNTIME_CLASS(CView)))

              {

                     pView = (CView*)pWnd;

                     SetActiveView(pView, FALSE);

              }

       }

 

       if (bMakeVisible)

       {

              // send initial update to all views (and other controls) in the frame

              SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);

 

              // give view a chance to save the focus (CFormView needs this)

              if (pView != NULL)

                     pView->OnActivateFrame(WA_INACTIVE, this);

 

              // finally, activate the frame

              // (send the default show command unless the main desktop window)

              int nCmdShow = -1;      // default

              CWinApp* pApp = AfxGetApp();

              if (pApp != NULL && pApp->m_pMainWnd == this)

              {

                     nCmdShow = pApp->m_nCmdShow; // use the parameter from WinMain

                     pApp->m_nCmdShow = -1; // set to default after first time

              }

              ActivateFrame(nCmdShow);

              if (pView != NULL)

                     pView->OnActivateView(TRUE, pView, pView);

       }

 

       // update frame counts and frame title (may already have been visible)

       if (pDoc != NULL)

              pDoc->UpdateFrameCounts();

       OnUpdateFrameTitle(TRUE);

}

 

 

原创粉丝点击