文档/视图结构是MFC中最有特色而又有难度的部分,在这当中涉及了应用、文档模板、文档、视图、MDI框架窗口、MDI子窗口等不同的对象,如果不了解这些部分之间如何关联的话,就可能犯错误,也就很难编出有水平的文档/视图程序。比如我在初学VC编程的时候,为应用
程序添加了两个文档模板,两个模板公用一个文档类,只是视图不一样,期望当一个模板的文档的视图改变了文档后,调用UpdateAllViews后也能更新另一个文档
模板的视图,结果当然是不行的,原因就是对MFC的文档/视图结构没有深入的了解,了解的最好方法就是阅读一下MFC的源代码。下面就是我的笔记:
(一)应用
程序对象与文档
模板之间的联系:
首先,在应用
程序对象中有一个CDocManager指针类型的共有数据成员m_pDocManager,在CDocManager中维护一个CPtrList类型的链表:m_tempateList,它是一个保护成员。InitInstance函数中调用CWinApp::AddDocTemplate函数,实际上是调用m_pDocManager的AddDocTemplate函数向链表m_templateList添加
模板指针。CWinApp提供了GetFirstDocTemplatePosition和GetNextDocTemplate函数实现对m_templateList链表的访问(实际上是调用了CDocManager的相关函数)。
在文件操作方面CWinApp提供的最常用的功能是文件的新建(OnFileNew)和打开(OnFileOpen),它也是调用CDocManager类的同名函数。对于新建,一般的时候在只有一个文档模板的时候,它新建一个空白的文件;如果有多个文档
模板的时候,它会出现一个对话框提示选择文档类型。它的源代码如下:
void CDocManager::OnFileNew()
{
if (m_templateList.IsEmpty())
{
.
return;
}
//取第一个文档
模板的指针
CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();
if (m_templateList.GetCount() > 1)
{
// 如果多于一个文档
模板,出现对话框提示用户去选择
CNewTypeDlg dlg(&m_templateList);
int nID = dlg.DoModal();
if (nID == IDOK)
pTemplate = dlg.m_pSelectedTemplate;
else