MFC绘图 实验报告.docx

上传人:b****5 文档编号:11774304 上传时间:2023-04-01 格式:DOCX 页数:31 大小:220.44KB
下载 相关 举报
MFC绘图 实验报告.docx_第1页
第1页 / 共31页
MFC绘图 实验报告.docx_第2页
第2页 / 共31页
MFC绘图 实验报告.docx_第3页
第3页 / 共31页
MFC绘图 实验报告.docx_第4页
第4页 / 共31页
MFC绘图 实验报告.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

MFC绘图 实验报告.docx

《MFC绘图 实验报告.docx》由会员分享,可在线阅读,更多相关《MFC绘图 实验报告.docx(31页珍藏版)》请在冰豆网上搜索。

MFC绘图 实验报告.docx

MFC绘图实验报告

基于MFC的绘图软件

目录

基于MFC的绘图软件2

1.引言3

2.MFC设备上下文及绘图的基本理论知识3

2.1GDI(GraphicDeviceInterface)绘图的实现3

2.2MFC图形对象类3

2.3库存的GDI对象4

2.4与绘图有关的简单数据类型5

2.5MFC应用程序框架中的图形绘制和刷新6

3.设计的主体内容MFC设备描述表---CDC类6

3.1CDC类及其派生类6

3.2文本输出7

3.3CDC常用的绘图函数7

3.4画笔和画刷9

4.软件主体设计9

4.1资源编辑9

4.2具体实现12

5.结果分析与讨论21

6.总结22

附录:

简单绘图软件作品说明23

1.引言

计算机的发展也是计算机语言的发展得到了很大的提高,人们的生活中离不开图像,除了我们可以用铅笔在纸上画图外,我们也可以在电脑上绘制我们的想象,本实验就是基于VC++的一个小型的绘图软件,虽然麻雀虽小五脏俱全。

本课题就是要实现这一小小的软件。

2.MFC设备上下文及绘图的基本理论知识

2.1GDI(GraphicDeviceInterface)绘图的实现

图形设备接口(GDI)可以理解为一个可执行程序,它处理来自windows应用程序的图形函数调用,然后把这些调用传递给合适的设备驱动程序,由设备驱动程序来执行与硬件相关的函数,并产生最后的输出结果。

Windows图形系统的结构关系如下:

设备描述表(DC)是一种windows数据结构,它包含了与一个设备(如显示器)的绘制属性的相关信息。

所有的绘制操作通过一个设备上下文对象进行,该对象封装了实现绘制线条,形状和文本的windowsAPI函数。

设备上下文可以用来向屏幕,打印机和图元件输入结果。

2.2MFC图形对象类

Windows提供了多种用于在设备描述表中进行绘图的图形对象,如画笔,位图,调色板,区域,和路径等。

MFC对这些图像对象进行了封装,提供给等同与它们的图形对象类。

MFC中各图形对象及封装类如下:

MFC图像对象

对象

MFC类

简要概述

画笔

CPen

画笔CPen对象在画点和画线时有用。

他的属性包括颜色,宽度,线条风格,如虚线,实线,点画线等

画刷

CBrush

刷子对象决定了填充区域时所采用的颜色或模板。

对于一个固定的刷子来讲它的属性为颜色,是否采用网格和网格的类型如水平的垂直的交叉的等

字体

CFont

用于选用文字时选用不同大小的字体。

可选风格包括:

斜体,粗体,字体名称,是否有下划线等。

位图

CBitmap

位图CBitmap类对象可以包含一副图像,可以保存在资源中

调色板

CPalette

一种颜色映射接口,在不干扰其他的前提下可以充分的利用出入设备的颜色描绘能力

区域

CRgn

利用他可以很好的控制和限制作图区域或是改变窗口外形等

在windows中使用GUI对象时必需遵循一定的规则:

☐首先需要创建一个合法的对象,不同的对象创建方法不同。

☐然后需要将该GUI对象选入DC中,同时保持DC中原来的GUI对象。

