默认情况下,“MFC 应用程序向导”用文档类和视图类创建应用程序主干。MFC 将数据管理分成这两类。
文档存储数据和管理数据的打印,并协调更新多个数据视图。
视图显示数据并管理用户与数据之间的交互,包括选择和编辑。
尽管可以容易地重写或者忽略文档/视图的分离,但在大多数情况下都有颇具说服力的理由需要遵循此模型。最有说服力的理由之一是在需要同一文档的多个视图时,例如同时需要电子数据表格和图表视图。文档/视图模型使一个单独的视图对象得以表示每个数据视图,而对所有视图通用的代码(例如计算引擎)可以驻留在文档中。文档还承担在每次数据更改时更新所有视图的任务。
MFC 文档/视图结构使支持多视图、多文档类型、拆分窗口和其他有价值的用户界面功能变得容易。
对用户和您(程序员)而言,MFC 框架中可见性最大的部分就是文档和视图。在用框架开发应用程序的工作中,编写文档和视图类占了大部分。本文章主要描述:
- 文档和视图的用途以及它们如何在框架内进行交互。
- 为实现它们所必须做的工作。
文档/视图的核心是四个关键类:
CDocument(或 COleDocument)类支持用于存储或控制程序数据的对象,并为程序员定义的文档类提供基本功能。文档表示数据单元,用户一般用“文件”菜单上的“打开”命令打开它,并用“文件”菜单上的“保存”命令保存它。
CView(或它的许多派生类之一)为程序员定义的视图类提供基本功能。视图被附加到文档并在文档和用户之间充当中介:视图在屏幕上呈现文档的图像并将用户输入解释为对文档的操作。视图还为打印和打印预览呈现图像。
CFrameWnd(或其变体之一)支持在文档的一个或多个视图周围提供框架的对象。
CDocTemplate(或 CSingleDocTemplate 或 CMultiDocTemplate)支持一个对象,该对象协调给定类型的一个或多个现有文档并对创建该类型的正确文档、视图和框架窗口对象进行管理。
下图显示了文档及其视图之间的关系。
文档和视图
类库中的文档/视图实现将数据本身同其显示分开,并且与用户对数据的操作分离。对数据的所有更改都通过文档类管理。视图调用此接口来访问和更新数据。
文档、与文档关联的视图以及给视图加框架的框架窗口都用文档模板创建。文档模板负责创建和管理属于同一种文档类型的所有文档。
文档/视图结构的优点
使用 MFC 文档/视图结构的主要优点是该结构能够很好地支持同一文档的多个视图。(如果不需要多个视图并且文档/视图的少量系统开销在应用程序中过多,则可以避免该结构。文档/视图结构的替换选项。)
假设您的应用程序允许用户查看电子数据表格格式或图表格式的数字数据。用户可能要同时在电子数据表格中和由数据产生的图表中查看原始数据。将这些单独的视图显示在单独的框架窗口中或单个窗口的拆分窗格中。现在假设用户可以在电子数据表格中编辑数据,同时在图表中看到即时反映的更改。
在 MFC 中,电子表格视图和图表视图基于从 CView 派生的不同类。两个视图与单个文档对象关联。文档存储数据(或者可能从数据库获取数据)。两个视图都访问该文档并显示它们从文档检索的数据。
当用户更新其中一个视图时,该视图对象调用 CDocument::UpdateAllViews。该函数通知所有文档视图,每个视图使用文档中的最新数据更新自身。单一调用 UpdateAllViews 对不同的视图进行同步处理。
若不将数据和视图分离,特别是视图本身存储数据时,此方案很难用代码编写。而使用文档/视图模型,则很容易。框架将为您完成大部分的协调工作。
我的想法
文档/视图结构就是把数据本身与对数据的显示分离的一种做法。用MFC创建应用程序时主要表现为创建了视图类和文档类。同一个文档可以支持多个视图同步更新。
在做电子表格数据存储的时候一个突出的问题就是数据与带有格式的数据的区分。比如说某单元格中的数据是10,但是在用户看来应该为10mm,那么就不能够直接将单元格中的数据读取出来进行处理。在处理之前必须首先对数据进行过滤得到其实际所表达的含义。同样地,如果一个单元格中的数据是3.1415926,用户设置了不显示小数点后的数字,则该单元格中的数据应该变为3,而后用户希望更改其设置,并设置为显示小数点后的2位,如果直接从单元格中读取,势必会造成数据的丢失。那么就要求在用户更改设置时做一个缓冲处理。即在更改精度的时候不改变实际的数据,只改变关于这个数据的精度的标记,只有在用户通过单元格更改了数据的时候才对其实际数据进行修改。