MFC多文档和单文档视结构

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

MFC多文档和单文档视结构
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
//这一页的代码最重要了,呵呵……什么都在这里面呢;
单文档新建:
CWinApp_________docManager->docSingleTemplate 的OpenDocumentFile函数参数为空,此函数完成了大部分东西,包括新建文档类框架类等______________然后是调用CDocument就没什么意思了,当然我们要是重载了CDocument的新建函数就是调用子类虚函数。

多文档新建:
CWinApp_________docManager->docMultTemplate的OpenDocumentFile函数参数为空,此函数完成了大部分东西,包括新建文档类框架类等______________然后是调用CDocument就没什么意思了,当然我们要是重载了CDocument的新建函数就是调用子类虚函数。

单文档打开:CWinApp_________docManager中经过一个
打开对话框传递参数,中途还调用了APP的OpenDocumentFile,当然如果我们的APP重载了这个函数也要调用我们的但是我们的函数一定别忘记最后返回是调
用父类的此函数___________docSingleTemplate的OpenDocumentFile函数参数不为空,此函数完成了大部分东西,包括新建文档类框架类等______________然后是调用CDocument就没什么意思了,当然我们要是重载了CDocument的新建函数就是调用子类虚函数。

多文档打开:CWinApp_________docManager中经过一个
打开对话框传递参数,中途还调用了APP的OpenDocumentFile,当然如果我们的APP重载了这个函数也要调用我们的但是我们的函数一定别忘记最后返回是调
用父类的此函数___________docMultTemplate的OpenDocumentFile函数参数不为空,此函数完成了大部分东西,包括新建文档类框架类等______________然后是调用CDocument就没什么意思了,当然我们要是重载了CDocument的新建函数就是调用子类虚函数。

他们两个只有在docMultTemplate和docSingleTemplate的OpenDocumentFile函数中的动作不同,单文档负责新建框架类和视类但是如果存在了我们就不重建了,只是给其赋值。

而多文档无论如何都会新建一个视类和框架类文档类,这也就是为什么他是多文档结构的原因。

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
接下来介绍这个最重要的函数,它基本什么都干了,不管是新建还是打开都得调用它,呵呵……
//
CDocument*
CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,
BOOL bMakeVisible)
{
//下面调用的是CDocTemplate::CreateNewDocument() CDocument* pDocument = CreateNewDocument();//这里面调用了AddDocument(pDocument);
//添加了一个CMyMultiTestDoc : public CDocument
//CMultiDocTemplate::m_docList保存的所有该种文档的
//文档实例的指针列表。

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);//创建了一个新的CChildFrame框架
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())//刚打开时新建的文档。

add by ralf
{
// 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))//这里是打开一个文档。

add by ralf
{
// 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;
}
要了解文档、视图、框架窗口、文档模板之间的相互关系,关键要理解他们的结构
1、首先应该对CWinApp类有充分的了解
它包含并管理着应用程序的文档/视窗的所有信
息。

它有一个成员变量
CDocManager * m_pDocManager,此变量是文档/视窗的管理器,m_templateList
是CDocManager里的一个列表,此列表里保存了所有文档模板的指针,当用户调用
CWinApp::AddDocTemplate( pDocTemplate ) 后
该pDocTemplate存入了
CWinApp::m_pDocManager::m_templateList里。

CWinApp::GetFirstDocTemplatePosition()
CWinApp::GetNextDocTemplate(POSITION& pos) 是遍例所有的文档模板指针。

2、上面我们提到了文档模板(CMultiDocTemplate(我们主要针对对文档)),
这是一个极重要的类。

CMultiDocTemplate::m_docList保存的所有该种文档的
文档实例的指针列表。

下面两个函数用于维护CMultiDocTemplate::m_docList数据
CMultiDocTemplate::AddDocument(CDocument*
pDoc);
CMultiDocTemplate::RemoveDocument(CDocument* pDoc);
而CMultiDocTemplate::GetFirstDocPosition() const;
CMultiDocTemplate::CDocument* GetNextDoc(POSITION& rPos) const;
用于遍例该文档类型所有文档实例。

3、上面提到文档(CDocument)
CDocument 我们最熟悉不过了。

每一个文档实例可有多个视与之相对应。

CDocument::m_viewList用来保存所有与此文档实例相关的View
★★★★这里我拉鲁夫说一下:CDocument::AddView函数用来维护m_viewList数据但我们一般不用★★★★
void CDocument::AddView(CView*
pView)//★★★MFC源码
{
ASSERT_VALID(pView);
ASSERT(pView->m_pDocument == NULL); //
must not be already attached
ASSERT(m_viewList.Find(pView, NULL) == NULL); // must not be in list
m_viewList.AddTail(pView);
ASSERT(pView->m_pDocument == NULL); // must be un-attached
pView->m_pDocument = this;
OnChangedViewList(); // must be the last thing done to the document
}
CDocument::GetDocTemplate 可获得CMultiDocTemplate;
4、CView 他是放在CMDIChildWnd里的,每一个CMDIChildWnd有一个View
CView::GetDocument可获得与此视相关的CDocument
CView::GetParentFrame() 可获得CMDIChildWnd;
通过以上分析可见
CWinApp,CMDIChildWnd,CView,CDocument,CMultiDocT emplate之间知道其中一个实例
必可知道其他所有几个实例,CWinApp统领全局,任何时候,只要获得CWinApp实例,则所有的文档模板,
文档实例,视,Frame窗口均可被枚举出来。

AfxGetApp() 获得CWinApp实例指针。

★★★★★最后我介绍一个最重要的:其实我们一个文档一般就对应一个视图!!!!!!!★★★★——————————————————————————————————————————获得CWinApp
获得CMainFrame
获得CChildFrame
获得CDocument
获得CView在CWinApp中AfxGetMainWnd()
m_pMainWnd
AfxGetMainWnd()->MDIGetActive() AfxGetMainWnd()->GetActiveFrame()
SDI:AfxGetMainWnd()->GetActiveView()->GetDocu ment()
MDI:AfxGetMainWnd()->MDIGetActive()->GetActive View()->GetDocument()
SDI:AfxGetMainWnd()->GetActiveView()
MDI:AfxGetMainWnd()->MDIGetActive()->GetActive View()
在CMainFrame中
AfxGetApp()
theAppMDIGetActive()
GetActiveFrame()
SDI:GetActiveView()->GetDocument()
MDI:MDIGetActive()->GetActiveView()->GetDocume nt()
SDI:GetActiveView()
MDI:MDIGetActive()->GetActiveView()
在CChildFrame中
AfxGetApp()
theApp
GetParentFrame()GetActiveView()->GetDocument() GetActiveView()
在CDocument中
AfxGetApp()
theApp
AfxGetMainWnd()
AfxGetMainWnd()->MDIGetActive()
AfxGetMainWnd()->GetActiveFrame()POSITION pos = GetFirstViewPosition();GetNextView(pos)
在CView中
AfxGetApp()
theApp
AfxGetMainWnd()
GetParentFrame()
GetDocument()在其他类中
AfxGetApp()
AfxGetMainWnd()
AfxGetMainWnd()->MDIGetActive()
AfxGetMainWnd()->GetActiveFrame()
SDI:AfxGetMainWnd()->GetActiveView()->GetDocu ment()
MDI:AfxGetMainWnd()->MDIGetActive()->GetActive View()->GetDocument()
SDI:AfxGetMainWnd()->GetActiveView()
MDI:AfxGetMainWnd()->MDIGetActive()->GetActive View()。

相关文档
最新文档