如果选入的是非法的对象将会引起异常。

☐在使用完成后应将恢复原来的对象。

这点特别重要,否则选中给设备环境的资源不会释放掉,使得程序使用越来越多的GDI资源。

2.3库存的GDI对象

Windows预定义了一些标准的GDI对象,提供给系统和程序使用,称为库存GDI对象,他们可以为多个程序使用。

他包括最常用的字体,画刷,画笔等,常用的库存GDI对象如下:

对象

说明

对象

说明

BLACK_BRUSH

黑色画刷

WHITE_BRUSH

白色画刷

NULL_BRUSH

空画刷及透明画刷

WHITE_PEN

白色画笔

BLACK_PEN

黑色画笔

NULL_PEN

空画笔

SYSTEM_FONT

系统字体

DEFAULT_PALETTE

默认调色板包含20种颜色

可以使用CDC:

:

SelectStockObject(intnIndex);选入这些库对象并返回原对象。

如下面代码:

CPenpen;//定义画笔

pen.CreatePen(this->m_nLineType,this->m_nLineWidth,this->m_cLineColor);

//选择新画笔,并保持旧画笔

CPen*pOldPen=this->m_pMemDC->SelectObject(&pen);

//选择库存空画刷

CBrush*pOldBrush=(CBrush*)m_pMemDC->SelectStockObject(NULL_BRUSH);

 

2.4与绘图有关的简单数据类型

→CPoint类

CPoint类封装了一个点的坐标,它包含2个数据成员x,y。

CPoint:

:

CPoint的构造函数

CPoint();

CPoint(intinitX,intinitY);

CPoint(POINTinitPt);

CPoint(SIZEinitSize);

CPoint(DWORDdwPoint);

当使用DWORD类型时,其低位字将赋值给CPoint的x成员,高位字将赋值给y。

→CSize类

如果表示距离和相关位置,可以使用CSize对象。

MFC类中包含2个成员变量,cx,cy。

CSize:

:

CSize类的构造函数

CSize();

CSize(intinitCX,intinitCY);

CSize(SIZEinitSize);

CSize(POINTinitPt);

CSize(DWORDdwSize);

当使用DWORD类型时,其低位字将赋值给CSize的Cx成员,高位字将赋值给cy。

→CRect类

cRect类是最常用的简单数据结构之一,它一般表示一个矩形,有4个数据成员定义如下:

typedefstructtagRECT{

LONGleft;

LONGtop;

LONGright;

LONGbottom;

}RECT,*PRECT,NEAR*NPRECT,FAR*LPRECT;

可以理解为左上角和右下角坐标。

他还有一些成员函数,我就在这略去。

→RGB宏

宏RGB用于定义一个颜色值,其声明如下:

COLORREFRGB(

BYTEbyRed,//redcomponentofcolor

BYTEbyGreen,//greencomponentofcolor

BYTEbyBlue//bluecomponentofcolor

);

它需要定义颜色的三种基本色成分,各分量取值0-255之间。

返回COLORREF值。

如下:

COLORREFcolor=RGB(125,125,125);

2.5MFC应用程序框架中的图形绘制和刷新

voidCMyView:

:

OnDraw(CDC*pDC);这个函数CView类的消息处理函数OnPaint调用。

从基类库MFC中可以找到OnPaint函数的实现代码:

voidCView:

:

OnPaint()

{

CPaintDCdc(this);

OnPrepareDC(&dc);

OnDrow(&dc);

}

OnPaint函数处理WM_PAINT消息,这个消息是当窗口的完整形受到破害是产生的一个消息,及当窗口产生WM_PAINT消息时,OnPaint函数执行并调用OnDrow(&dc);函数来完成绘图。

当窗口刷新是会自动调用图形重绘操作。

图形的刷新是绘图过程中必须考虑的问题,如窗口的大小调整,窗口的移动,窗口被覆盖后恢复等都需要重新对窗口进行刷新。

