文档模板和文档/视图的创建过程

    为管理创建文档及其关联的视图和框架窗口的复杂过程,框架使用两个文档模板类:用于 SDI 应用程序的 tabindex="0" keywords="_mfc_CSingleDocTemplate">CSingleDocTemplate 和用于 MDI 应用程序的 tabindex="0" keywords="_mfc_CMultiDocTemplate">CMultiDocTemplate。CSingleDocTemplate 一次只能创建和存储一种类型的一个文档。CMultiDocTemplate 则可以保留一种类型的多个已打开文档的列表。

    某些应用程序支持多种文档类型。例如,应用程序可能支持文本文档和图形文档。在这样的应用程序中,当用户选择“文件”菜单上的“新建”命令时,对话框显示要打开的可能的新文档类型列表。对于每一种支持的文档类型,该应用程序使用不同的文档模板对象。下图阐释了支持两种文档类型并显示若干打开文档的 MDI 应用程序配置。

使用两种文档类型的 MDI 应用程序

    文档模板由应用程序对象创建和维护。在应用程序的 InitInstance 函数执行期间执行的一个主要任务是构造适当类型的一个或多个文档模板。文档模板的创建中对该功能进行了描述。应用程序对象存储指向其模板列表中每一个文档模板的指针,并提供一个添加文档模板的接口。(大家可以去查查CWinApp类)

    如果需要支持两种或更多的文档类型,必须为每种文档类型添加对 tabindex="0" keywords="_mfc_CWinApp.3a3a.AddDocTemplate">AddDocTemplate 的额外调用。

    根据每个文档模板在应用程序文档模板列表中的位置为其注册了一个图标。文档模板的顺序取决于 AddDocTemplate 调用添加它们的顺序。MFC 假定应用程序中的第一个图标资源是应用程序图标,下一个图标资源是第一个文档图标,依此类推。

    例如,某个文档模板是应用程序的三个文档模板中的第三个。如果应用程序的索引 3 处有图标资源,则该图标将用于此文档模板。如果没有,则位于索引 0 处的图标将用作默认图标。

文档模板的创建

    当为响应“文件”菜单中的“新建”或“打开”命令而创建新文档时,文档模板还创建一个用于查看该文档的新框架窗口

文档模板构造函数指定模板将可创建的文档、窗口和视图的类型。这由传递到文档模板构造函数的参数确定。下列代码阐释了为示例应用程序创建 tabindex="0" keywords="_mfc_CMultiDocTemplate">CMultiDocTemplate 的过程:

AddDocTemplate( new CMultiDocTemplate( IDR_SCRIBTYPE,
          RUNTIME_CLASS( CScribDoc ),
          RUNTIME_CLASS( CMDIChildWnd ),
          RUNTIME_CLASS( CScribView ) ) );

    指向新的 CMultiDocTemplate 对象的指针用作 tabindex="0" keywords="_mfc_CWinApp.3a3a.AddDocTemplate">AddDocTemplate 的参数。CMultiDocTemplate 构造函数的参数包括与文档类型的菜单和快捷键关联的资源 ID 以及 tabindex="0" keywords="_mfc_RUNTIME_CLASS">RUNTIME_CLASS 宏的三次使用RUNTIME_CLASS 对被指定为其参数的 C++ 类返回 tabindex="0" keywords="_mfc_CRuntimeClass">CRuntimeClass 对象。传递给文档模板构造函数的三个 CRuntimeClass 对象提供在文档创建过程中创建指定类的新对象所需要的信息。此示例显示了一个文档模板的创建过程,该文档模板创建附加了 CScribView 对象的 CScribDoc 对象。视图框架由标准的 MDI 子框架窗口构造。

文档/视图的创建

    框架提供“文件”菜单上的“新建”和“打开”命令(不止这些)的实现。新文档及其关联视图和框架窗口的创建应用程序对象、文档模板、新创建的文档和新创建的框架窗口相互合作的结果。下表总结了各对象创建的内容。

对象创建者

创建者创建
     应用程序对象                                  文档模板
     文档模板                                  文档
     文档模板                                  框架窗口
     框架窗口                                  视图

MFC 对象之间的关系

    为有助于正确处理文档/视图的创建过程,请考虑一个正在运行的程序:文档、用于包含视图的框架窗口以及与文档关联的视图。

  • 文档保留该文档的视图列表和指向创建该文档的文档模板的指针
  • 视图保留指向其文档的指针,并充当其父框架窗口的子级
  • 文档框架窗口保留指向其当前活动视图的指针
  • 文档模板保留其已打开文档的列表
  • 应用程序保留其文档模板的列表
  • Windows 跟踪所有打开的窗口,以便可以向这些窗口发送消息。

    这些关系都是在文档/视图的创建期间建立的。下表显示了正在运行的程序中的对象如何访问其他对象。任何对象均可通过调用全局函数 tabindex="0" keywords="_mfc_AfxGetApp">AfxGetApp 获取指向应用程序对象的指针。

