王文恒 C++设计报告.docx
《王文恒 C++设计报告.docx》由会员分享,可在线阅读,更多相关《王文恒 C++设计报告.docx(23页珍藏版)》请在冰点文库上搜索。
王文恒C++设计报告
青岛理工大学琴岛学院
设计报告
课题名称:
绘图板
学院:
青岛理工大学琴岛学院
专业班级:
计算机科学与技术091
学号:
20090301017
学生:
王文恒
指导教师:
张秀国、宋传磊
青岛理工大学琴岛学院教务处
2010年12月20日
学生
王文恒
指导教师
张秀国、宋传磊
课题名称
绘图板
设计时间
2010/12/20-2010/12/31
设计地点
图书馆501
设计目的
具体体验一个简单矢量绘图程序的具体过程,利用MFC单文档程序框架,可以使用鼠标实现矢量图形元素的交互式绘制,逻辑上设计图形对象基类,然后派生各具体图元类,并实现虚函数。
进一步熟悉C++的编程理念,提高对C++的认识水平。
指导教师评语
系部教研室
意见
一、设计目的:
具体体验一个简单矢量绘图程序的具体过程,利用MFC单文档程序框架,可以使用鼠标实现矢量图形元素的交互式绘制,逻辑上设计图形对象基类,然后派生各具体图元类,并实现虚函数。
进一步熟悉C++的编程理念,提高对C++的认识水平。
二、需求分析:
要想制作绘图板,是要用MFC单文档程序框架(SDI)实现。
并且可以通过选择菜单项或工具箱的按钮来选择绘图工具类型,在绘图区绘制线段、矩形、圆。
随着经济与科技的快速发展,办学模式多元化,在校学生规模不断扩大。
信息的传达和需求,也变得越来越重要。
有越来越多的师生,在完成一些实践任务的时候,非常迫切的希望有一个绘图板,来帮他们完成一些基本的绘图工作。
这样利用绘图板所绘制出来的图形,不仅美观、准确。
从某种意义上来讲,大大减少了工作量,所以制作绘图板是一件很有现实生活意义的事情,这也就是我之所以选择制作绘图板的原因之所在。
我所设计的绘图板,能够帮助用户完成绘制线段、矩形、圆等图形,在日常的生活生产当中,其所起到的作用和使用范围是非常广泛的。
三、设计过程:
1、界面的设计分析:
设计绘图板的界面,要先对绘图板的功能要有所了解。
绘图板主要是绘制线段、矩形、圆。
图1界面分析图
在绘图板的主界面上,用户能看到、选择和操作的选项如图一所示,用户要完成自己的操作,可根据系统的提示,进行操作即可。
2、绘图板的设计过程
(1)、想要完成绘图板的设计,就需要建立一个工程。
创建一个工程,选择工程中的MFCAPPWizard[exe],写明存储位置和工程名,如图可视:
创建的过程是,先打开VC++6.0,选择文件选项中的新建选择项,选择工程中的MFCAPPWizard[exe],在工程栏中输入20101221,点击确定。
这样就创建了一个工程名为20101221,存储位置在C盘的工程。
(如图2所示)
(2)导入绘图板所用的文字及图片:
1)、在Resources添加插入位图并且导入图片(颜色选择菜单)位图以表示绘图板主界面上的颜色选择菜单。
右击桌面上的我的电脑,选择搜索,在全部或部分文件名的下方矩形框中输入.ico,从中搜索所需要的图片,在复制到桌面上以备用。
在所建的工程里展开Icon选项,双击第一项,再右击从弹出的对话框中选择Isert,单击M导入选项。
在桌面上选择所需要的图片,点击import,图片便被导入进去了,如图2所示。
图2导入图片
2)、展开Menu菜单,双击菜单中的选项,从弹出的界面中的菜单栏,右击选择属性,在C标题重输入所要建立的绘图板的主界面的菜单栏选项和ID号(如图3所示),依次操作。
图3设置画笔的界面
工具栏和菜单栏当中的ID号如表一所示:
表1各个菜单项对应的ID号
ID号
属性
作用
ID_RECT
绘制矩形
从菜单栏中选择绘制矩形
ID_CIRCLE
绘制圆形
从菜单栏中选择绘制圆形
ID_LINE
绘制直线
从菜单栏中选择绘制直线
IDD_PENSTYLE
各类画笔的选择
从菜单栏中选择绘图所用的画笔
IDD_SELECT
工具
从菜单栏中选择应用的工具
ID_LINE
线段
在工具栏中直接选择绘制线段
ID_RECT
矩形
在工具栏中直接选择绘制矩形
ID_CIRCLE
圆形
在工具栏中直接选择绘制圆形
ID_COLOR
颜色菜单选择项
在工具栏中选择绘制图形所用的颜色
ID_FONT
字体
在工具栏中选择绘制图形所用的字体
ID_PEN
虚体
在工具栏中选择绘制虚体图形所用
ID_BRUSH
实体
在工具栏中选择绘制实体图形所用
3)、图片被导入进去以后,还需要展开Toolbar选项,双击Toolbar选项当中的IDR_DRAWTOOLS选项,在从IDR_DRAWTOOLS选项中选择所需要的菜单栏,将刚刚被导入进去的图片黏贴过来,这时当在以后运行程序的时候绘图板的主界面就会显示所建立的颜色选择菜单栏的图片。
随后,在IDR_DRAWTOOLS其它的菜单栏中,依次输入绘图板的主界面所需要的文字,在打开VC++6.0显示屏的右方我们会看到A(Text)选项,然后点击A(Text)选项,在弹出的对话框中输入所要在绘图板的主界面上所要显示的工具栏文字即可。
依次操作,完成后,如图4所示。
图4工具栏的设计图
4)、就这样,绘图板的基本的主界面中的菜单栏和工具栏(界面的设计),已基本完成。
用户在绘制图形时,可根据自身的需要选择菜单栏和工具栏当中的选项,已完成绘图。
5)、绘图板的主界面完成以后,这只是在实际的操作中完成了主界面的设计。
简单的来说,就是此时的主界面,还没有完成理论上的设计。
绘图板的主界面还不能够在VC++6.0程序运行的时候出现,这样用户就无法利用绘图板进行绘制图形,而我们所设计的绘图板的主界面也就毫无意义了。
因此,这就需要我们来完成,当用户在运行绘图板VC++6.0程序的时候,我们所设计的绘图板的主界面,就会出现在用户的面前,这样用户就可以根据自身的需要进行绘制图形了。
完成绘图板的理论的设计需要代码的实现,在上面建立的工程里,点击ClassView选项。
展开CmainFrame菜单,找到展开的CmainFrame菜单当中的OnCreate(LPCREATESTREATESTRUCTIpCreateStruct)选项,双击OnCreate(LPCREATESTREATESTRUCTIpCreateStruct)选项,在//TODO:
Deletethesethreelinesifyoudon'twantthetoolbarto;//bedockable语句的后面,添加以下语句,具体如下:
if(!
m_wndDrawTool.CreateEx(this,TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|CBRS_LEFT|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_SIZE_DYNAMIC)||!
m_wndDrawTool.LoadToolBar(IDR_DRAWTOOLS))
{TRACE0("failedtocreatetoolbar\n");
return-1;
}
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
m_wndDrawTool.EnableDocking(CBRS_ALIGN_LEFT);
DockControlBar(&m_wndDrawTool);
这些VC++6.0的代码,最主要的功能就是,帮助我们在当用户运行VC++6.0程序的时候,我所设计的绘图板的主界面会出现在用户的面前。
这样,当这些VC++6.0语句加上以后,当用户在运行绘图板VC++6.0程序的时候,已经设计好了的绘图板的主界面就会随着绘图板VC++6.0程序的运行,进而出现在用户的面前。
6)、绘图板的主界面的基本框架虽然已经设计完成了,但是,其主界面的背景还没有设计。
具体步骤如下:
在上面建立的工程里,点击ClassView选项。
展开Cmy20101221View类,找到展开的Cmy20101221View类当中的OnDraw(CDC*pDC)选项,双击OnDraw(CDC*pDC)选项,在//CMy20101221Viewdrawing语句的后面,添加以下语句,具体如下:
voidCMy20101221View:
:
OnDraw(CDC*pDC)
{
CMy20101221Doc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:
adddrawcodefornativedatahere
CBrushClientBrush(RGB(255,255,255));
CRectrect;
GetClientRect(&rect);//获得整个用户区
……
}
else
{
CPenpen,*poldpen;
pen.CreatePen(m_penstyle,m_lwidth,m_color);
poldbrush=MemDC.SelectObject(&ClientBrush);
MemDC.Rectangle(&rect);//画一个用户区大小的矩形
……
}
这些代码的主要作用就是,在已经设计好了的绘图板的主界面的基本框架内添加上背景,当用户在运行绘图板的程序的时候,整个绘图板的主界面将呈现在用户的面前。
自此,绘图板的整个主界面已经全部完成了,其运行程序后的绘图板的主界面如图5所示。
图5绘图板主界面
(3)绘图板各类功能的实现过程:
1)、想要实现绘图板的各项功能,要在自己已经建立的工程里面,再建立类。
具体自己所建立的类(不包括系统自动生成的类)以及所要实现的最主要的功能如表二所示
表2类的功能表
类名
最主要的功能
CSettingDlg
最主要是设置绘图板在用户绘制图形的时候所选择的线宽和类型(如图6所示)。
CToolDlg
最主要是实现绘图板的主界面上的菜单栏当中工具这一项的功能(如图7所示)。
建立这两个类的主要的过程是,在上面建立的工程里,点击ClassView选项。
在ClassView选项所有的类的选项上找到20101221classes选项,右击20101221classes选项,在弹出的对话框当中查找到NewClass选项,点击NewClass选项,在弹出的方框当中,将
Classtype选项当中的MFCClass选项,更改为GenericClass选项。
在Classinformation
图6线宽的设置图7粗细画笔的选择
当中的Name:
右端的方框内输入所要建立的类的类名CSettingDlg,然后再点击OK,新建立的类就完成了。
此时,在20101221classes选项下面,就会出现新增加的类CsettingDlg。
具体如图8所示
图8成员函数的建立
另外,CtoolDlg类的建立过程,和CSettingDlg类的建立过程是一样的,仅以CSettingDlg类的建立过程为例,CtoolDlg类的建立过程就不再复述了。
实现带画框弹出功能的代码如下:
voidCMy20101221View:
:
OnPenstyle()
{
CSettingDlgdlg;设置画笔类型对话框类,并显示画笔设置对话框,通过对话框设置画笔类型和画笔宽度。
if(IDOK==dlg.DoModal())
{m_penstyle=dlg.m_style;
m_lwidth=dlg.m_width;
}
粗细画笔的选择功能实现代码如下:
voidCMy20101221View:
:
OnSelect()
{
CToolDlgdlg;
if(IDOK==dlg.DoModal())
m_gtype=dlg.m_type;
}
2)、对于类向导的建立,在VC++6.0的界面上的左端,点击ResourceView选项,将Toolbar展开后,选中Toolbar选项当中的第一个选项。
打开VC++6.0的界面上菜单栏当中的查看选项,选中弹出的对话框当中的第一个选项建立类向导,此时就会弹出一个对话框。
自己所建立的类所包含的数据成员,以及数据成员的描述,如表3所示。
表3数据成员的描述
类名
数据成员
数据成员的描述
CSettingDlg
m_style
画笔类型的选择
CSettingDlg
m_wide
线宽的设置
CToolDlg
m_type
粗细画笔的设置
在对话框的Classname选项当中,选中所属的类名,在ObjectIDs选项当中,选中正确的ID号,在点击AddFunction选项,此时,类向导的建立过程就完成了,每个类向导的建立过程都是这样的,以此为例,不再重复。
个各类所包含的成员函数,如表4所示。
表4成员函数表
类名
成员函数名
CSettingDlg
CsettingDlg()
CSettingDlg
DoDataExchange()
CToolDlg
CtoolDlg()
CToolDlg
DoDataExchange()
CToolDlg
OnRadio()
3)、工具栏的功能实现及代码
首先来定义这些数据成员:
在My20101221View.h里面找到
CMy20101221View,在下面添加以下代码:
classCMy20101221View:
publicCview
{…
BOOLm_lbutton;
CPointm_end;
CPointm_start;
…
public:
intm_penstyle;
intm_gtype;
COLORREFm_color;
intm_lwidth;
intm_drawtype;
}
并为他们建立类向导
首先在菜单栏中找到查看,单击查看,找到建立类向导并单击,在弹出的框里面找到Classname,在这里面找到Cmy20101221View,然后在ObjectIDs:
找到WOnLButtonDown双击然后选择COMMAND最后单击AddFunction,最后点击确定。
就这样分别为WOnLButtonUp等建立类向导。
如图六所示
图9建立类向导
4)、划线功能的实现及代码
voidCMy20101221View:
:
OnDraw(CDC*pDC)
{……
if(m_drawtype==0)
{
MemDC.MoveTo(m_start);
MemDC.LineTo(m_end);
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);
}
……
}
将画直线设置为0
voidCMy20101221View:
:
OnLine()
{
m_drawtype=0;
}
鼠标移动过程中获得划线最后一点的坐标,并调用OnDraw()函数画图
voidCMy20101221View:
:
OnMouseMove(UINTnFlags,CPointpoint)
{……
if(m_lbutton)
{
if(m_drawtype==0)
{
m_end=point;
Invalidate();
}
……
}
5)、画矩形功能的实现及代码
voidCMy20101221View:
:
OnDraw(CDC*pDC)
{
……
elseif(m_drawtype==1)
{
MemDC.Rectangle(m_start.x,m_start.y,m_end.x,m_end.y);
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);
}
……
}
将画矩形设置为1
voidCMy20101221View:
:
OnRect()
{
m_drawtype=1;
}
鼠标移动过程中获得矩形最后一点的坐标,并调用OnDraw()函数画图
voidCMy20101221View:
:
OnMouseMove(UINTnFlags,CPointpoint)
{
……
elseif(m_drawtype==1)
{
m_end=point;
Invalidate();
}
……
}
6)、画圆功能的实现及代码
voidCMy20101221View:
:
OnDraw(CDC*pDC)
{
……
elseif(m_drawtype==2)
{
MemDC.Ellipse(m_start.x,m_start.y,m_end.x,m_end.y);
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);
}
……
}
将画圆设置为2
voidCMy20101221View:
:
OnCircle()
{
m_drawtype=2;
}
鼠标移动过程中获得圆最后一点的坐标,并调用OnDraw()函数画图
voidCMy20101221View:
:
OnMouseMove(UINTnFlags,CPointpoint)
{
……
elseif(m_drawtype==2)
{
m_end=point;
Invalidate();
}
……
}
7)、用户在绘制图形的时候,绘图颜色的设置,显示颜色对话框,并获取对话框中用户选择的颜色,代码如下所示。
voidCMy20101221View:
:
OnColor()
{
CColorDialogdlg(m_color=0,CC_FULLOPEN);if(dlg.DoModal()==IDOK)
{
m_color=dlg.GetColor();
}
}
8)、字体功能及代码,显示字体对话框
voidCMy20101221View:
:
OnFont()
{
LOGFONTlf;//定义字体结构
memset(&lf,0,sizeof(LOGFONT));//分配内存
strcpy(lf.lfFaceName,"TimesNewRoman");
CFontDialogdlg(&lf,CF_EFFECTS|CF_SCREENFONTS,0,this);
if(dlg.DoModal()==IDOK)
{
CClientDCdc(this);
dlg.GetCurrentFont(&lf);
CFontfont;
font.CreateFontIndirect(&lf);
dc.SelectObject(&font);
Invalidate();
}
}
9)、画笔和画刷的设置及代码
voidCMy20101221View:
:
OnBrush()
{
m_gtype=0;//将画刷设置为0
}
voidCMy20101221View:
:
OnPen()
{
m_gtype=1;//将画笔设置为1,默认值为1
}
10)、画图过程的实现及代码,按下鼠标左键,在客户区获得第一个点和鼠标左键弹起画图结束
voidCMy20101221View:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
m_lbutton=true;
m_start=point;
CView:
:
OnLButtonDown(nFlags,point);
}
voidCMy20101221View:
:
OnMouseMove(UINTnFlags,CPointpoint)
{
if(m_lbutton)//鼠标移动过程中获得最后一点的坐标,并调用OnDraw()函数画图
……
CView:
:
OnMouseMove(nFlags,point);
}
voidCMy20101221View:
:
OnLButtonUp(UINTnFlags,CPointpoint)
{
m_lbutton=false;
CView:
:
OnLButtonUp(nFlags,point);
}
11)、双缓存的设置,防止画图过程中屏幕的闪
voidCMy20101221View:
:
OnDraw(CDC*pDC)
{
……
MemDC.SelectObject(poldbrush);
poldbrush=MemDC.SelectObject(&brush);
……
MemDC.SelectObject(poldbrush);/*获得原始画刷,也就是释放当前画刷*/
MemDC.SelectObject(pOldBitmap);
brush.DeleteObject();
MemDC.DeleteDC();
bitmap.DeleteObject();
}
……
MemDC.SelectObject(poldpen);
MemDC.SelectObject(pOldBitmap);
pen.DeleteObject();
MemDC.DeleteDC();
bitmap.DeleteObject();
……
}
四、遇到的问题及解决方法
在制作绘图板的过程当中,我确实遇到了很多的问题,其主要的原因还是由于在前期学习C++课程的时候,没能真正的理解C++的编程理念。
(1)、再设计绘图板的主界面的时候,不知道设置哪些菜单栏和工具栏。
其主要的解决办法是,通过查看面向对象程序设计(C++语言)当中的第十二章的内容。
一次了解了,所要设计的绘图板所要实现的功能主要是,绘制线段、矩形、圆等图形。
对绘图板的功能了解了以后,就知道了,绘图版主界面的工具栏和菜单栏,最主要是设置绘制这些图形的快捷键,以及在用户绘制图行的时候所需要的颜色和字体的工具栏。
(2)、在设计绘图板主界面工具栏的时候,所需要的图片,不知道该怎么导入。
其主要的解决办法是,通过查看课本、询问同学,得知:
右击桌面上的我的电脑,选择搜索,在全部或部分文件名的下方矩形框中输入.ico,从中搜索所需要的图片,在复制到桌面上以备用。
在所建的工程里展开Icon选项,双击第一项,再右击从弹出的对话框中选择Isert,单击M导入选项。
在桌面上选择所需要的图片,点击import,图片便被导入进去了,将图片导入进去以后,还不能够在绘图板的主界面上的工具栏上显示出来。
要想在绘图板的主界面上的工具栏上显示出来,还需要展开Toolbar选项,双击Toolbar选项当中的IDR_DRAWTOOLS选项,在从IDR_DRAWTOOLS选项中选择所需要的菜单栏,将刚刚被导入进去的图片黏贴过来,这时当在以后运行程序的时候绘图板的主界面就会显示所建立的颜色选择菜单栏的图片。
(3)、当我在对绘图板的主界面和一些画笔设计完成了以后,自己在绘制图形的时候,出现了这样