3.设计的主体内容MFC设备描述表---CDC类

3.1CDC类及其派生类

CDC类派生自CObject,他具有CObject类的特点,CDC类即包括了设备属性又包括了绘图方法,通过此方法可以实现GDI的所以图形输出。

CDC类包含了177种函数和很多的数据成员,可以用CWnd的成员函数GetDC来获得设备环境,使用完后要ReleaseDC释放CDC对象。

CDC*pDC=GetDC();

…………………………….

this->ReleaseDC(pDC);

CDC的派生类及其说明

说明

CClientDC

代表客户窗口区的设备环境,绘图点(0,0)指客户区左上角。

可以随时创建CClientDC对象,CClientDC的析构函数将自动调用ReleaseDC(pDC);函数自动释放设备描述表

CWindowDC

代表整个窗口区(包括客户区和非客户区)的设备环境,绘图点(0,0)指整个窗口的左上角。

可以随时创建CWindowDC对象,CWindowDC可以自动释放设备描述表

CPaintDC

代表客户区的无效区(需要重画区域),

3.2文本输出

输出文本一般用CDC:

TextOut()函数,他可以对单行文本进行输出,函数原型如下:

BOOLTextOut(intx,inty,constCString&str);

X,y为文本输出的位置坐标,参数STR为要输出的文本

CDC类还有在制定的矩形区域范围内显示格式话文本

CDC:

:

DrawText(constCString&str,LPRECTlpect,UINTnFormat)

Str为要输出的文本,lpect为要输出的矩形区域,nFormat为设定的对齐方式和风格

nFormat常用的取值和含义

DT_SINGLELINE

单行输出

DT_BOTTOM

底部对齐必须和DT_SINGLELINE一起用

DT_TOP

顶部对齐必须和DT_SINGLELINE一起用

DT_VCENTER

中部对齐必须和DT_SINGLELINE一起用

DT_LEFT

左对齐

DT_RIGHT

右对齐

DT_CALCRECT

根据文本内容,扩展矩形区域

3.3CDC常用的绘图函数

→绘制点

CDC:

:

SetPixel()制定的颜色画个点

COLORREFSetPixel(intx,inty,COLORREFcrColor);

COLORREFSetPixel(POINTpoint,COLORREFcrColor);

X,y(piont)为制定的坐标,crColor为将要绘制的颜色

→绘制直线

CDC:

:

MoveTo 

CPointMoveTo(intx,inty);

CDC:

:

LineTo 

BOOLLineTo(intx,inty);

这两个函数一般一起用,一般形式如:

dc.MoveTo(x1,y1);

dc.LineTO(x2,y2);

window绘制从(x1,y1)到(x2,y2)所在的直线的所有像素,不包括(x2,y2);

→绘制弧线

CDC:

:

Arc 

BOOLArc(intx1,inty1,//边框矩形左上角的逻辑坐标

intx2,inty2,//边框矩形右下角的逻辑坐标

intx3,inty3,//圆弧起始坐标

intx4,inty4);//圆弧终点坐标

 

→绘制矩形

CDC:

:

Rectangle 可以绘制一个矩形区域原型如下

BOOLRectangle(intx1,inty1,intx2,inty2);

(x1,y1)(x2,y2)为矩形的左上角和右下角

CDC:

:

RoundRect 可以绘制一个圆角矩形原型如下

BOOLRoundRect(intx1,inty1,intx2,inty2,intnWidth,intnHeight);

(x1,y1)(x2,y2)为矩形的左上角和右下角

intnWidth,intnHeight为圆角宽和高

 

 

→绘制椭圆

CDC:

:

Ellipse 可以绘制椭圆和园,原型如下:

BOOLEllipse(intx1,inty1,intx2,inty2);

(x1.y1)(x2,y2)分别是左上角和右下角坐标

3.4画笔和画刷

在windows中,画笔和画刷是使用最多的GUI对象,绘制图时,画笔负责绘制图形区域的边界,而画刷负责内部填充