获得对应用程序中其他对象的访问

从该对象如何访问其他对象
文档使用 tabindex="0" keywords="_mfc_CDocument.3a3a.GetFirstViewPosition">GetFirstViewPosition 和 tabindex="0" keywords="_mfc_CDocument.3a3a.GetNextView">GetNextView 访问文档的视图列表。

调用 tabindex="0" keywords="_mfc_CDocument.3a3a.GetDocTemplate">GetDocTemplate 获取文档模板。

视图调用 tabindex="0" keywords="_mfc_CView.3a3a.GetDocument">GetDocument 获取文档。

调用 tabindex="0" keywords="_mfc_CWnd.3a3a.GetParentFrame">GetParentFrame 获取框架窗口。

文档框架窗口调用 tabindex="0" keywords="_mfc_CFrameWnd.3a3a.GetActiveView">GetActiveView 获取当前视图。

调用 tabindex="0" keywords="_mfc_CFrameWnd.3a3a.GetActiveDocument">GetActiveDocument 获取附加到当前视图的文档。

MDI 框架窗口调用 tabindex="0" keywords="_mfc_CMDIFrameWnd.3a3a.MDIGetActive">MDIGetActive 获取当前活动的 tabindex="0" keywords="_MFC_CMDIChildWnd">CMDIChildWnd

    框架窗口通常有一个视图,但有时(如在拆分窗口中)同一个框架窗口包含多个视图。框架窗口保留指向当前活动视图的指针;每当激活另一个视图时都更新该指针。

注意   指向主框架窗口的指针存储在应用程序对象的 tabindex="0" keywords="_mfc_CWinThread.3a3a.m_pMainWnd"> m_pMainWnd 成员变量中。 CWinAppInitInstance 成员函数重写中的 OnFileNew 调用为您设置 m_pMainWnd。如果不调用 OnFileNew,则必须亲自在 InitInstance 中设置该变量的值。(如果命令行上有 /Embedding,则 SDI COM 组件(服务器)应用程序可能不设置该变量。)注意, m_pMainWnd 现在已成为 CWinThread 类的成员,而不是 CWinApp 类的成员。

创建新文档、窗口和视图

    下图概述了文档、视图和框架窗口的创建过程。着重探讨参与对象的其他文章将提供进一步的详细信息。

    该过程完成后,合作对象仍存在并存储指向彼此的指针。下图显示了对象的创建顺序。可以遵循这几个图的顺序。

文档的创建顺序

框架窗口的创建顺序

视图的创建顺序

    有关框架如何初始化新文档、视图和框架窗口对象的信息,请参见“MFC 库参考”中的 tabindex="0" keywords="_MFC_CDocument">CDocument、 tabindex="0" keywords="_MFC_CView">CView、 tabindex="0" keywords="_MFC_CFrameWnd">CFrameWnd、 tabindex="0" keywords="_MFC_CMDIFrameWnd">CMDIFrameWnd 和 tabindex="0" keywords="_MFC_CMDIChildWnd">CMDIChildWnd 类。

初始化您自己向这些类添加的内容

    以上各图还表明了在何处可以重写成员函数以初始化应用程序的对象。视图类中的 OnInitialUpdate 重写是初始化视图的最佳位置。创建了框架窗口并将框架窗口中的视图附加到其文档后,将立即发生 OnInitialUpdate 调用。例如,如果视图为滚动视图(从 CScrollView 而不是从 CView 派生),则应在 OnInitialUpdate 重写中根据文档大小设置视图大小。( tabindex="0" keywords="_mfc_CScrollView">CScrollView 类的说明中对此过程进行了描述。)可以重写 CDocument 成员函数 OnNewDocumentOnOpenDocument 以提供应用程序特定的文档初始化。通常必须重写这两个函数,因为可以用两种方法创建文档。

大多数情况下,重写应调用基类版本。有关更多信息,请参见“MFC 库参考”中 tabindex="0" keywords="_MFC_CDocument">CDocument、 tabindex="0" keywords="_MFC_CView">CView、 tabindex="0" keywords="_MFC_CFrameWnd">CFrameWnd 和 tabindex="0" keywords="_MFC_CWinApp">CWinApp 类的命名成员函数。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值