一.DeleteContent:一般在销毁文档之前调用此函数,他是销毁文档中的数据,并不是销毁CDocument对象。另外,它还用来保证在重新加载文档之前该文档为NULL,在关闭一个文档时负责删除数据。单文档应用程序中只存在一个CDocument对象。

 

二.在单击‘File|New’时

函数调用顺序:

CWinApp::OnFileNew------>CDocManager::OnFileNew---------->CSingleDocmentTemplate::OnPenDocument------------>....

到此,程序执行回分两种情况(根据他的保护成员:lpszPathName是否为null来判断):如果为空,则直接调用自己重载了的虚函数OnNewDocument。否则先调用OnOpenDocument

MFC源码如下:

 

1 void CWinApp::OnFileNew()
2 {
3 if (m_pDocManager != NULL)
4 m_pDocManager->OnFileNew();
5 }  

CDocManager::OnFileNew:

 

代码

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

//事实上,pTemplate指向的是CSingleDocmentTemplate实例

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

 

 CSingleDocmentTemplate::OnPenDocument源码如下:

 

代码
1 CDocument* CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,
2 BOOL bMakeVisible)
3 // if lpszPathName == NULL => create new file of this type
4  {
5 CDocument* pDocument = NULL;
6 CFrameWnd* pFrame = NULL;
7 BOOL bCreated = FALSE; // => doc and frame created
8   BOOL bWasModified = FALSE;
9
10 if (m_pOnlyDoc != NULL)
11 {
12 // already have a document - reinit it
13   pDocument = m_pOnlyDoc;
14 if (!pDocument->SaveModified())
15 return NULL; // leave the original one
16  
17 pFrame = (CFrameWnd*)AfxGetMainWnd();
18 ASSERT(pFrame != NULL);
19 ASSERT_KINDOF(CFrameWnd, pFrame);
20 ASSERT_VALID(pFrame);
21 }
22 else
23 {
24 // create a new document
25   pDocument = CreateNewDocument();
26 ASSERT(pFrame == NULL); // will be created below
27 bCreated = TRUE;
28 }
29
30 if (pDocument == NULL)
31 {
32 AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
33 return NULL;
34 }
35 ASSERT(pDocument == m_pOnlyDoc);
36
37 if (pFrame == NULL)
38 {
39 ASSERT(bCreated);
40
41 // create frame - set as main document frame
42 BOOL bAutoDelete = pDocument->m_bAutoDelete;
43 pDocument->m_bAutoDelete = FALSE;
44 // don't destroy if something goes wrong
45 pFrame = CreateNewFrame(pDocument, NULL);
46 pDocument->m_bAutoDelete = bAutoDelete;
47 if (pFrame == NULL)
48 {
49 AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
50 delete pDocument; // explicit delete on error
51 return NULL;
52 }
53 }
54
55 if (lpszPathName == NULL)
56 {
57 // create a new document
58 SetDefaultTitle(pDocument);
59
60 // avoid creating temporary compound file when starting up invisible
61 if (!bMakeVisible)
62 pDocument->m_bEmbedded = TRUE;
63
64 if (!pDocument->OnNewDocument())
65 {
66 // user has been alerted to what failed in OnNewDocument
67 TRACE0("CDocument::OnNewDocument returned FALSE.\n");
68 if (bCreated)
69 pFrame->DestroyWindow(); // will destroy document
70 return NULL;
71 }
72 }
73 else
74 {
75 CWaitCursor wait;
76
77 // open an existing document
78 bWasModified = pDocument->IsModified();
79 pDocument->SetModifiedFlag(FALSE); // not dirty for open
80
81 if (!pDocument->OnOpenDocument(lpszPathName))
82 {
83 // user has been alerted to what failed in OnOpenDocument
84 TRACE0("CDocument::OnOpenDocument returned FALSE.\n");
85 if (bCreated)
86 {
87 pFrame->DestroyWindow(); // will destroy document
88 }
89 else if (!pDocument->IsModified())
90 {
91 // original document is untouched
92 pDocument->SetModifiedFlag(bWasModified);
93 }
94 else
95 {
96 // we corrupted the original document
97 SetDefaultTitle(pDocument);
98
99 if (!pDocument->OnNewDocument())
100 {
101 TRACE0("Error: OnNewDocument failed after trying to open a document - trying to continue.\n");
102 // assume we can continue
103 }
104 }
105 return NULL; // open failed
106 }
107 pDocument->SetPathName(lpszPathName);
108 }
109
110 CWinThread* pThread = AfxGetThread();
111 if (bCreated && pThread->m_pMainWnd == NULL)
112 {
113 // set as main frame (InitialUpdateFrame will show the window)
114 pThread->m_pMainWnd = pFrame;
115 }
116 InitialUpdateFrame(pFrame, pDocument, bMakeVisible);
117
118 return pDocument;
119 }
120

 

 

 OnOpenDocument源码:

 

代码
1 BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName)
2 {
3 if (IsModified())
4 TRACE0("Warning: OnOpenDocument replaces an unsaved document.\n");
5
6 CFileException fe;
7 CFile* pFile = GetFile(lpszPathName,
8 CFile::modeRead|CFile::shareDenyWrite, &fe);
9 if (pFile == NULL)
10 {
11 ReportSaveLoadException(lpszPathName, &fe,
12 FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
13 return FALSE;
14 }
15
16 DeleteContents();
17 SetModifiedFlag(); // dirty during de-serialize
18
19 CArchive loadArchive(pFile, CArchive::load | CArchive::bNoFlushOnDelete);
20 loadArchive.m_pDocument = this;
21 loadArchive.m_bForceFlat = FALSE;
22 TRY
23 {
24 CWaitCursor wait;
25 if (pFile->GetLength() != 0)
26 Serialize(loadArchive); // load me用于文档串行化:
27 loadArchive.Close();
28 ReleaseFile(pFile, FALSE);
29 }
30 CATCH_ALL(e)
31 {
32 ReleaseFile(pFile, TRUE);
33 DeleteContents(); // remove failed contents
34
35 TRY
36 {
37 ReportSaveLoadException(lpszPathName, e,
38 FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
39 }
40 END_TRY
41 DELETE_EXCEPTION(e);
42 return FALSE;
43 }
44 END_CATCH_ALL
45
46 SetModifiedFlag(FALSE); // start off with unmodified
47
48 return TRUE;
49 }
50

 

三.单文档模板类创建了文档对象和框架窗口对象,然后在有框架窗口创建视图对象

posted on 2009-12-29 00:52  !-_-木糖-_-!  阅读(442)  评论(0编辑  收藏  举报