◆画笔对象及其使用

1.画笔对象的创建

一般分为2部:

首先构造一个Cpen对象,然后在调用对象CreatePen()函数。

CreatePen()函数按制定样式,宽度,等属性创建一个逻辑画笔,然后将画笔和Cpen对象关联原型如下

CPen:

:

CreatePen

BOOLCreatePen(intnPenStyle,intnWidth,COLORREFcrColor);

intnPenStyle,代表笔的样式

nPenStyle,的可能取值

PS_SOLID

创建一个实线画笔

PS_DASH

创建一个虚线画笔,但宽度必须为1,否则为实线

PS_DOT

创建一个点线画笔,但宽度必须为1,否则为实线

PS_DASHDOT

创建一个点划线画笔,但宽度必须为1,否则为实线

intnWidth,代表笔的宽度,为像素

COLORREFcrColor使用RGB宏前面介绍了。

2.使用画笔对象进行输出

当画笔对象创建成功后,就可以使用CDC类的成员函数selectobject()将其选入设备描述表中进行各种输出。

在完成后还原设备描述表中原有的GDI对象。

◆画刷对象及其使用

刷子对象用来在GDI输出时填充一个封闭图形的内部。

CBrush:

:

CreateSolidBrush函数原型为:

BOOLCreateSolidBrush(COLORREFcrColor);

他用与创建一个固定颜色的刷子。

使用如下

CBrushbrush;

Brush.CreateSolidBrush(RGB(255,0,0));

4.软件主体设计

4.1资源编辑

光标资源,填充IDC_CURSOR_FILL和画笔IDC_CURSOR_PEN(图1)

位图资源填充和版权资源

图1

对话框资源关于IDD_ABOUTBOX文本对话框资源IDD_DIALOG1(图2)

图2

工具栏图标资源分别是直线,矩形,圆形(椭圆),圆角矩形,

填充,铅笔,文字(图3)

图3

具体的ID资源号和对应的说明等见下图(图4)

在视图类中对应的变量和主要的函数

public:

intm_nScreenX;//视图最大x坐标

intm_nScreenY;//视图最大y坐标

intm_nDrawType;//所画的东西(线,矩形。

intm_nLineWidth;//线宽

intm_nLineType;//线型

COLORREFm_cLineColor;//线色

COLORREFm_cFillColor;//填充的颜色

boolm_bDrawing;//是否在画图否false是true

CPointm_ptStart;//画图的起点坐标

CPointm_ptold;//画图的前一个坐标

CDC*m_pMemDC;//兼容内存dc

CBitmap*m_pBitmap;//位图指针

CRect*textRect;//文本区域

CStringstr_Text;//文本内容

COLORREFm_cTextColor;//文字的颜色

LOGFONTm_font;//字体对象

intm_nRoundRecWidth;//圆角的宽

intm_nRoundRecHeight;//圆角的高

//创建我们需要的子窗口

afx_msgintOnCreate(LPCREATESTRUCTlpCreateStruct);

//用于窗口的重绘相应WM_PAINT消息前面一介绍

virtualvoidOnDraw(CDC*pDC);

//用于填充和确定起始点

afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);

//用于各种画图

afx_msgvoidOnLButtonUp(UINTnFlags,CPointpoint);

//用于捕捉移动画面的绘图

afx_msgvoidOnMouseMove(UINTnFlags,CPointpoint);

//相应不同的消息的光标

afx_msgBOOLOnSetCursor(CWnd*pWnd,UINTnHitTest,UINTmessage);

4.2具体实现

●构造函数:

由于构造函数的程序运行时就执行的,所以初始赋值就是最主要的:

CMyView:

:

CMyView()

