按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
}
void CScribbleView::OnDraw(CDC* pDC)
{
450
…………………………………………………………Page 513……………………………………………………………
第7章 簡單而完整:MFC 骨幹程式
CScribbleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
就这样,我们不费吹灰之力获得了一个多窗口的文字编辑器:
并拥有读写档能力以及预视能力:
451
…………………………………………………………Page 514……………………………………………………………
第篇 湷觥 FC 程式設計
452
…………………………………………………………Page 515……………………………………………………………
4
深入MFC 程 序 设 计
深入湷觥FC
2nd Edition
453
…………………………………………………………Page 516……………………………………………………………
MFC
第篇 深入 程式設計
454
…………………………………………………………Page 517……………………………………………………………
第8章
Document…View 深入探讨
形而上者谓之道,形而下者谓之器。
对于 View 而言,很少有人能够先道而后器。
Document/
完全由AppWziard 代劳做出的Scribble step0,应用程序的整个架构(空壳)都已经建
构起来了,但是Document Document 和VView iew 还空着好几个最重要的函数(都是虚拟函数)等着
你设计其实体。这就像一部汽车外面的车体以及内部的油路电路都装配好了,但还等着
最重要的发动机(引擎)植入,才能够产生动力,开始「有所为」。
我已经在第7章概略介绍了Document/View 以及Document Template ,还有更多的秘密将
在本章揭露。
为什么需要Document…View (形而上)
MFC 之所以为Application Framework ,最重要的一个特征就是它能够将管理资料的程序
码和负责资料显示的程序代码分离开来,这种能力由MFC 的Document/View 提供。
Document/View 是MFC 的基石,了解它,对于有效运用MFC 有极关键的影响。甚至
OLE 复合文件(pound document )都是建筑在Document/View 的基础上呢!
几乎每一个软件都致力于资料的处理,毕竟信息以及资料的管理是计算机技术的主要用途。
把数据管理和显示方法分离开来,需要考虑下列几个议题:
455
…………………………………………………………Page 518……………………………………………………………
第篇 深入 MFC 程式設計
1。 程序的哪一部份拥有资料
2。 程序的哪一部份负责更新资料
3。 如何以多种方式显示资料
4。 如何让资料的更改有一致性
5。 如何储存资料(放到永久储存装置上)
6。 如何管理使用者接口。不同的数据类型可能需要不同的使用者接口,而一个程
序可能管理多种类型的资料。
其实Document / View 不是什么新主意,Xerox PARC 实验室是这种观念的滥觞。它是
Smalltalk 环境中的关键性部份,在那里它被称为Model…View…Controller (MVC )。其
中的Model 就是MFC 的Document ,而Controller 相当于MFC 的Document Template。
回想在没有Application Framework 帮助的时代(并不太久以前),你如何管理资料?只
要程序需要,你就必须想出各种表现资料的方法;你有责任把资料的各种表现方法和资
料本体调解出一种关系出来。100 位程序员,有100 种作法!如果你的程序只处理一种
数据类型,情况还不至于太糟。举个例,字处理软件可以使用巨大的字符串数组,把文
字统统含括进来,并以ASCII 型式显示之,顶多嘛,变换一下字形!
但如果你必须维护一种以上的数据类型,情况又当如何?想象得到,每一种数据类型可
能需要独特的处理方式,于是需要一套功能菜单;每一种数据类型显现在窗口中,应该
有独特的窗口标题以及缩小图标;当资料编辑完毕要存盘,应该有独特的扩展名;登录
在Registry 之中应该有独特的型号。再者,如果你以不同的窗口,不同的显现方式,秀
出一份资料,当资料在某一窗口中被编辑,你应该让每一窗口的资料显像与实际资料之
间常保一致。吧啦吧啦吧啦! K ,繁杂事务不胜枚举。
」
很快地,问题就浮显出来了。程序不仅要做数据管理,更要做「与数据类型相对应的UI
的管理。幸运的是,解决之道亦已浮现,那就是对象导向观念中的Model…View…Controller
(MVC ),也就是MFC 的Document / View 。
456
…………………………………………………………Page 519……………………………………………………………
第8章 Document…View 深入探討
Document
名称有点令人惧怕…Document 令我们想起文字处理软件或电子表格软件中所谓的「文件」。
但,这里的Document 其实就是资料。的确是,不必想得过份复杂。有人用data set 或data
source 来表示它的意义,都不错。
Document 在MFC 的CDocument 里头被具体化。CDocument 本身并无实务贡献,它
只是提供一个空壳。当你开发自己的程序,应该从CDocument 衍生出一个属于自己的
Document 类别,并且在类别中声明一些成员变量,用以承载(容纳)数据。然后再(至
少)改写专门负责文件读写动作的Serialize 函数。事实上,AppWizard 为我们把空壳都
准备好了,以下是Scribble step0 的部份内容:
class CScribbleDoc : public CDocument
{
DECLARE_DYNCREATE(CScribbleDoc)
。。。
virtual void Serialize(CArchive& ar);
DECLARE_MESSAGE_MAP()
};
void CScribbleDoc::Serialize(CArchive& ar)
{
if (ar。IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
由于CDocument 衍生自CObject,所以它就有了CObject 所支持的一切性质,包括执行
时期型别信息(RTTI )、动态生成(Dynamic Creation )、文件读写(Serialization)。又
由于它也衍生自CCmdTarget,所以它可以接收来自菜单或工具栏的WM_MAND 讯
息。
457
…………………………………………………………Page 520……………………………………………………………
第篇 深入 MFC 程式設計
View
View 负责描述(呈现)Document 中的资料。
View 在MFC 的CView 里头被具体化。CView 本身亦无实务贡献,它只是提供一个空
壳。当你开发自己的程序,应该从CView 衍生出一个属于自己的View 类别,并且在
类别中(至少)改写专门负责显示资料的OnDraw 函数(针对屏幕)或OnPrint 函数
(针对打印机)。事实上,AppWizard 为我们把空壳都准备好了,以下是Scribble step0 的
部份内容:
class CScribbleView : public CView
{
DECLARE_DYNCREATE(CScribbleView)
。。。
virtual void OnDraw(CDC* pDC);
DECLARE_MESSAGE_MAP()
};
void CScribbleView::OnDraw(CDC* pDC)
{
CScribbleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
由于CView 衍生自CWnd,所以它可以接收一般Windows 消息(如WM_SIZE、
WM_PAINT 等等),又由于它也衍生自CCmdTarget,所以它可以接收来自菜单或工具
列的WM_MAND 消息。
在传统的C/SDK 程序中,当窗口函数收到WM_PAINT ,我们(程序员)就调用