面向对象程序设计报告
——关于Drawcli的程序分析
一、 程序分析
1. 程序简介
Drawcli是一个微软MSDN中附带的一个示例程序,能够进行简单的绘图操作,主要包括16.cpp文件,而每个.cpp文件都对应了一个.h文件。
2. 界面分析
drawcli文件夹中有可执行程序,点击后进入主程序界面,它包含了一般Windows程序通有的一些结构。最上方是标题栏,再往下是菜单栏,翻译成中文,有文件、编辑、查看、绘画、对象、窗口、帮助七个下拉菜单,往下便是工具栏,包括新建、打开、保存、剪切、复制、粘贴、箭头、画图工具、打印、关于、帮助按钮,然后便是图形编辑界面,它是一个独立的窗口,已经给出了等间距的虚线,可以新建、打开、关闭等,以上就是打开程序后大概的界面。
3. 功能分析
该程序是一个简易的绘图程序,新建绘图页面后,可以在菜单栏中Draw的下拉菜单或者工具栏中的绘图工具按钮中选择需要的图形,分别有直线、矩形、圆角矩形、椭圆、点画多边形等画图模式,在编辑区通过鼠标的点击可以画出相应图形,并且可以实现拖动功能。在菜单栏中Object下拉菜单中选择对应功能,可以实现自定义线宽、填充颜、图层移动等功能。同时,在绘图的同时,也可以通过右键点击、工具栏按钮或者快捷键对图形进行复制、剪切、粘贴的操作。在绘图完成之后,用Save按钮或者File下拉菜单中的Save进行用户自定义路径的保存,保存默认格式为.drw。程序中的AboutHelp提供了程序的一些版本信息。
二、 源代码分析
1. 常量
在整个程序中,在很多地方定义了常量,例如形如const CRect & rect的常量引用的定义,形如void AssertValid() const的常量函数的定义,其中引用变量的使用,主要出现在函数自检传
值时,形参的定义,帮助实现了函数自检的地址传输,有利于数据在函数与函数之间的传递。程序中同样存在new运算符,即动态分配存储空间的使用,如CDrawObj* pClone = new CDrawObj(m_position)语句中即通过new申请了一块CDrawObj类大小的内存空间给与CDrawObj指针,与此相对的,运用了delete运算符将所申请的内存空间释放掉。对于作用域运算符::的使用,主要是在对类中已经申明的函数在类外进行定义时用到,如CDrawDoc类中声明的构造函数CDrawDoc()在另一个头文件中进行定义,其定义形式为CDrawDoc::CDrawDoc(),用以指明CDrawDoc()函数的存在区域。
2.
作为面向对象程序,其中含有大量的class类的定义,主要有四个绘图对象类,其中各类的主要说明如下:
2.1 class CDrawObj
其中CdrawObj是父类,不作为具体的绘图类对象存在。
class CDrawObj : public CObject
{
protected:
    DECLARE_SERIAL(CDrawObj);
    CDrawObj();
// Constructors
public:
    CDrawObj(const CRect& position);
// Attributes
    CRect m_position;//对象显示的位置
    CDrawDoc* m_pDocument;//对象存储对应的文档对象指针enum函数
    virtual int GetHandleCount();//获得对象特征点数量
    virtual CPoint GetHandle(int nHandle);//获得对象特针点的位置
    CRect GetHandleRect(int nHandleID, CDrawView* pView);//获得特征点的小矩形
    virtual HCURSOR GetHandleCursor(int nHandle);//获得特征点的鼠标形状
    virtual void SetLineColor(COLORREF color);//设置线条颜
    virtual void SetFillColor(COLORREF color);//设置填充颜
// Operations
    virtual void Draw(CDC* pDC);//纯虚函数,由子对象自己实现
    enum TrackerState { normal, selected, active };//对象的状态(一般、被选、活动)
    virtual void DrawTracker(CDC* pDC, TrackerState state);//绘出特征点
    virtual void MoveTo(const CRect& positon, CDrawView* pView = NULL);//移动到一个新的位置,要求重绘
    virtual int HitTest(CPoint point, CDrawView* pView, BOOL bSelected);//如果对象被选择,返回特征点;如果没有被选择,返回是否在对象内
    virtual BOOL Intersects(const CRect& rect);//判断对象和矩形是否重叠
    virtual void MoveHandleTo(int nHandle, CPoint point, CDrawView* pView = NULL);//通过特征点的移动来改变形状大小
    virtual void OnOpen(CDrawView* pView);//调用OnEditProperties()来修改属性
    virtual void OnEditProperties();//打开修改属性对话框,修改属性
    virtual CDrawObj* Clone(CDrawDoc* pDoc = NULL);//创建一个新的CDrawObj对象,并加入到pDoc
    virtual void Remove();//delete自己
    void Invalidate();//对应的m_pDocument对象更新所有视图
// Implementation
public:
    virtual ~CDrawObj();
    virtual void Serialize(CArchive& ar);//保存数据、读取数据
#ifdef _DEBUG
    void AssertValid();
#endif
    // implementation data
protected:
    BOOL m_bPen;//是否使用笔
    LOGPEN m_logpen;//笔的属性
    BOOL m_bBrush;//是否使用刷子
    LOGBRUSH m_logbrush;//刷子属性
};
2.2 CdrawRect
CdrawObj中已经实现了许多功能,因此在CdrawRect中只是实现了需要修改和增加的函数。
class CDrawRect : public CDrawObj
{
protected:
    DECLARE_SERIAL(CDrawRect);
    CDrawRect();
public:
    CDrawRect(const CRect& position);//添加了对新数据成员的初始化
// Implementation
public:
    virtual void Serialize(CArchive& ar);//添加了对新数据成员操作
    virtual void Draw(CDC* pDC);//根据要求画出每个图形
    virtual int GetHandleCount();//lineroundRectangle特殊处理
    virtual CPoint GetHandle(int nHandle);//lineroundRectangle特殊处理
    virtual HCURSOR GetHandleCursor(int nHandle);//lineroundRectangle特殊处理
    virtual void MoveHandleTo(int nHandle, CPoint point, CDrawView* pView = NULL);//通过特征点来修改大小
    virtual BOOL Intersects(const CRect& rect);//判断与图形是否存在相交
    virtual CDrawObj* Clone(CDrawDoc* pDoc);//Clone一个新对象加入到pDoc
protected:
    enum Shape { rectangle, roundRectangle, ellipse, line };
    Shape m_nShape;//通过枚举变量来标示属于上述四种的哪一种形状
    CPoint m_roundness; // for roundRect corners
    friend class CRectTool;
};
2.2 CDrawPoly
class CDrawPoly;
class CDrawPoly : public CDrawObj
{
protected:
    DECLARE_SERIAL(CDrawPoly);
    CDrawPoly();
public:
    CDrawPoly(const CRect& position);
// Operations
    void AddPoint(const CPoint& point, CDrawView* pView = NULL);//增加新的点
    BOOL RecalcBounds(CDrawView* pView = NULL);//计算这些点的外围大小
// Implementation
public:
    virtual ~CDrawPoly();
    virtual void Serialize(CArchive& ar);
    virtual void Draw(CDC* pDC);
    virtual void MoveTo(const CRect& position, CDrawView* pView = NULL);
    virtual int GetHandleCount();
    virtual CPoint GetHandle(int nHandle);
    virtual HCURSOR GetHandleCursor(int nHandle);
    virtual void MoveHandleTo(int nHandle, CPoint point, CDrawView* pView = NULL);
    virtual BOOL Intersects(const CRect& rect);
    virtual CDrawObj* Clone(CDrawDoc* pDoc);
protected:
    int m_nPoints;
    int m_nAllocPoints;
    CPoint* m_points;
    CDrawPoly* m_pDrawObj;
    friend class CPolyTool;
};
2.3 CDrawOleObj
class CDrawOleObj : public CDrawObj
{
protected:
    DECLARE_SERIAL(CDrawOleObj);
    CDrawOleObj();
public:
    CDrawOleObj(const CRect& position);
// Implementation
public:
    virtual void Serialize(CArchive& ar);
    virtual void Draw(CDC* pDC);
    virtual CDrawObj* Clone(CDrawDoc* pDoc);
    virtual void OnOpen(CDrawView* pView);
    virtual void MoveTo(const CRect& positon, CDrawView* pView = NULL);
    virtual void OnEditProperties();
    virtual void Remove();
    virtual ~CDrawOleObj();
    static BOOL c_bShowItems;
    CDrawItem* m_pClientItem;
    CSize m_extent; // current extent is tracked separate from scaled position
};
另外存在29处自定义的新类,并且所有的类的定义均在头文件中完成。大部分的类的定义中都用到了两种或以上的访问限制符,如CDrawDoc类中用到了publicprotect两种访问限制符。每个类中大都定义了一定数量的构造函数,包含各种类型的构造函数。如类CProperty中含有CProperty( void )函数和CProperty( DWORD dwID, const LPVOID pValue, DWORD dwType )函数,类CRectDlg中含有的构造函数CRectDlg(CWnd* pParent = NULL),其中前者是无参构造函数,后者则为一般构造函数,第三个构造函数则为复制构造函数。与构造函数相对的,类中必然定义了与此对应的析构函数,用于撤销该类,如class CDrawView中的函数virtual ~CDrawView()则为其对应的析构函数。类中还含有大量的一般成员函数,主要执行访问本类数据成员以及完成本类主要功能的任务。如CDrawView类中的void Select(CDrawObj* pObj, BOOL bAdd = FALSE)CDrawDoc类中的CDrawObjList* GetObjects()等函数即是一般成员函数。其中CDrawObjList* GetObjects()函数的主要功能为返回一个地址值。关于this指针的运用,程序中主要将其进行隐式调用,一般在运算符重载,调用成员函数时用到。C++中的静态成员在此程序中亦有用到,如类CDrawOleObj中的static BOOL c_bShowItems;即为静态数据成员。为了在程序中建立类与类之间联系,提高程序执行效率,降低程序中消息在类与类之间传递而带来的开销,各个代码中也包括友元函数和友元类,如类COleDataSource中的friend class COleServerItem,即为友元类。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。