{

//TODO:

addconstructioncodehere

this->m_nScreenX=1800;//最大x=1000

this->m_nScreenY=800;//最大y=800

this->m_nDrawType=-1;//初始不画图

this->m_nLineWidth=1;//线宽为1

this->m_nLineType=PS_SOLID;//线型为实线

this->m_cLineColor=RGB(0,0,0);//线色初始为黑

this->m_cFillColor=RGB(255,0,0);//填充初始为红

this->m_bDrawing=false;//初始为每画任何图形

this->m_ptStart=CPoint(0,0);//

this->m_ptold=CPoint(0,0);//

this->m_pMemDC=newCDC();//

this->m_pBitmap=newCBitmap();//

textRect=newCRect();//文字的区域

this->str_Text="";//文字内容

this->m_cTextColor=RGB(0,0,0);//文字颜色

memset(&m_font,0,sizeof(m_font));//d得到当前系统字体

this->m_nRoundRecWidth=40;//圆角宽

this->m_nRoundRecHeight=50;//圆角高

}

由于我们在构造函数中使用了new这个操作符所以在析构函数里有:

CMyView:

:

~CMyView()

{

deletethis->m_pMemDC;

deletethis->m_pBitmap;

deletethis->textRect;

}

构造和析构完了,我就开始写函数了,当在作图之前还要在,还要初始化我们的画图“纸”,具体见代码注释

intCMyView:

:

OnCreate(LPCREATESTRUCTlpCreateStruct)

{

if(CView:

:

OnCreate(lpCreateStruct)==-1)

return-1;

//TODO:

Addyourspecializedcreationcodehere

//以像素为单位计算屏幕尺寸

this->m_nScreenX=GetSystemMetrics(SM_CXSCREEN);

this->m_nScreenY=GetSystemMetrics(SM_CYSCREEN);

//获取显示dc的指针

CDC*pDC=GetDC();

//创建显示dc的兼容内存dc

this->m_pMemDC->CreateCompatibleDC(pDC);

//创建与显示dc的位图兼容的位图与屏幕一样大

this->m_pBitmap->CreateCompatibleBitmap(pDC,this->m_nScreenX,this->m_nScreenY);

//将兼容位图选进内存dc,指针poldbitmap用来跟踪原位图

CBitmap*pOldBitmap=this->m_pMemDC->SelectObject(this->m_pBitmap);

//创建一个白色画刷

CBrushbrush(RGB(255,255,255));

//将选进的内存dc位图填上白色

CRectrect(-1,-1,this->m_nScreenX,this->m_nScreenY);

this->m_pMemDC->FillRect(rect,&brush);

//恢复内存dc中的原位图

m_pMemDC->SelectObject(pOldBitmap);

this->ReleaseDC(pDC);

return0;

}

还有就是最主要的相应WM_PAINT消息的OnDraw函数,具体前面有我就在重复下:

就是在窗口拉动,缩小放大等情况下,对窗口进行重绘。

voidCMyView:

:

OnDraw(CDC*pDC)

{

CMyDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:

adddrawcodefornativedatahere

//兼容位图选入内存同时保存旧的

CBitmap*pOldBitmap=this->m_pMemDC->SelectObject(this->m_pBitmap);

//将兼容位图从内存dc拷贝到dc

pDC->BitBlt(0,0,this->m_nScreenX,this->m_nScreenY,this->m_pMemDC,0,0,SRCCOPY);

//恢复原位图

m_pMemDC->SelectObject(pOldBitmap);

memset(&m_font,0,sizeof(m_font));//d得到当前系统字体

}

对IDR_MAINFRAME菜单进行如下设计(图5)

图5

然后新建个菜单IDR_MENU1用来做右键弹出菜单(图6)

(图6)

添加消息相应ON_WM_CONTEXTMENU对于代码如下

voidCMyView:

:

OnContextMenu(CWnd*pWnd,CPointpoint)

{

//TODO:

Addyourmessagehandlercodehere

CMenumenu;

menu.LoadMenu(IDR_MENU1);//加载IDR_MENU1

CMenu*popMenu=menu.GetSubMenu(0);

popMenu->TrackPopupMenu(TPM_RIGHTBUTTON,point.x,point.y,t

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1