简易画图板设计报告.doc

上传人:wux****ua 文档编号:9054496 上传时间:2020-04-02 格式:DOC 页数:16 大小:110KB
返回 下载 相关 举报
简易画图板设计报告.doc_第1页
第1页 / 共16页
简易画图板设计报告.doc_第2页
第2页 / 共16页
简易画图板设计报告.doc_第3页
第3页 / 共16页
点击查看更多>>
资源描述
设计报告:Graphic简易画图板 -韩伟 谢程焜 肖越 周峰 电科二班1设计目的设计一个单文档类型的MFC AppWizard (exe)工程,工程取名为:Graphic。此程序将实现简单的绘图功能,包括点、直线、矩形、椭圆、扇形和连续线的绘制。并且能实现绘图的控制,包括线宽、线型和颜色的设置,图形的保存和打开以及笔刷的使用。2 总体设计设计图如图6简易画图板文件绘图笔刷打开保存点直线矩形椭圆扇形连续线设置颜色简单笔刷位图笔刷透明笔刷线宽线型图63详细设计首先,新建一个单文档类型的MFC AppWizard (exe)工程,工程取名为:Graphic。为此程序添加一个子菜单,菜单名称为“绘图”,并为其添加六个菜单项,分别用来控制不同图形的绘制。当用户选择其中的一个菜单项后,程序将按照当前的选择进行相应图形的绘制。添加的六个菜单项的ID及名称如表1所示。然后分别为这六个菜单项添加命令响应,本程序让视类(CGraphicView)对这些菜单命令进行响应,这六个响应函数的名称分别如表1所示。表1添加的菜单项菜单项ID菜单项名称菜单项命令响应函数IDM_DOT点OnDotIDM_LINE直线OnLineIDM-RECTANGLE矩形OnRectangleIDM_ELLIPSE椭圆OnEllipseIDM_SHANXING扇形OnShanxingIDM_LIANXUXIAN连续线OnLianxuxian在程序运行以后,当用户单击某个菜单项时,应该把用户的选择保存起来,以便随后的绘图操作使用。因此在CGraphicView类中添加一个私有变量m_nDrawType;用来保存用户的选择,该变量的定义如下所述:private: UINT m_nDrawType;接着,在视类的构造函数中将此变量初始化为0,程序代码如下:CGraphicView:CGraphicView()/ TODO: add construction code here m_nDrawType=0;利用switch/case语句,来分别完成相应图形的绘制。当用户选择【绘图】菜单下的不同子菜单项时,将变量m_nDrawType设置为不同的值。程序代码如下:void CGraphicView:OnDot() / TODO: Add your command handler code herem_nDrawType=1;void CGraphicView:OnLine() / TODO: Add your command handler code herem_nDrawType=2;void CGraphicView:OnRectangle() / TODO: Add your command handler code herem_nDrawType=3;void CGraphicView:OnEllipse() / TODO: Add your command handler code herem_nDrawType=4;void CGraphicView:OnShanxing() / TODO: Add your command handler code herem_nDrawType=5;void CGraphicView:OnLianxuxian() / TODO: Add your command handler code herem_nDrawType=6;3.1点、直线、矩形、椭圆的绘制 (周峰 谢程焜)对于直线、矩形和椭圆,在绘制时都可有两点来确定其图形。当鼠标左击时得到一个点,当鼠标左键松开时得到另外一个点。为视类CGraphicView分别捕获鼠标左键按下和弹起这两个消息。另外当鼠标左键按下时,需要将鼠标当前按下点保存,因此我们为CGraphicView再增加一个CPoint类型的私有成员变量:m_ptOrigin,在视类的构造函数中将此变量初始化为0。在鼠标按下消息响应函数中,保存该点,代码如下:void CGraphicView:OnLButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultm_ptOrigin=point; /保存鼠标按下得到点,也是绘制一个点CView:OnLButtonDown(nFlags, point);在鼠标左键弹起消息响应函数中实现绘图,代码如下:void CGraphicView:OnLButtonUp(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call default/创建并获得设备描述CClientDC dc(this); switch (m_nDrawType)case 1:dc.SetPixel(point,RGB(255,0,0)); /*绘制点*/break;case 2: /*绘制直线*/dc.MoveTo(m_ptOrigin);/*调用MoveTo函数移动到原点*/dc.LineTo(point);/*调用LineTo函数绘制到终点。*/break;case 3: /*绘制矩形*/ dc.Rectangle(CRect(m_ptOrigin,point);break;case 4: /*绘制椭圆*/dc.Ellipse(CRect(m_ptOrigin,point);break;CView:OnLButtonUp(nFlags, point);在上述程序中,设置一个点,用到的函数是SetPixel,这也是CDC类的一个成员方法,该函数的生命形式如下:COLORREF SetPixel (POINT point,COLORREF crColor);该函数是在指定的点设置一个像素。其中第一个参数(point)是指定的点,第二个参数(crColor)是指定的颜色。在程序中设定的颜色在系统颜色表中可能不存在,但系统会选择一种和这个颜色最接近的颜色。RGB是一个宏,它有三个参数,分别代表红、绿、蓝三种颜色的值。这三个参数BYTE类型,取值范围为0255。RGB(0,0,0)是黑色,RGB(255,255,255)是白色,将这三个分量设置成为0255之间的任意值,从而得到各种不同的颜色。这里的RGB(255,0,0)是红色。绘制直线时,首先调用MoveTo函数移动到原点,然后调用LineTo函数绘制到终点。绘制矩形时使用Rectangle函数,该函数声明形式为:BOOL Rectangle (LPCRECT lpRect);该函数有一个指向Crect对象的参数,后者可以利用两个点来构造。需要注意的是该函数需要的是指向Crect对象的指针,而上述代码中传递的却是Crect对象,但运行编译时也能成功通过,运行时也不会报错,这是为什么呢?我们知道C系列的语言都是强类型语言,如果类型不匹配的话,需要进行强制类型转换。但这里为什么没有进行这样的强制类型转换程序也可以通过呢?实际上,Crect类提供了这样一个成员函数:重载LPCRECT操作符,其作用是将Crect转换为LPCRECT类型。因此,当在程序中给Rectangle函数的参数赋值时,如果它发现该参数是一个Crect对象,它就会隐式地调用LPCRECT操作符,将Crect类型的对象转换为LPRECT类型。因此,在给函数传递参数时,如果我们看到的传递的数值类型和所需要的类型不匹配,但编译和运行都正确的情况时,就要想想这其中的缘由了。当然,有的情况下可能是这些类型之间本来就可以互相转换,例如short类型和int类型。但是参数是对象类的话,就要考虑了,它选择的对象的构造方法进行的隐式转换,还是有其他重载的操作符。当用户选择椭圆菜单项时,调用Ellipes函数绘制一个椭圆。3.2连续线和扇形的绘制(周峰 谢程焜)Windows系统为我们提供了一个画图程序,在该程序中,利用画笔可以绘制连续的线条,下面我们设计绘制连续线和扇形。为了绘制连续的线条,首先要得到线条的起点,这在前面已经实现。然后需要捕获鼠标移动过程中的每一个点,这可以通过捕获鼠标移动消息(WM_MOUSEMOVE)来实现。在此消息响应函数中,在依次捕获的各个点之间绘制一条条非常短的线段,从而就可以绘制出一条连续的线条。遵照这一思路,我们开始增加程序的功能。首先为视类增加鼠标移动消息(WM_MOUSEMOVE)的响应函数(OnMouseMove)。这样,只要鼠标在应用程序窗口中移动时都会进入到这个消息响应函数中。但这并不是我们所期望的,我们希望在鼠标左键按下后开始绘图。因此,我们需要有一个变量来表示鼠标左键是否按下这一状态,然后在鼠标移动消息响应函数中对这一变量进行判断。当此变量为真,即鼠标左键已经按下去,我们开始绘图。于是,为视类添加一个BOOL型的私有变量m_bDraw,当鼠标左键按下去时,此变量为真;当鼠标左键弹起时,此变量为假,这时,我们就不再绘制线条了。该变量在视类头文件中的定义代码如下:Private: BOOL m_bDraw;接下来在视类的构造函数中,将此变量初始化为FALSE。m_bdraw=FALSE;当鼠标左键按下去时,在视类的OnLButtonDown函数中将此变量初始化为TRUE。m_bdraw=TRUE;当鼠标左键弹起时,在视类的OnLButton函数中将此变量初始化为假。m_bdraw=FALSE;然后在OnMouseMove函数中首先对m_bdraw变量进行判断,如果其值为真,说明鼠标左键已经按下去了,这时就可开始进行画线操作。还有一点需要注意,因为每绘制一条线段后,下次应该从这条线段的终点开始继续绘制。因此,绘制完当前线段后,应该修改线段的起点,将当前线段的终点作为下一条线段的起点,程序代码如下:void CGraphicView:OnMouseMove(UINT nFlags, CPoint point) /TODO: Add your message handler code here and/or call default/创建并获得设备描述 CClientDC dc(this);/创建宽度为1的实线红色画笔CPen pen (PS_SOLID, 1, RGB(255,0,0));/把创建的画笔选入设备描述 CPen *pOldpen=dc.SelectObject(&pen);if(m_bDraw=true)dc.MoveTo(m_ptOrigin); dc.LineTo(point);/修改线段的起点 m_ptOrigin=point;/恢复设备描述dc.SelectObject(pOldpen); CView:OnMouseMove(nFlags, point);如果在上面绘制连续线条的程序中,保持每段小直线的起点不变,即以鼠标左键按下时的起点为起点不变,分别绘制到鼠标移动点的直线,这时就会出现扇形的效果。也就是去掉上述代码OnMouseMove函数中修改线段起点的代码。程序代码如下:void CGraphicView:OnMouseMove(UINT nFlags, CPoint point) /TODO: Add your message handler code here and/or call default/创建并获得设备描述 CClientDC dc(this);/创建宽度为1的实线红色画笔CPen pen (PS_SOLID, 1, RGB(255,0,0));/把创建的画笔选入设备描述 CPen *pOldpen=dc.SelectObject(&pen);if(m_bDraw=true)dc.MoveTo(m_ptOrigin); dc.LineTo(point);/恢复设备描述dc.SelectObject(pOldpen); CView:OnMouseMove(nFlags, point);3.3画刷 (韩伟 肖越)再为此程序添加一个子菜单,菜单名称为“画刷”,并为其添加三个菜单项,分别用来控制不同的画刷。MFC提供了一个CBrush类,可以用来创建画刷对象。画刷通常用来填充一块区域。简单画刷、位图画刷、透明画刷,程序代码如下:void CDrawView:OnLButtonUp(UINT nFlags, CPoint point) /创建一个红色画刷CBrush brush(RGB(255,0,0);/创建并获得设备描述表CClientDC dc(this);/利用红色画刷填充鼠标拖曳过程中形成的矩形区域dc.FillRect(CRect(m_ptOrigin,point),&brush);/创建位图对象CBitmap bitmap;/加载位图资源bitmap.LoadBitmap(IDB_BITMAP1);/创建位图画刷CBrush brush(&bitmap);/创建并获得设备描述表CClientDC dc(this);/利用红色画刷填充鼠标拖曳过程中形成的矩形区域dc.FillRect(CRect(m_ptOrigin,point),&brush);/创建并获得设备描述表CClientDC dc(this);/创建一个空画刷CBrush *pBrush = CBrush:FromHandle(HBRUSH)GetStockObject(NULL_BRUSH);/将空画刷选入设备描述表CBrush *pOldBrush = dc.SelectObject(pBrush);/绘制一个矩形dc.Rectangle(CRect(m_ptOrigin,point);/恢复先前的画刷dc.SelectObject(pOldBrush);m_bDraw = FALSE;CView:OnLButtonUp(nFlags, point);在简单画刷程序中,首先创建一个红色画刷;接着创建设备描述表对象;然后调用设备描述表对象的成员函数FillRect,利用指定的画刷填充一块指定的矩形区域,而鼠标拖动过程中的起点和终点就决定了需要填充的矩形区域,因此,代码中通过CRect类利用鼠标拖动的起点和终点构造了这快矩形区域。CRect类提供了多个构造函数,这里使用的是下面这种构造函数,即通过指定矩形区域的左上角和右下角这两个点来构造一块矩形区域。CRect(POINT topLeft,POINT bottomRight);代码中的CDC类的成员函数FillRect,该函数的功能是用指定的画刷填充一个矩形。该函数将填充全部的矩形,包括上左边界,但不填充右底边界。FillRect函数的声明如下:void FillRect (LPCRECT lpRect,CBrush* pBrush);该函数有两个参数,lpRect是指向一个RECT结构体或CRect对象的指针,该结构体或对象中包含了要填充的矩形的逻辑坐标。pBrush是指向用于填充矩形的画刷对象的指针。在位图画刷程序中,CBrush类有下面这样一种构造函数。CBrush (CBitmap* pBitmap);该构造函数要求一个CBitmap类型的指针,CBitmap类是位图类,于是我们就会这样想:利用这个构造函数是否就可以创建一个位图画刷呢?事实确实如此。创建CBitmap对象时,仅调用其构造函数并不能得到一个有用的位图对象,还需要调用一个初始化函数来初始化这个位图对象。CBitmap类提供了多个初始化函数,例如,LoadBitmap、CreateBitmap、BitmapIndirect等。这里用LoadBitmap函数来加载一副位图,该函数的声明如下:BOOL LoadBitmap (LPCTSTR lpszResourceName);BOOL LoadBitmap (UINT nIDResource);其中第二种声明需要一个资源ID作为参数。首先给程序增加一个位图资源。为一个工程创建资源有多种实现方法,其中一种方法可以利用【Insert】菜单下的【Resource】命令,在弹出的对话框中选择Bitmap资源类型,单击【New】按钮,即可创建一个默认名称为IDB_BITMAP1的位图资源,并在VC+集成开发环境右边的代码编辑区中打开位图编辑器。可以利用编辑器右边的调色板和绘图工具来编辑位图资源,还可以通过拉伸位图编辑器中网格周围的蓝色方点来调整位图的大小。在透明画刷程序中,我们利用GetStockObject这个函数来获取一个黑色或白色的画刷句柄。这个函数是否能够获得一个透明画刷句柄呢?从MSND提供的帮助信息中,可以看到该函数的参数取值之一可以是NULL_BRUSH,以获取一个空画刷。那么,这个空画刷是否就是我们所需要的透明画刷呢?结论是正确的。但这时存在一个问题,我们获取的是句柄,而在进行绘制操作时需要的是一个画刷对象。如何从画刷句柄转换为画刷对象呢?CBrush类提供了一个FromHandle函数来实现这样的功能。该函数的声明如下:Static CDC* PASCAL FromHandle(HDC hDC);3.4设置对话框(韩伟 肖越)为程序添加一个设置对话框,允许用户指定画笔的类型、线宽,并让随后的绘图操作就使用用户指定的新设置值来进行绘制。为了实现这一功能,首先需要为程序添加一个对话框资源,并按下表修改属性。属性值IDIDD_DLG_SETTINGCaptionSettingFont宋体设置线型、线宽对话框的代码如下:void CGraphicView:OnSetting() /TODO: Add your command handler code hereCSettingDlg dlg;dlg.m_nLineWidth=m_nLineWidth; dlg.m_nLineStyle=m_nLineStyle;if(IDOK=dlg.DoModal()m_nLineWidth=dlg.m_nLineWidth; m_nLineStyle=dlg.m_nLineStyle;3.5颜色(韩伟 肖越)颜色对话框看起来比较复杂。实际上,MFC为我们提供了一个类:CColorDialog,可以很方便的创建这样的一个颜色对话框。void CGraphicView:OnColor() / TODO: Add your command handler code here CColorDialog dlg;dlg.m_cc.Flags |=CC_RGBINIT | CC_FULLOPEN; dlg.m_cc.rgbResult=m_clr;if(IDOK=dlg.DoModal()m_clr=dlg.m_cc.rgbResult;3.6打开与保存void CGraphicView:OnFileOpen() / TODO: Add your command handler code hereHMETAFILE hmetaFile;hmetaFile=GetMetaFile(meta.wmf);m_dcMetaFile.PlayMetaFile(hmetaFile);DeleteMetaFile(hmetaFile);Invalidate();void CGraphicView:OnFileSave() / TODO: Add your command handler code here HMETAFILE hmetaFile;hmetaFile=m_dcMetaFile.Close();CopyMetaFile(hmetaFile,meta.wmf);m_dcMetaFile.Create();DeleteMetaFile(hmetaFile);4运行结果运行结果如图7、8、9图7图8图9结论其实学任何一种语言都是一样的。需要勤奋+毅力+运气=成功,这是我认为的一个公式。这里毅力和勤奋是个人因素,而运气这是先天的。如果以前没有接触过编程语言的话,在接触VC前我建议你先学习一些基础语言,比如C等都是一些比较好学的基础语言,我当初就是从C语言过度学VC的。学基础语言的目的是学习语法结构和如何编写概念,只有你理解和掌握了这些编程用的工具才能学习高级语言。这些基础语言中我建议大家学C语言,其实VC就是C+也就是C语言的儿子,父亲学习起来比较容易上手,但遇到类似WINDOWS的程序的时候比较固执不容易沟通,在这种条件下才有了儿子,儿子比较开朗应变能力强,但是就因为他这些优点才使初学者难以掌握。 VC是C+语言,是一种面向对象的编程语言。他于基础语言不同点在于,基础语言是一条路走到底的(中断技术除外),而面向对象是等待你的指令才往下走,是被动的编程语言。这点是学习VC前必须扭转的概念。通过这次学年设计,我了解vc+是Windows平台上的C+编程环境,学习VC要了解很多Windows平台的特性并且还要掌握MFC、ATL、COM等的知识,难度比较大。Windows下编程需要了解Windows的消息机制以及回调(callback)函数的原理;MFC是Win32API的包装类,需要理解文档视图类的结构,窗口类的结构,消息流向等等;COM是代码共享的二进制标准,需要掌握其基本原理等等。基于我们这次用VC+编写了一个简单的画图板,功能不是很多,但是从中的到不少收获。主要有:1对项目和文档的了解,我们在编写程序时,要对不同的文件进行编写。其中项目就是文件的集合,包括头文件、源代码文件、资源文件。文档窗口也称编辑窗口,是用户进行输入或编辑头文件、源文件、资源的区域。在编辑文件时,为了增加程序的可读性,系统用绿色显示注释语句,用蓝色显示关键字。2菜单:我们绘制画图板时,就要建立一个“绘图”菜单。对于“绘图”菜单下还有几个子菜单项,通过建立菜单同时让它实现菜单上的命令,这就要我们对每个菜单项进行设置,诸如,ID、标题、快捷键、热键等。还有一些属性设置,设置不好,容易出错,所以每次建立菜单,都需谨慎设置,记住每个菜单对应的参数。3.文件打开与保存,对于我们绘制出一幅图片,那么我们就要把它保存下来。如果我们无法保存,我们做了也就没没什么意义了。对于图形的保存于打开,我们还存在很多问题,自定义保存不同文件夹下尚未解决,所以还需要我们进一步的学习和了解,争取实现我们心里多希望的。4.在编程时遇到了图像在变换大小时,原来的图形会消失,后来通过查看相关资料,这里涉及的一个重绘问题。经过多次修改,添加代码,才得以解决。所以我觉得学习VC+就要拿出那种坚持不懈的精神,做什么也是,只有你不放弃对它了解,才会实现我们自己想要的,这就要我们要不断的学习VC+,从中学习更多我们没了解到的知识。5对于CView视图,经过查询主要是负责内存数据与用户的交互。包括数据的显示、用户操作的响应(如菜单的选取、鼠标的响应)。最重要的是OnDraw(重画窗口),通常用CWnd:Invalidate()来启动它。另外,它通过消息映射表处理菜单、工具条、快捷键和其他用户消息。最后通过学习VC+,从中受益匪浅,更多的知识,还有待于我们去挖掘实现更多有趣的东西,同样它也是一个很强大的软件。
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 管理文书 > 工作总结


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!