Visual C++设计二维平面图形.docx
- 文档编号:11000445
- 上传时间:2023-02-24
- 格式:DOCX
- 页数:29
- 大小:410.56KB
Visual C++设计二维平面图形.docx
《Visual C++设计二维平面图形.docx》由会员分享,可在线阅读,更多相关《Visual C++设计二维平面图形.docx(29页珍藏版)》请在冰豆网上搜索。
VisualC++设计二维平面图形
目录:
一、设计目的……………………………………………………………………………………………………………2
二、需求分析……………………………………………………………………………………………………………2
三、运行环境……………………………………………………………………………………………………………2
四、功能要求……………………………………………………………………………………………………………2
五、总体设计……………………………………………………………………………………………………………3
1.根据题目,得到系统功能模块图………………………………………………3
2.程序流程图…………………………………………………………………………………………………4
3.图形类图………………………………………………………………………………………………………5
4.关键代码………………………………………………………………………………………………………6
六、测试过程………………………………………………………………………………………………………………13
1.实际完成的情况……………………………………………………………………………………………13
2.程序的性能分析……………………………………………………………………………………………13
3.上机过程中出现的问题及其解决方案……………………………………………13
4.程序中可以改进的地方说明…………………………………………………………………13
5.程序中可以扩充的功能及设计实现构想………………………………………14
6.系统测试…………………………………………………………………………………………………………14
七、设计总结………………………………………………………………………………………………………………16
八、系统使用手册……………………………………………………………………………………………………17
九、参考文献………………………………………………………………………………………………………………20
十、附录…………………………………………………………………………………………………………………………21
一、设计目的
利用VisualC++设计二维平面图形:
可通过菜单或者工具栏按钮,选择绘画工具,画不同的平面图形(直线、圆弧、矩形、圆角矩形、圆、椭圆等);可通过颜色对话框选择不同的颜色,使所画的图形具有不同颜色;可保存文档所画的图形,并能打开该图形。
二、需求分析
1.选作这个二维图形的设计题目,主要是基于了解在电脑上的画图软件的功能是如何实现的,以及在MFC平台是怎么实现功能调用的,实现图形的绘制,从而可以进一步的了解到c++是如何面向对象的程序设计,以及在我们平常使用的一些软件的一些功能实现的算法。
在一些基本的菜单如:
文件菜单、编辑菜单、工具菜单、还有窗口菜单都是如何实现的。
熟练掌握类的继承、多态和构造函数,以及在VC++6.0的软件的一些扩展功能。
了解编程的实际用处,增加对编程更深入的了解,对自己所学的知识更加深入的学习与掌握。
2.通过本次实验主要实现一些画图的基本功能,本程序可以通过菜单栏或工具栏进行图形的绘制,本程序可以绘制直线、圆弧、矩形、圆角矩形、圆、椭圆等。
图像的颜色可以通过编辑框选择,也可以自定义颜色。
笔画的线性有实线型、虚线型、点画线,也可以自己设定并且设定笔画的宽度(当然必须要大于0),在对话框可以显示你选择的线性。
还可以进行撤销功能和全部删除功能。
在完成后可以将自己的作品保存起来,并且能够打开。
为了达到以上所叙述的优点及功能,我使用VC开发平台,MFC框架实现一个画图程序,尽可能多的实现Windows自带的画图功能,并扩展其功能。
并且优化界面,绘图方便。
三、运行环境
操作系统MicrosoftWindows
四、功能要求
1.能够用鼠标操控方式,绘制直线、圆弧、矩形、圆角矩形、圆、椭圆
2.在绘图时,选择绘制某种图像后(如直线),在画布中按住鼠标左键后移动鼠标,在画布中实时的根据鼠标的移动显示相应的图形。
在松开鼠标左键后,一次绘图操作完成
3.编辑图像的颜色可,以通过编辑框选择,也可以自定义颜色
4.笔画的线性有实线型、虚线型、点画线,也可以自己设定并且设定笔画的宽度(宽度大于0),在对话框可以显示选择的线性和线宽
5.可以以矢量图方式保存绘制的图形。
6.可以读取保存的矢量图形文件,并显示绘图的结果。
7.有画直线、圆弧、矩形、圆角矩形、圆、椭圆的工具箱。
8.有颜色选择工具箱。
9.在鼠标移向一工具不动时,有工具的功能提示。
五、总体设计
1.根据题目,得到系统功能模块图
图1系统功能图
2.程序流程图
图2系统流程图
3.图形类图
4.关键代码
(1)实现用画笔画图:
/*根据m_nDrawType的值判断选择画图的形状,使用画笔进行画图*/
switch(m_nDrawType)
{
caseTYPE_LINE:
//直线
m_pShape=newCLine();
break;
caseTYPE_ARC:
//圆弧
m_pShape=newCArc();
break;
caseTYPE_RECTANGLE:
//矩形
m_pShape=newCRectangle();
break;
caseTYPE_SQUARE:
//正方形
m_pShape=newCSquare();
break;
caseTYPE_ROUNDRECT:
//圆角矩形
m_pShape=newCRoundRect();
break;
caseTYPE_ELLIPSE:
//椭圆
m_pShape=newCEllipse();
break;
caseTYPE_CIRCLE:
//圆
m_pShape=newCCircle();
break;
}
(2)调色板的使用
//编辑自定义线条颜色
voidCGraphic1View:
:
OnDlgColor()
{
//TODO:
Addyourcommandhandlercodehere
CColorDialogcDlg;//调用MFC的颜色对话框
cDlg.m_cc.Flags|=CC_RGBINIT|CC_FULLOPEN;//m_cc是choosecolor的结构图,CC_FULLOPEN将颜色板完全打开
cDlg.m_cc.rgbResult=m_Color;//rgbresult指示用户的颜色选择
if(IDOK==cDlg.DoModal())
{
m_Color=cDlg.m_cc.rgbResult;
}
}
//设置选项响应函数
voidCGraphic1View:
:
OnSetting()
{
//TODO:
Addyourcommandhandlercodehere
CSittingDlgdlgSetting;//设置对话框类对象
dlgSetting.m_nLineWidth=m_nLineWidth;//设置线宽
dlgSetting.m_nLineStyle=m_nLineStyle;//设置线型
dlgSetting.m_Color=m_Color;//设置颜色
if(IDOK==dlgSetting.DoModal())
{
m_nLineWidth=dlgSetting.m_nLineWidth;
m_nLineStyle=dlgSetting.m_nLineStyle;
}
}
(3)使用链表管理图元实现重绘
CObList是一个用于存储对象的链表,它可以储存CObject及其派生类的对象。
它存储的是对像的指针。
CObList类提供共了加入对象、删除对象、查找对象等一系列的方法,使用这些方法,我们可对图元进行一些简单的操作。
CObList对象最好定义在CDoc类中,这样方便我们今后的串行化。
CObList对象定义在CDoc中,我们就不能在CView类中直接使用,这时我们可以通过CView类中的GetDocument()函数获取CDoc类的指针,我们通过指针就可以访问CDoc中的CObList对象。
在画图时,当鼠标左键抬起时,我们可以认定图元绘制完毕,所以,在鼠标左键抬起的时候,我们可以将画好的图元加入链表中。
在CDoc类中定义CObList对象m_listShape;
在鼠标左键抬起的消息响应函数中加入如下代码:
CGraphic1Doc*pDoc=GetDocument();
if(m_bDrawing&&m_pShape)
{
m_pShape->SetEndPoint(point);
pDoc->m_listShape.AddTail(m_pShape);//图元加入链表
m_pShape=NULL;
m_bDrawing=FALSE;
Invalidate();//刷新
}
每个一完成的图元都存放在链表中,我们可以通过一些查找的方法,随时将他们取出使用。
例如,为了实现现场的保护,我们可以在OnDraw(CDC*pDC)函数中,我们可以遍历整个链表,将其全部取出,重绘出来。
在OnDraw(CDC*pDC)中重绘所有图元:
CGraphic1Doc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//重绘所有图元
CObList*pListObj=&(GetDocument()->m_listShape);//获取链表的地址
POSITIONpos=pListObj->GetHeadPosition();//得到链表头的位置
while(pos!
=NULL)
{
CShape*pShape=(CShape*)pListObj->GetNext(pos);//获取下一个图元的指针
pShape->Draw(pDC);//画图
}
在使用链表的时候,我们的图元对象都是动态创建的,图元被删除后或是程序退出的时候,一定要把他们析构掉,否则会造成内存泄漏。
析构可以在CDoc类的析构函数中进行。
//析构,防止内存泄露
POSITIONpos=m_listShape.GetHeadPosition();
while(pos)
{
deletem_listShape.GetNext(pos);//释放内存空间
}
m_listShape.RemoveAll();
(4)串行化
为了使我们的类可以串行化,我们要做如下工作:
我们可以为我们的自定义类的定义中添加DECLARE_SERIAL(类名)
在.cpp文件中加上IMPLEMENT_SERIAL(类名,基类名,版本号)
编写Serialize函数,将需要的信息串行化。
在基类CShape添加宏定义:
在头文件中
classCShape:
publicCObject
{
DECLARE_SERIAL(CShape)
public:
……
……
};
在实现部分
IMPLEMENT_SERIAL(CShape,CObject,1)
CShape:
:
CShape()
{
…………
派生类也类似。
编写CShape的Serialize函数:
添加虚函数virtualvoidSerialize(CArchive&ar);
voidCShape:
:
Serialize(CArchive&ar)
{
CObject:
:
Serialize(ar);
if(ar.IsStoring())
{
ar< ar< ar< } else { ar>>m_nPenWidth>>m_nPenStyle>>m_crPenColor; ar>>m_nBrushIndex>>m_crBrushColor; ar>>m_ptStart>>m_ptEnd; Update(); } } 派生类中的Serialize函数: 如果不用串行化新的信息,可以使用CShape类的串行化函数。 (5)图片的保存和打开 通过和CFile类的配合,实现了对可序列化对象(SerializableObjects,这个概念后面描述)的文件读写。 CFile是MFC类库中所有文件类的基类。 所有MFC提供的文件I/O功能都和这个类有关。 在实际的使用中,我们可以使用CFileDialog对话框获取文件的完整文件名,然后用CFile类打开文件进行读写。 使用的CObList(“建立链表”)也是支持串行化的,其中提供了串行化函数Serialize,这个函数可以将链表中所有的对象串行化,前提是这些对象都支持串行化。 我们这个函数就能很方便的实现图元的串行化。 实现读操作的代码如下: voidCGraphic1View: : OnFileOpen() { //TODO: Addyourcommandhandlercodehere Invalidate(); CStringfileExtention("Windowspicture(*.bmp)|*.bmp||"); CFileDialogdlg(TRUE,".bmp",NULL,OFN_ALLOWMULTISELECT|OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT,fileExtention,this);//打开多个文件 CStringfilename; if(dlg.DoModal()==IDOK) { filename=dlg.GetFileName();//获取文件的完整文件名 } if(filename.IsEmpty()) return; CFilefile; file.Open(filename,CFile: : modeRead,NULL); CArchivear(&file,CArchive: : load); CGraphic1Doc*pDoc=GetDocument(); pDoc->m_listShape.Serialize(ar); ar.Close(); file.Close(); Invalidate(); } 实现读操作的代码如下: CStringfileExtention("Windowspicture(*.bmp)|*.bmp|ALLFiles(*.*)|*.*||");//文件过滤器 CFileDialogdlg(FALSE,".bmp",NULL,OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT,fileExtention,NULL); if(dlg.DoModal()==IDOK) { CStringfilename=dlg.GetFileName(); CFilefile;//定义文件对象 if(! file.Open(filename,CFile: : modeWrite|CFile: : modeCreate,NULL))//以写方式打开文件 return; CArchivear(&file,CArchive: : store);//构建CArchive对象 CGraphic1Doc*pDoc=GetDocument(); pDoc->m_listShape.Serialize(ar);//调用串行化函数 ar.Close();//写完毕,关闭文件流 file.Close(); Invalidate(); } (6)OnLButtonDown代码: voidCGraphic1View: : OnLButtonDown(UINTnFlags,CPointpoint) { //TODO: Addyourmessagehandlercodehereand/orcalldefault m_nBegin=point; switch(m_nDrawType) { caseTYPE_LINE: //绘制直线 m_pShape=newCLine(); break; caseTYPE_ARC: //绘制圆弧 m_pShape=newCArc(); break; caseTYPE_RECTANGLE: //绘制矩形 m_pShape=newCRectangle(); break; caseTYPE_SQUARE: //绘制正方形 m_pShape=newCSquare(); break; caseTYPE_ROUNDRECT: //绘制圆角矩形 m_pShape=newCRoundRect(); break; caseTYPE_ELLIPSE: //绘制椭圆 m_pShape=newCEllipse(); break; caseTYPE_CIRCLE: //绘制圆 m_pShape=newCCircle(); break; } if(m_pShape! =NULL)//设置图元的属性 { m_pShape->SetStartPoint(point);//设置起点 m_pShape->SetEndPoint(point);//设置终点,开始时与起点相 m_pShape->SetPenStyle(m_nLineStyle);//设置画笔类型 m_pShape->SetPenWidth(m_nLineWidth);//设置画笔线宽 m_pShape->SetPenColor(m_Color);//设置画笔颜色 m_pShape->SetBrushIndex(m_bBIndex);//设置画刷类型 m_pShape->SetBrushColor(m_crBrushColor);//设置画刷颜色 m_bDrawing=TRUE;//处于画图的过程中 } CView: : OnLButtonDown(nFlags,point); } (7)OnMouseMove代码: voidCGraphic1View: : OnMouseMove(UINTnFlags,CPointpoint) { //TODO: Addyourmessagehandlercodehereand/orcalldefault CDC*pDC=GetDC(); intoldPen=pDC->SetROP2(R2_NOTXORPEN); if(m_bDrawing&&m_pShape) { m_pShape->Draw(pDC);//重画,擦除用 m_pShape->SetEndPoint(point);//设置新的终点 m_pShape->Draw(pDC);//绘新图元 } pDC->SetROP2(oldPen);//还原 CStringstr; str.Format(_T("(%d,%d)"),point.x,point.y); ((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(str);//在状态栏显示当前画面坐标 CView: : OnMouseMove(nFlags,point); } (8)OnLButtonUp代码: voidCGraphic1View: : OnLButtonUp(UINTnFlags,CPointpoint) { //TODO: Addyourmessagehandlercodehereand/orcalldefault m_nEnd=point; CGraphic1Doc*pDoc=GetDocument(); if(m_bDrawing&&m_pShape) { m_pShape->SetEndPoint(point); pDoc->m_listShape.AddTail(m_pShape);//图元加入链表 m_pShape=NULL; m_bDrawing=FALSE; Invalidate();//刷新 } CView: : OnLButtonUp(nFlags,point); } (9)OnDraw代码: voidCGraphic1View: : OnDraw(CDC*pDC) { CGraphic1Doc*pDoc=GetDocument(); ASSERT_VALID(pDoc); //重绘所有图元 CObList*pListObj=&(GetDocument()->m_listShape);//获取链表的地址 POSITIONpos=pListObj->GetHeadPosition();//得到链表头的位置 while(pos! =NULL) { CShape*pShape=(CShape*)pListObj->GetNext(pos);//获取下一个图元的指针 pShape->Draw(pDC);//画图 } //TODO: adddrawcodefornativedatahere } 六、测试过程: 1.实际完成的情况 实际完成了设计要求的基本任务,可通过菜单或者工具栏按钮,选择绘画工具,画不同的平面图形(直线、圆弧、矩形、圆角矩形、圆、椭圆等);可通过颜色对话框选择不同的颜色、线型、线宽,使所画的图形具有不同颜色、线型、线宽;可保存文档所画的图形,并能打开该图形。 除此,我在程序中加了画刷功能(填充为线性)。 2.程序的性能分析 程序的功能简单,算法简单,性能应该还可以。 继承关系很简单,就有一个基类CShap
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Visual C+设计二维平面图形 C+ 设计 二维 平面 图形