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

    技术2022-05-19  18

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

    }

     

     


    最新回复(0)