绘图 单文档应用实例

文档/视图结构开发实例

 

    下面在单文档应用程序框架的基础上,逐步开发一个典型的文档/视图结构的绘图程序,通过程序的具体开发,说明有关视图对象和文档对象的具体开发过程和方法。

 

一、实例说明

       本实例在单文档应用程序框架的基础上,进行开发,最终实现一个简单的屏幕绘图程序。首先从最基本的视图绘图处理开始,逐渐加入文档的处理、数据的序列化、实现滚动窗口等功能。   

 

二、视图的处理

       要在屏幕进行绘图操作,必须在视图类中实现。即读取用户的鼠标输入以及绘图操作都必须在视图类中完成。本节将结合实例,讲解与视图类实现有关的资源及编程方法。

       绘图操作的实现过程为:当用户在窗口客户区按下鼠标左键,并移动鼠标时,用连线的方式绘制鼠标经过的点,即所绘制的图形为鼠标的移动轨迹。而当用户释放左键时,停止绘图。实现过程如下。

 

1在视图类中定义成员变量 

在CSDocDemoView.h中添加成员变量:

   VC计划之三 <wbr>绘图 <wbr>单文档应用实例
 

在CSDocDemoView.cpp中构造函数中初始化成员变量:

 

VC计划之三 <wbr>绘图 <wbr>单文档应用实例

全局函数AfxGetApp( ) 回指向应用程序对象的一个指针,通过该指针调用CWinApp类成员函数LoadStandardCursor( )载入系统定义的光标资源。

 

2 添加鼠标消息映射及消息处理函数

OnLButtonDown( );

OnLButtonUp( );

OnMouseMove( );

例:

2.1 消息处理函数声明

VC计划之三 <wbr>绘图 <wbr>单文档应用实例

2.2添加消息映射

VC计划之三 <wbr>绘图 <wbr>单文档应用实例

2.3完善消息处理函数

VC计划之三 <wbr>绘图 <wbr>单文档应用实例

3添加鼠标消息处理函数代码,实现绘图操作

在CSDocDemoView 类的资源文件中,添加鼠标消息处理函数实现代码,如下:

 VC计划之三 <wbr>绘图 <wbr>单文档应用实例
 

 

 

VC计划之三 <wbr>绘图 <wbr>单文档应用实例

 

4设置视图窗口的特性 (非必需)

在视图类的PreCreatWindow函数中,可以实现视图窗口的特性。CSDocDemoView类已经自动重载了该函数,在其中添加代码实现视图的光标为箭头光标,窗口背景为浅灰色,代码如下:

 (自生成时,本虚函数已存在,只等重载。)

 

 VC计划之三 <wbr>绘图 <wbr>单文档应用实例
 

5 修改程序窗口标题栏

       打开String Table资源,选择ID为IDR_MAINFRAME的字符串,双击它,修改之。

VC计划之三 <wbr>绘图 <wbr>单文档应用实例
 

 

6 编译运行

按F5编译程序,即可以利用鼠标在客户窗口中进行绘图操作,如下图示。

VC计划之三 <wbr>绘图 <wbr>单文档应用实例

可见,仅在视图类中就可以实现客户窗口的绘图操作。然而这种绘图是很不稳定的,当窗口大小改变或覆盖(ugl)引起重绘时,所绘图形就会消失。而解决这个问题,可以将图形信息保存在文档对象中,当窗口重绘时,根据这些保存的信息重新绘制。

 

 

三、文档的处理

       本节将在上节的程序的基础上,在文档类中通过一个数组保存视图窗口所绘制的线条坐标,当窗口重绘时,能够再现已绘图形。另外,还给程序添加了一个“撤销”菜单命令项,能够撤销前一步的绘图操作。下面详细介绍实现过程。

1.       创建类CLineDraw存放线条

在工程中,添加一个派生自CObject类的新类CLineDraw,用于实现与图形线条有关的操作。头文件“LineDraw.h”的实现如下:

 

实现文件内容如下:

 

 VC计划之三 <wbr>绘图 <wbr>单文档应用实例
VC计划之三 <wbr>绘图 <wbr>单文档应用实例
 

2 在文档类CSDocDemoDoc中,实现存储线条坐标

在文档类CSDocDemoDoc的头文件中定义数组对象和操作CLineDraw对象的相关函数。如下:

VC计划之三 <wbr>绘图 <wbr>单文档应用实例
在文档类CSDocDemoDoc的实现文件中定义函数,如下:

VC计划之三 <wbr>绘图 <wbr>单文档应用实例

3 在视图中,绘制直线的同时,将直线保存到数组中

由前面介绍,绘制直线的操作是在OnMouseMove()函数中实现的,这里将OnMouseMove( )代码修改如下:

 

 VC计划之三 <wbr>绘图 <wbr>单文档应用实例
 

4 重写视图类中的OnDraw( )函数

当视图窗口进重绘时,它会调用视图类中的OnDraw( )函数,因此需要在OnDraw( )函数中,根据文档类中数组对象何保存的数据恢复直线。代码如下:

(注意,此函数在生成时就已有,直接在其内添加即可!)

VC计划之三 <wbr>绘图 <wbr>单文档应用实例
 

 

5 文档数据的删除

当初始化新文档之前,如通过“文件”->“新建”菜单命令项创建一个新的文档,必须删除存放在当前文档中的数据。这就需要在文档类中重载函数DeleteContents(  )来实现。可以通过ClassWixard在文档类中重载DeleteContents(  ),实现代码如下:

VC计划之三 <wbr>绘图 <wbr>单文档应用实例

6 添加“撤消”菜单命令项入处理

在“Resource View”选项中,单击“Menu”资源中的“IDR_MAINFRAME”菜单资源,在其中添加“编辑”主菜单项,在其下添加“撤消”菜单命令项,ID设置为“ID_UNDO”,其余属性项采用默认置。如下所示:

 

 VC计划之三 <wbr>绘图 <wbr>单文档应用实例
 

采用ClassWizard,在文档类SDocDemoDoc中,分别为菜单项添加COMMAND 的UPDATE_COMMAND_UI消息处理函数 OnUndo(  ) 和 OnUpdateUndo(),实现如下:

VC计划之三 <wbr>绘图 <wbr>单文档应用实例
VC计划之三 <wbr>绘图 <wbr>单文档应用实例
7 编译运行

由于文档中存放有所绘制的直线,窗口缩放和移动时,视图始终显示所绘制的图形,同时还可以通过“撤消”菜单命令项取消最后一步的绘图操作,运行结果如下图:

VC计划之三 <wbr>绘图 <wbr>单文档应用实例

由于每移动一下鼠标,就会记录下一小段直线对象,所以需多次撤消,才能明显看出。

更改点,每次鼠标左键松开时,再加一标识对象,当撤消时,一次撤消到此标识对象为止。

你可能感兴趣的:(MFC,绘图)