MFC多文档和单文档视结构
- 格式:doc
- 大小:15.23 KB
- 文档页数:14
MFC中实现多文档(转)2007-12-27 21:21MDI (Multiple Document Interface) 是Windows 界面的一种规范,它建立多个窗口来浏览文档数据,如Windows 中的Program Manager 等都是按MDI 规范实现的。
在实际工程软件开发中,许多程序员将其作为一种实现多窗口的标准方法。
微软基础类库(Microsoft Foundation Class Library, 简称MFC 库), 是微软公司为方便Windows 程序开发所提供的一个功能强大的通用类库。
MFC 的核心是以类的形式封装了大量Windows API。
在可视化编程语言VC++ 下应用MFC 是目前开发Windows 程序最方便的途径之一。
VC++ 提供的各种开发工具如AppWizard、ClassWizard 和App Studio, 可以建立起具备基本功能的Windows 框架程序(Framework)。
而程序员所需要做的工作就是将自己特有的代码填入到框架程序中去,从而极大地减少了用户界面编程的工作量,加快了开发速度。
关于MDI 的标准开发方法可参考一般的Windows 编程书籍,本文将介绍利用MFC 实现MDI 界面。
MFC 2.0 以上版本支持“文档/ 浏览视窗”(Document/View) 结构模式。
由文档负责管理数据,浏览视窗负责数据显示及与用户的交互,从而实现了数据与界面的分离,使整个程序设计更具规范化、模块化。
MFC 中,“文档”由类CDocument 及其派生类实现( 简称Doc 类);“浏览视窗”由类CView 及其派生类实现 ( 简称View 类)。
二者都包含于应用程序的框架窗口中,并由其管理。
使用单文档时,框架窗口由类CFrameWnd 及其派生类实现;使用多文档时,框架窗口是利用类CMDIFrameWnd 和CMDIChildWnd 实现。
由文档模板将文档、浏览窗口和框架窗口三者联系起来。
第8章文档和视图精讲MFC应用程序的核心是文档/视图结构。
在前面章节的学习中,已经接触了不少文档/视图结构的应用程序,本章将详细分析其结构和原理,并进一步学习使用复杂的文档结构、构造更加丰富的视图。
8.1 文档/视图概述使用MFC的AppWizard可以创建三种类型的应用程序:(1)单文档界面的应用程序(SDI:Single Document Interface)(2)多文档界面的应用程序(MDI:Multiple Documents Interface)(3)基于对话框的应用程序(Dialog based)基于对话框的应用程序框架非常简单,由应用程序类、对话框类构成。
通过应用程序类的InitInstance()函数,构造一个模式对话框对象;调用DoModal()函数,让Windows对话框处理程序象通常情况一样接受和分配消息;用户退出对话框后,程序也就结束了。
我们已经知道SDI应用程序由应用程序类(CWinApp)、框架窗口类(CFrameWnd)、文档类(CDocument)、视图类(CView)和文档模板类(CSingleDocTemplate)共同作用。
MDI应用程序与SDI 应用程序的主要差别在于:MDI有CMDIFrameWnd和CMDIChildWnd两个框架窗口类,前一个派生CMainFrame类,负责菜单等界面元素的主框架窗口管理;后一个派生CChildFrame类,负责相应的文档及其视图的子框架维护。
而SDI由框架窗口类CFrameWnd 派生CMainFrame类。
一个文档可以有多个视图,但一个视图只能对应一个确定的文档。
因此,MDI应用程序需要解决的问题是多个文档的数据管理方法。
在MDI应用程序中,文档模板只支持主窗口。
每打开一个新文档时,都调用文档类的成员函数OnNewDocument(),建立一个由CMDIChildWnd派生的新的MDI子窗口,在子窗口中保存已打开的文档,所有这些细节都由MFC库来处理。
深入了解MFC中的文挡/视结构李泽宇金刚熊联欢姜军(华中理工大学图象识别与人工智能研究所)Visual C++ 5.0 以其功能强大、用户界面友好而倍受程序员们的青睐。
但是,在当前的Microsoft 基本类库4.2 版本中,大约有将近200 个类,数千个函数,加之Microsoft 公司隐藏了一些技术细节,使得人们深入学习MFC变得十分困难。
MFC的AppWizard可以生成三种类型的应用程序:基于对话框的应用、单文档应用(SDI)和多文档应用(MDI)。
前两者的结构较简单,本文不再赘叙。
笔者拟从MFC中的文档/视结构入手,分析一些函数的流程,并解决编制MDI 应用程序过程中的一些常见问题。
(一)、了解文档/视结构MFC应用程序模型历经多年以有了相当大的发展。
有一个时期,它只是个使用应用程序对象和主窗口对象的简单模型。
在这个模型中,应用程序的数据作为成员变量保持在框架窗口类中,在框架窗口的客户区中,该数据被提交显示器。
随着MFC2。
0的问世,一种应用程序结构的新方式----MFC文档/视结构出现了。
在这种结构中,CFrameWnd繁重的任务被委派给几个不同类,实现了数据存储和显示的分离。
一般情况下,采用文档/视结构的应用程序至少应由以下对象组成:。
应用程序是一个CwinApp派生对象,它充当全部应用程序的容器。
应用程序沿消息映射网络分配消息给它的所有子程序。
框架窗口是一CfrmeWnd派生对象。
文档是一个CDocument派生对象,它存储应用程序的数据,并把这些信息提供给应用程序的其余部分。
视窗是Cview派生对象,它与其父框架窗口用户区对齐。
视窗接受用户对应用程序的输入并显示相关联的文档数据。
通常,应用程序数据存在于简单模型中的框架窗口中。
在文档/视方式中,该数据移入称为document 的独立数据对象。
当然,文档不一定是文字,文档是可以表现应用程序使用的数据集的抽象术语。
而用户输入处理及图形输出功能从框架窗口转向视图。
MFC类库是一个层次结构,主要有CObject类、应用程序类、可视对象类、绘图和打印类、通用类、数据库类、Internet和网络类、OLE类。
(1)CObject类CObject类是MFC的抽象基类,MFC中的大多数类是从CObject类派生出来的。
它是MFC 中多数类和用户自定义的根类,该类为程序员提供了希望融入所编写程序的许多公共操作,包括对象的建立和删除、串行化支持、对象诊断输出、运行时信息以及集合类的兼容等。
CObject类的声明在Afx.h中。
(2)应用程序结构类该类主要用于构造框架应用程序的结构,提供了多数应用程序公用的功能.编写程序的任务是填充框架,添加应用程序专有的功能。
1.应用程序和线程支持类CWinThread类是所有线程的基类,窗口应用程序类CWinApp类就是从该类中派生来的。
每个应用程序有且只有一个应用程序对象,在运行程序中该对象和其他对象相互协调,该对象从CWinApp中派生出来。
该类封装了初始化、运行、终止应用程序的代码。
2.命令相关类CCmdTarget类是CObject的子类,它是MFC所有具有消息映射属性的基类。
消息映射规定了当一对象接收到消息命令时,应调用哪个函数对该消息进行处理。
程序员很少需要从CCmdTarget类中直接派生出新类,往往都是从它的子类中派生出新类。
如窗口类(CWnd)、应用程序类(CWinApp)、文档模板类(CDocTemplate)、视类(CView)及框架窗口类(CFrameWnd)等。
3.文档类文档对象由文档对象模板创建,用于管理应用程序的数据。
视图对象表示一个窗口的客户区,用于显示文档数据并允许读者与之交互。
有关文档/视结构的类如下:①CDocTemplate类:文档模板的基类。
文档模板用于协调文档、视图和框架窗口的创建。
②CSingleDocTemplate类:单文档界面(SDI)的文档模板。
③CMultiDocTemplate类:多文档界面(MDI)的文档模板。
VC习题1下列对于WinMain函数的描述中,错误的是()。
A)WinMain函数的名称是固定的B)WinMain函数是Windows程序的入口点C)WinMain函数不能有参数D)窗口函数与WinMain的关联是通过窗口类的注册实现的以下四个特性中哪一个不属于面向对象的三大特性()。
A)封装性B)多态性C)抽象性D)继承性下列关键字中哪一个不是用于类的访问控制的()。
A)public B)friend C)private D)protected下面四个MFC类中哪一个是管理MFC应用程序的()。
A)CWinApp B)CMainFrame C)CDocument D)CView下列类中不属于MFC框架基本类的是()。
A)CWinApp B)CFrameWnd C)CView D)CObject传统的软件开发主要采用过程驱动的方法,而Windows程序的开发使用消息驱动模型,该模型靠事件机制来实现其功能。
主框架类是应用程序中负责控制菜单、工具栏和状态栏等界面元素的最主要的类。
命令视图类文档类文档模板类框架窗口类应用程序类VC习题2VC开发环境可以生成的基于MFC appwizard的应用程序类型有单文档/视图结构、多文档/视图结构和基本对话框。
包含类定义的文件称为头文件,包含类中成员函数实现代码的文件称为源文件,包含资源信息的文件称为资源文件。
ResourceView的主要功是编辑当前工程中的资源。
应用程序向导的主要功能是帮助生产应用程序。
类向导的主要功能是管理各个类中的消息。
项目工作区窗口一般在开发环境的左侧,它包含工程的多个方面,分别是classview 、fileview 和resource view 。
项目工作区文件的扩展名为.dsw 。
VC习题3下列选项中哪一个不是命令消息的触发途径:单击对话框中的按钮。
Windows应用程序的消息来源主要包括输入消息、控制消息和系统消息、用户消息。
发送消息可以采用的两个函数是postmessage 和sendmessage 。
文档对象:是用来保存数据的。
视图对象:是用来显示和编辑数据的。
应用程序框架:框架是用来管理不同文档显示界面的。
例如你有一个数据网格显示界面,还有一个图形显示界面,它们的数据可能都来自你的文档,但是视图不同,怎么办用框架。
为什么不用视图?为的是把界面管理独立的拿出来。
文档模板:MFC把文档/视图/框架视为一体,只要你创建文档/视图框架结构的程序,必定会为你创建这三个类。
这个工作在在应用程序初始化时完成,如下:[cpp]view plaincopy1.BOOL CMyHtmlApp::InitInstance()2.{3. CSingleDocTemplate* pDocTemplate;4. pDocTemplate = new CSingleDocTemplate(5. IDR_MAINFRAME,6. RUNTIME_CLASS(CMyHtmlDoc),7. RUNTIME_CLASS(CMainFrame), // main SDI frame window8. RUNTIME_CLASS(CMyHtmlView));9. AddDocTemplate(pDocTemplate);10. }单文档:就是一次只能打开一个文件,和你的文档类型支持的多少无关。
你完全可以做一个单文档的支持所有图象格式的程序,只不过它一次只能打开一个文档罢了。
多文档:就是你可以打开多个文件,和文档类型也无关。
你也可以作一个可以同时打开多个文档的程序,但它只支持一种文档类型。
何时需要文档/视图框架结构?首先你可以不使用文档视图这种框架结构,即便是在MFC中。
你可以在你需要的时候选择使用这种方式。
你可以完成一个只有视图没有文档的程序,例如一个基于对话框的应用。
哪什么时候需要呢?当你想将你的数据层和界面层分开的时候。
通常我们对数据的操作放在文档类中,例如存取,打开,关闭。
在这里你可以尽情的对你的数据进行操作,如果你需要,在对数据进行了改变后,对视图做一下更新,那么程序会将你对数据所做的改变呈现给你的程序的用户。
如何在MFC单文档中创建多视图如何在MFC单文档中创建多视图基本步骤如下:1.首先创建一个MFC单文档应用程序。
2.添加4个MFC类TopLView、BottomLView、T opRView、BottomRView,基类为CView。
3.添加一个MFC类CControlForm,基类为CFormView,对话框ID默认。
4.创建一个切分类,如MySplitter,基类为CSplitterWnd(默认基类选项中无此类,自己添加即可)。
5.在框架类Cmainframe的头文件中,添加2个MySplitter的变量(因为下面要进行两次切分操作)。
6.重写框架类Cmainframe的OnCreateClient函数,如下://第一次静态切分CreateStatic,一行两列if (!m_wndSplitter.CreateStatic(this,1,2))return FALSE;//第二次静态切分(将第一次切分后的第二列再分为2*2)及所有的子视图创建(CreateView函数)。
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CControlForm), CSize(100, 100), pContext) || !m_wndSplitter2.CreateStatic(&m_wndSplitter,2,2,WS_CHILD |WS_VISIBLE,m_wndSplitter.IdFromRowCol(0,1))|| !m_wndSplitter2.CreateView(0, 0, RUNTIME_CLASS(TopLView), CSize(350, 240), pContext) || !m_wndSplitter2.CreateView(1, 0, RUNTIME_CLASS(BottomLView), CSize(350, 240), pContext) || !m_wndSplitter2.CreateView(0, 1, RUNTIME_CLASS(TopRView), CSize(350, 240), pContext) || !m_wndSplitter2.CreateView(1, 1,RUNTIME_CLASS(BottomRView), CSize(350, 240), pContext)) {m_wndSplitter.DestroyWindow();return FALSE;}// return CFrameWnd::OnCreateClient(lpcs, pContext); //注释掉原有的响应函数注意:记得在Mainfrm.h中添加以上五个视图类的头文件:#include "CControlForm.h"#include "T opLView.h"#include "T opRView.h"#include "BottomLView.h"#include "BottomRView.h"6. 切分视图完成,结果如下:其中,最左的视图为FormView类型,操作类似对话框(可以在Resource-Dialog看到其对应的对话框资源);右边四个的操作则类似普通视图。
一、修改文档标题:(以下都是在MFC单文档工程Graphic下)1、单击【文件/新建】菜单项,或者程序启动时,程序会进入到CGraphicDoc类的OnNewDocument函数,该函数是【文件/新建】命令处理的一部分,是由框架调用的一个虚函数,用于建立一个文档。
通过该函数设置程序标题:BOOL CGraphicDoc::OnNewDocument(){if (!CDocument::OnNewDocument())return FALSE;// TODO: add reinitialization code here// (SDI documents will reuse this document)SetTitle("MY MFC");//设置程序标题为MY MFC。
return TRUE;}提示:当单击保存时,默认文件名会是设置的文档名。
2、通过IDR_MAINFRAME字符串资源修改文档标题在ResourceView选项卡下->展开String Table文件夹->双击String Table字符串资源->找到ID 为IDR_MAINFRAME的字符串资源->在头两个”\n”间添加文档标题。
符串资源的各个子串。
实际上利用MFC AppWizard生成应用程序框架的第四步,单击【Advanced】按钮也可以修改IDR_MAINFRAME字符串中的子串。
3、OnNewDocument函数的调用过程OnNewDocument函数并不是一个消息响应函数,它只是一个虚函数。
(1)、程序启动时OnNewDocument函数的调用过程,第一次启动程序时,在OpenDocumentFile函数内部创建了文档类对象,同时还创建了框架类对象和视类对象。
这就是MFC提供的文档/视类结构的一个特点:每当有一份文档产生时,总是会产生一个文档类对象、框架类对象和视类对象,它们三位一体来为这份文档服务。
第16单元多文档界面程序本单元教学目标介绍多文档界面(MDI)程序的构造和编程方法。
学习要求理解多文档界面(MDI)程序的构造,掌握其编程方法。
授课内容和框架窗口界面程序、单文档界面(SDI)程序和基于对话框的应用程序一样,多文档界面(MDI)程序也是基本的MFC应用程序结构。
MDI程序的结构最复杂,功能也最强。
其特点是用户一次可以打开多个文档,每个文档均对应不同的窗口;主窗口的菜单会自动随着当前活动的子窗口的变化而变化;可以对子窗口进行层叠、平铺等各种操作;子窗口可以在MDI主窗口区域内定位、改变大小、最大化和最小化,当最大化子窗口时,它将占满MDI主窗口的全部客户区。
MDI不仅可以在同一时间内同时打开多个文档,还可以为同一文档打开多个视图。
16.1MDI应用程序从程序员角度看,每个MDI应用程序必须有一个CMDIFrameWnd或其派生类的对象,该窗口称作MDI框架窗口。
CMDIFrameWnd是CFrameWnd的派生类,除了拥有CFrameWnd 类的全部特性外,还具有以下与MDI相关的特性:1.与SDI不同,MDI的框架窗口并不直接与一个文档和视图相关联。
MDI的框架窗口拥有客户窗口,在显示或隐藏控制条(包括工具条、状态栏、对话条)时,重新定位该子窗口。
2.MDI客户窗口是MDI子窗口的直接父窗口,它负责管理主框架窗口的客户区以及创建子窗口。
每个MDI主框架窗口都有且只有一个MDI客户窗口。
3.MDI子窗口是CMDIChildWnd或其派生类对象,CMDIChildWnd也是CFrameWnd 的派生类,用于容纳视图和文档,相当于SDI下的主框架窗口。
每打开一个文档,框架就自动为文档创建一个MDI子窗口。
一个MDI应用程序负责动态的创建和删除MDI子窗口。
在任何时刻,最多只有一个子窗口是活动的(窗口标题栏颜色呈高亮显示)。
MDI框架窗口始终与当前活动子窗口相关联,命令消息在传给MDI框架窗口之前首先分派给当前活动子窗口。
本文在介绍了几种标准的单文档与多视结构的VC5.0 MFC实现方法之后,介绍了笔者摸索出的另外两种实用方法,并给出了实现它们的的主要程序框架。
一、单文档与多视Windows程序一般分为以下几种风格:多文档、单文档、基于对话框的。
Word一类多文档程序和计算器一类基于对话框的程序不在本文介绍之列。
单文档又分为单视的和多视的。
一般情况下,单文档仅需要单视就够了,如画笔等。
但也有一些情况下,单文档需要多视支持,比如同时观察文档的不同部分,同时从不同的角度观察同一文档等。
在MFC的框架下,文档对象(CDocument)维持了一个保存其所有视的列表,并提供了增加与删除视的函数,以及当文档内容改变时通知其所有视的方法。
通过多文档框架的窗口复制机制和单文档框架的分割窗口机制是实现单文档多视的主要方法。
但这些标准方法在有的情况下并不够用,为此笔者摸索出另外两种实用的方法,在实践中使用效果良好。
二、三种标准的单文档与多视情况1.视对象基于同一视类,每个视位于MDI的一个独立子文档框架中。
用户可以通过“窗口\新窗口”菜单,为同一文档的视再创建一个窗口,通过新创建的窗口,可以编辑和观察文档的另一部分,同一文档各个视图之间自动实现同步,用户修改一个视的内容,在另外的视中也自动更新。
MFC框架通过复制原来的子框架窗口和其中的视来实现上面的功能,并且是完全自动的。
2.视对象基于同一视类,所有视位于同一文档框架中。
分割窗口将单文档窗口的视区分割成几个独立的视,框架从同一视类创建多个视对象。
Word的子窗口即属于这种类型。
3.视对象基于不同的视类,所有的视位于同一文档框架中。
多个视共享同一文档框架,但从不同的视类创建,每个视可以为文档提供不同的观察和编辑方法。
比如一个视用图形观察文档,而另一个视用文本编辑文档中对象的属性。
这种情况也适应于用不同的视来观察文档的不同部分。
这种类型的实现方法是通过重载OnCreateClient函数实现。
mfc ceditview实例全文共四篇示例,供读者参考第一篇示例:MFC CEditView(多文本编辑框视图)是Microsoft Foundation Class(MFC)库中的一个类,用于在应用程序中显示和编辑文本。
它提供了一个易于使用和定制的界面,使用户能够轻松地输入、编辑和查看文本信息。
在本文中,我们将介绍如何使用MFC CEditView类创建一个简单的文本编辑器实例。
我们需要创建一个新的MFC应用程序项目。
在Visual Studio 中,选择“文件” -> “新建” -> “项目”,然后选择“MFC 应用程序”模板。
在向导中,选择“单文档应用程序”类型,并确保勾选“生成视图”和“支持MFC 功能”选项。
点击完成按钮后,Visual Studio 将自动生成一个基本的MFC应用程序框架。
```cppclass CMyEditView : public CEditView{protected:CMyEditView(); // 隐藏的构造函数DECLARE_DYNCREATE(CMyEditView)``````cppIMPLEMENT_DYNCREATE(CMyEditView, CEditView)CMyEditView::CMyEditView(){}if (!m_wndSplitter.CreateView(0, 0,RUNTIME_CLASS(CMyEditView), CSize(0, 0), pContext) ||!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CListView), CSize(0, 0), pContext)){m_wndSplitter.DestroyWindow();return FALSE;}SetActiveView((CView*)m_wndSplitter.GetPane(0, 0));return TRUE;}通过上述代码,我们创建了一个名为CMyEditView的自定义CEditView类,并将其添加到应用程序的主视图中。
mfc面试知识点总结MFC(Microsoft Foundation Class)是微软公司开发的一套 C++ 库,用于简化 Windows 应用程序的开发。
MFC 提供了一系列的类和函数,用于处理 windows 窗口、消息、事件等,使得开发者能够更快速地完成 Windows 程序的开发。
在 MFC 的面试中,通常会涉及到一些基础知识和高级知识,下面就来总结一些常见的 MFC 面试知识点。
一、MFC 的基本概念1. MFC 是什么?MFC 是 Microsoft Foundation Class 的简称,是微软公司提供的用于简化 Windows 应用程序的开发的一套 C++ 类库。
2. MFC 的特点有哪些?MFC 的特点包括易学易用、功能强大、提供了丰富的类库和工具等。
3. MFC 和 Win32 API 有什么区别?MFC 是建立在 Win32 API 之上的,它封装了 Win32 API,提供了更加高层次的接口,使得开发 Windows 应用程序更加简单和方便。
4. MFC 和 ATL 有什么区别?MFC 是面向传统 Windows 应用程序的开发框架,而 ATL 是为开发高效的 COM 组件而设计的,两者目标不同。
5. MFC 和 .Net 的关系是什么?MFC 是基于 C++ 的框架,而 .Net 是 Microsoft 开发的基于 .Net Framework 的框架,两者属于不同的技术栈。
二、MFC 的基本类和对象1. CWinApp 类CWinApp 是 MFC 应用程序的主类,它代表了一个 MFC 应用程序的实例,通常包含了一个主窗口类对象和一些初始化及清理代码。
2. CFrameWnd 类CFrameWnd 是 MFC 中的主窗口类,它代表了应用程序的主窗口,通常包含了菜单、工具栏等 UI 元素。
3. CView 类CView 是MFC 中的视图类,它用于显示窗口中的用户界面,通常包含了子视图、控件等。
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::CreateNewDocumentreturned 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 wrongCFrameWnd* 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 invisibleif (!bMakeVisible)pDocument->m_bEmbedded = TRUE;if (!pDocument->OnNewDocument())//刚打开时新建的文档。
add by ralf{// user has be alerted to what failed in OnNewDocumentTRACE0("CDocument::OnNewDocument returned FALSE.\n");pFrame->DestroyWindow();return NULL;}// it worked, now bump untitled countm_nUntitledCount++;}else{// open an existing documentCWaitCursor wait;if(!pDocument->OnOpenDocument(lpszPathName))//这里是打开一个文档。
add by ralf{// user has be alerted to what failed in OnOpenDocumentTRACE0("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 attachedASSERT(m_viewList.Find(pView, NULL) == NULL); // must not be in listm_viewList.AddTail(pView);ASSERT(pView->m_pDocument == NULL); // must be un-attachedpView->m_pDocument = this;OnChangedViewList(); // must be the last thing done to the document}CDocument::GetDocTemplate 可获得CMultiDocTemplate;4、CView 他是放在CMDIChildWnd里的,每一个CMDIChildWnd有一个ViewCView::GetDocument可获得与此视相关的CDocumentCView::GetParentFrame() 可获得CMDIChildWnd;通过以上分析可见CWinApp,CMDIChildWnd,CView,CDocument,CMultiDocT emplate之间知道其中一个实例必可知道其他所有几个实例,CWinApp统领全局,任何时候,只要获得CWinApp实例,则所有的文档模板,文档实例,视,Frame窗口均可被枚举出来。