4
具体完成,应用程序的数据显示或屏幕重绘专门由视图类的 OnDraw 函数负责具体完成。如
果在二维图形基类 CShape定义中把负责数据保存的成员函数 Serialize 和负责图形绘制的成员
函数 Drawing 说明为虚函数,在派生类即具体的二维图形类定义中只对 Serialize 和 Drawing
的函数内容重新定义,保留其函数名、返回值类型和参数(包括类型和个数)不变,用一个
指向基类 CShape 的指针访问虚函数 Serialize 和 Drawing ,就可以实现画图程序具有不同数据
类型和个数的二维图形对象的保存,以及根据保存的数据区别不同图形对象在屏幕上重新绘
制出来。
在 MFC 类库中, 集合类是专门用于数据保存的。 集合类又分为数组类、链表类和映射类
(也称数据字典类) 。它们都能适用于各种数据类型,如 BYTE 、WORD 、int 、float 、String 、
对象地址或对象指针等。从前面的分析可以看出,在画图程序中需要保存的数据是各二维图
形对象的地址, 因此可以选用数组类的 CObArray/CPtrArray 或链表类的 CObList/CPtrList 。在
MFC 中,数组是采用动态数组,链表是采用双向链表。数组和链表对存取数据的操作各有优
缺点。在本设计中,可以简单地选用 CObArray 来存放二维图形对象的地址。
1.5 设计思路
综上所述,可以总结设计思路如下:
首先定义一个二维图形的基类 CShape,它包含颜色、线型和线宽 3 个共有的数据成员,
定义串行化 Serialize 和绘图 Drawing 两个虚函数,然后从 CShape 类派生上述各二维图形类:
CLine 、CCircle 、CEllipse 、CRectangle、CBezier 和 CPolygon 等,在每一个二维图形类中定义
自己的几何数据,定义构造函数以便生产各自的图形对象,重载 Serialize 和 Drawing 函数,
以实现各自不同的数据序列化和屏幕重绘。
其次,在文档类中定义一个可以保存各二维图形对象地址的 CObArray 数组,并定义 3
个操作该 CObArray 数组的文档类成员函数 AddShape、GetShape、GetShapeNumber。视图类
是使用这些函数的重要用户。 在文档类的 Serialize 函数中简单地调用 CObArray.Serialize 函数,
而 CObArray 的 Serialize 函数又依据所存放的对象指针类型调用相应类对象的 Serialize 函数,
完成实际的数据读写操作,从而实现了二维图形对象不同数据类型和个数的序列化。
再次,在用鼠标进行屏幕绘图的鼠标消息处理函数代码中,在 OnLButtonUp 函数内,对
不同的二维图形对象,分别调用各自的构造函数生成二维图形对象,再把该二维图形对象地
址用 AddShape 函数保存在 CObArray 数组中,以矩形为例,如下所示:
if(CurrentDraw= =DRAW_RECTANGLE)
{
pShape=new CRectangle(m_pOrigin, point, m_pWidth, m_pStyle, m_pColor);
}
… //其他二维对象的相应语句段
pDoc->AddShape(pShape);
其中, pDoc 为指向文档的指针; m_pWidth 、m_pStyle 和 m_pColor 为视图类的数据成员,
分别代表二维图形的线宽、线型和颜色。
最后,在 OnDraw 成员函数中定义一个基类 CShape 的指针变量 pShape,采用循环方法遍
历 CObArray 数组中的所有元素, 在 for 循环内把调用 GetShape 函数获得的二维图形对象的地
址赋给 pShape,用 pShape 调用虚函数 Drawing ,就可以实现虚函数的多态性,即相同的
pShape->Drawing(pDC) 函数调用语句,由于 pShape 所指向的对象不同,实现了调用不同
Drawing 函数体内容的目的。从而在屏幕上绘出不同的二维图形。
实现不同二维图形对象的数据保存和屏幕重绘的过程可以概括为:在视图类中利用鼠标
消息处理函数用鼠标绘出二维图形,获得数据;调用各自的构造函数生成二维图形对象,调
评论0
最新资源