MFC OnFileNew OnFileOpen过程分析代码

A) OnFileNew()执行过程分析

1.     void CWinApp::OnFileNew()

{

       if (m_pDocManager != NULL)

              m_pDocManager->OnFileNew();

}

注释:MFCID_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.     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);

}

你可能感兴趣的:(exception,null,delete,mfc,Path,templates)