2024年4月19日发(作者:)

SDI、MDI和拆分窗口

文档、视图和单文档界面

一、文档/视图结构的程序

文档/视图结构的程序不同于传统的MFC应用程序,传统的MFC应用程序体

系主要包括两个对象:应用程序对象和主窗口对象,应用程序对象的主要任务是创

建 程序的主窗口而主窗口对象的任务主要是用来和程序用户进行交互操作。文档/

视图体系的MFC应用程序包括了应用程序对象、框架窗口对象、视图对象和文档

对 象四个方面。应用程序对象和传统MFC程序当中的应用程序对象完成类似的任

务:创建其余的三个对象;而框架窗口对象创建了程序窗口的框架;视图对象是一

个 覆盖在框架窗口对象的客户区上方的一个子窗口,在这个子窗口当中程序实现与

用户的交互;文档对象主要是用来实现保存程序数据的功能。在这个体系当中视图

对 象和文档对象通过文档的公有成员函数实现数据的交互。

使用文档/视图体系的好处在于通过VC所提供的应用程序向导我们可以方便

的创建一个应用程序,并且向导将为我们完成程序当中内存数据和磁盘数据交互的

过程,我们只需要为整个应用程序添加核心的代码就可以获得一个带有磁盘IO的

强大应用程序。

二、文档

文档提供了应用程序数据操作的集合,在这个类当中我们封装所有程序所需要

的数据,并且为这些数据的修改和读取提供公有成员函数供视图对象和文档对象交

互使用。

在文档类当中我们经常需要覆盖的基类成员函数有:OnNewDocument()这个成

员函数提供了创建新文档时文档对象的数据初始化过程;之所以不使用 文档对象的

构造函数来完成这个功能是因为文档对象仅仅在应用程序创建之初才被创建并调用

构造函数。Serialize(CArchive& ar)这个函数提供了文档数据与磁盘IO的交互功能。

文档类当中我们经常使用的基类成员函数有SetModifiedFlag(BOOL)这个函数

设置一个修改标志,如果在文档被关闭的时候这个标志为 TRUE那么程序会提示用

户保存数据;另一个函数是UpdateAllViews(CView *)这个函数通知与文档对象相关

联的视图对象刷新他的显示。

三、视图

视图对象提供了程序与用户的交互,他通过文档对象的公用成员函数实现程序

内部数据的交互。

在视图对象当中我们经常要覆盖的成员函数是OnDraw(CDC *)这个函数用来

实现重画视图对象表面。另外InitialDraw成员函数跟文档类当中的OnNewDocument

成员函数类似,尽当新文档被加载时 才被调用,他完成加载新文档时视图上的绘图

工作。

在视图对象当中我们经常使用的基类成员函数是GetDocument()这个函数返回

一个与改视图对象相关联的文档对象指针。

三、消息传递

根据Windows操作系统的规定,操作系统发送的消息只能由程序的窗口接收。但是

在MFC体系特别是基于窗口/视图结构体系的应用程序中程序的每个模块 包括应

用程序类、框架窗口类、视图类、文档类都能够接受由操作系统发送而来的消息并

进行处理。这并不是MFC体系获得了操作系统的例外而是MFC体系底层 通过一

系列的代码实现了一种所谓的消息传递机制。

所谓消息传递机制指的就是当属于应用程序的消息由操作系统传递而来的时候,活

动视图是操作系统消息传递机制所传递的窗口类。视图类首先查找其自身对于该消

息有没有对应的消息处理程序,如果没有则传递给文档类,文档类如果不能处理该

消息则传递给文档模板,按照上面所描述的过程,消息将按照活动视图-> 文档->

文档模板->框架窗口->应用程序对象->::DefWindowProc的流程进行传递。当消息在

这个流程的某个节点 上得到处理那么消息传递的过程将被终止。

需要注意的是消息传递机制传递的是命令消息,也就是说仅有COMMAND消息和

UPDATE_COMMAND_UI消息将通过这个机制被传递;而其他的消息不会被传递,

处理其他消息遵循消息在哪里发生就在哪里处理的规则。

SDI

一、文档/视图结构概述

文档/视图结构的MFC应用程序通过将程序的界面和程序的数据封装在两个

类当中实现了程序逻辑的简化。而视图类和文档类之间通过成员函数实现了信息的

双向 通信。文档/视图应用程序有两种大的分类:SDI和MDI程序。SDI是一种单

文档的应用程序,这种程序的构造在上一章中已经有所描述,这章主要讲述 SDI

结构当中两种特殊的视图类;MDI应用程序是一种多文档应用程序。

二、SDI应用程序

lView视图类

这个视图类不同于CView视图类他提供了横向和纵向的两个滚动条。这个视

图类提出了逻辑空间和物理空间两个概念,在程序窗口表面能够被看到的部分我们

称 为物理空间,而视图类可以定义一个逻辑空间,当物理空间小于逻辑空间时窗口

上会自动出现滚动条。需要注意的是无论滚动条当前所处的位置在哪里逻辑空间的

坐 标都以当前窗口左上角位置为(0,0)点。

实现这个视图类我们要做的是在视图类的OnInitialUpdate成员函数当中通过

调用SetScrollSizes成员函数来设置逻辑空间的大小, 而在OnDraw成员函数当中

我们根据逻辑空间的大小来进行绘图。在CScrollView视图类当中响应鼠标事件时,

我们必须通过调用DpToLp函数 将鼠标坐标转换为逻辑空间坐标

iew视图类

这个视图类提供了一个实现Internet浏览器的简便方法,在这个类当中调用

Navigate成员函数能够简单的使视图窗口当中显示成员函数参数当中所提供URL的

网页。

iew视图类

这个视图类根据CTreeList通用控件封装而来。这个视图类提供了树列表的视

图,通过这个视图类能够清晰的表示数据间的层次关系。由于这个视图类是从

CTreeList通用控件封装而来,因此这个视图类的核心是封装在类当中的CTreeList

对象,我们可以通过调用GetTreeCtrl()函数来 获取这个对象,并且调用这个对象的

方法。

CTreeView视图类提供了多种样式参数,我们可以通过在视图类的

PreCreateWindow成员函数当中使用CREATESTRUCT对象的 style字段使用按位与