学习MFC ,学习SDI,学习MDI,直到现在工作中要一直和MDI打交道,当中明白了很多,想纪录下来。
很多书上只是介绍了CDocument,CView,CChildFrame之间是如何通过CCreateContext来建立联系的。这里介绍另外一个方面的内存,就是MDI中CDocManager,CMultiDocTemplate,CDocument以及CView之间的关系:App中包含了一个m_pDocManager
在BOOL CMDIApp::InitInstance()中会调用
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_Test_DocsTYPE,
RUNTIME_CLASS(CFirstDoc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CFirstView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
void CWinApp::AddDocTemplate(CDocTemplate* pTemplate)
{
if (m_pDocManager == NULL)
m_pDocManager = new CDocManager;
m_pDocManager->AddDocTemplate(pTemplate);
}
而 AddDocTemplate(pDocTemplate);是可以调用多次的。
也就是说在App中,利用m_pDocManager来管理多个CMultiDocTemplate对象!
在CMultiDocTemplate中,有一个成员函数很值得注意:
void CMultiDocTemplate::AddDocument(CDocument* pDoc)
{
ASSERT_VALID(pDoc);
CDocTemplate::AddDocument(pDoc);
ASSERT(m_docList.Find(pDoc, NULL) == NULL); // must not be in list
m_docList.AddTail(pDoc);
}
可以看出,利用CMultiDocTemplate::m_docList,CMultiDocTemplate管理着多个CDocument对象!
在CDocument中,同样有一个函数值得关注:
void CDocument::AddView(CView* pView)
{
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::m_viewList,CDocument管理中多个CView对象!
这样一来,各个对象之间的关系就清晰。MDI中CDocManager,CMultiDocTemplate,CDocument以及CView之间的关系:在CWinApp中CDocManager管理着多个CMultiDocTemplate;CMultiDocTemplate管理着多个CDocument;CDocument管理着多个CView。加上我们熟知的CCreateContext,整个MDI中各个常用的类之间的关系就基本明晰了!
下面会介绍一下如何在SDI,MDI模式下如何组合CDocManager,CMultiDocTemplate,CDocument以及CView形成不同的应用:
SDI_MultiViews单文档多视图.rar,
MDI相同的Doc对应不同的View,当然Doc对象创建后是各不相同的.rar,
MDI不同的Doc对应不同的View.rar,
MDI不同的Doc对应不同的View--其中一个Doc对应多个View.rar,
MDI不同的Doc对应不同的View--其中一个Doc对应多个View ThirdView带分割条.rar,
MDI不同的Doc对应不同的View--其中一个Doc对应多个View ThirdView带分割条.rar,还加上停靠窗口
(待续)