MFC课程设计实验报告.docx
- 文档编号:28412740
- 上传时间:2023-07-13
- 格式:DOCX
- 页数:53
- 大小:651.63KB
MFC课程设计实验报告.docx
《MFC课程设计实验报告.docx》由会员分享,可在线阅读,更多相关《MFC课程设计实验报告.docx(53页珍藏版)》请在冰豆网上搜索。
MFC课程设计实验报告
《面向对象可视化对象编程》课程设计
总结报告
班级:
学号:
姓名:
2016.12.12-2016.12.23
一、课程设计的目的
1.参加本课程设计的同学已经学习了《C语言程序设计》和《面向对象可视化编程》两门课程,现在需要通过一个相对实际性的开发过程来巩固与鉴定一下学习成效,可以查看离实际需要还有哪些部分没有完全掌握,需要加强检测;
2.本课程设计可以提供一个稍微具有规模的程序开发的例子,让同学们可以体会到程序的构思、编码以及调试的完整过程,最后并总结课程设计的过程;
3.通过本次课程设计,可以对自身做一个评估,看看在哪方面不足从而加强学习;
二、课程设计的内容与设计思路
1.课设内容
要求:
采用单文档方式,文档中存储图形画面的各个图元数据,视图负责图形的绘制。
文档支持图形的序列化(连载),提供新建、打开、保存等操作。
视图除了绘制图形,还提供图形交互,能够按住Ctrl键再鼠标左键单击来创建图元,鼠标左键双击编辑修改图元属性,鼠标右键双击删除图元。
图元创建与修改时的参数由参数对话框来编辑。
创建时以鼠标左击时光标的所在位置作为基点来创建图元。
2.设计思路
我们的最终目的是显示一个单文档窗口,且可利用从对话框中输入的数据绘制图形。
所以,首先建立一个单文档程序,再添加对话框,用来创建与修改图形参数,之后给对话框中的各复选框,编辑框,按钮添加消息响应函数,进行控件关联,并利用枚举型使参数传递。
定义一个动态数组以存储从对话框中获取的数据,之后添加Shape类,用来绘图,由Shape类定义一个指针指向动态数组,便可从中读出之前存储的数据进行绘图,从而达到目的,思路图参考如图1,2:
图1.Shape的六个派生类
图2.工程思路图解
三、程序实现过程与细节
1.涉及的主要函数列表
附表1
函数定义与功能一览表
序号
函数名
函数定义
定义所在文件名
函数功能
1
OnInitDialog()
BOOLCType:
:
OnInitDialog()
Type.cpp
对对话框进行初始化处理
2
OnOk()
voidCType:
:
OnOK()
Type.cpp
按确定按钮时调用
3
OnFillColorButton()
voidCType:
:
OnFillColorButton()
Type.cpp
按下按钮,弹出颜色选择对话框
4
OnLinelColorButton()
voidCType:
:
OnLineColorButton()
Type.cpp
按下按钮,弹出颜色选择对话框
5
OnDraw()
voidCLwhView:
:
OnDraw(CDC*pDC)
LwhView.cpp
应用程序窗口的客户区进行绘图
6
OnLButtonDown()
voidCLwhView:
:
OnLButtonDown(UINTnFlags,CPointpoint)
LwhView.cpp
按下鼠标左键,执行该函数
7
OnRButtonDblClk()
voidCLwhView:
:
OnRButtonDblClk(UINTnFlags,CPointpoint)
LwhView.cpp
双击鼠标右键时,执行该函数
8
OnSelchangeComBoxTuYuanType()
voidCType:
:
OnSelchangeComBoxTuYuanType()
LwhView.cpp
选择图元属性组合框时,显示或隐藏某个编辑框
9
Serialize()
voidCSquare:
:
Serialize(CArchive&ar)
voidCRectangle:
:
Serialize(CArchive&ar)
voidCTriangle:
:
Serialize(CArchive&ar)
voidCCircle:
:
Serialize(CArchive&ar)
voidCEllipse:
:
Serialize(CArchive&ar)
voidCText:
:
Serialize(CArchive&ar)
Shape.cpp
将表单内容序列化
10
CSquare()
CSquare:
:
CSquare()
Shape.cpp
缺省构造函数,初始化
11
CSquare()
CRectangle()
CCircle()
CEllipse()
CTriangle()
Ctext()
CSquare:
:
CSquare()
CRectangle:
:
CRectangle()
CCircle:
:
CCircle()
CEllipse:
:
CEllipse()
CTriangle:
:
CTriangle()
CText:
:
CText()
Shape.cpp
接受由对话框传递过来的参数
12
Draw(CDC*pDC)
voidCSquare:
:
Draw(CDC*pDC)
voidCRectangle:
:
Draw(CDC*pDC)
voidCCircle:
:
Draw(CDC*pDC)
voidCEllipse:
:
Draw(CDC*pDC)
voidCTriangle:
:
Draw(CDC*pDC)
voidCText:
:
Draw(CDC*pDC)
Shape.cpp
绘制函数
13
IsMatched(CPointpnt)
boolCSquare:
:
IsMatched(CPointpnt)
boolCRectangle:
:
IsMatched(CPointpnt)
boolCCircle:
:
IsMatched(CPointpnt)
boolCEllipse:
:
IsMatched(CPointpnt)
boolCTriangle:
:
IsMatched(CPointpnt)
boolCText:
:
IsMatched(CPointpnt)
Shape.cpp
图元匹配函数
图3.主要函数OnLButtonDown()
2.工程的新建
打开MicrosoftVisualC++6.0—>点击File—>New在Projects中选择MFCAppWizard(exe);在Projectname中输入工程的名字Lwh,在Location中选择工程存放的路径。
填完后点击OK按钮。
填完后点击OK按钮,在弹出来的对话框中我们选择Singledocument,再点击Finish,完成工程的创建。
之后编译运行,结果参见图3。
图4.新建工程结果示意图
3.建立图元属性对话框
点击ResouceView,右击Dialog—>插入Dialog,这时会弹出来一个对话框,双击“确定”按钮,选择“Createanewclass”,点击OK,设置类名为CType—>OK,之后设置对话框属性为IDD_TYType,参见图4,绘制对话框,参见附表2.属性表给各复选框、编辑框、按钮修改属性。
附表2
属性表
序号
名称
ID
7
角度
IDC_Angle
1
图元类型
IDC_m_ComBox_TuYuanType
8
线型
IDC_m_ComBoxLineType
2
线色按钮
IDC_LineColorButton
9
线色(R/G/B)
IDC_LineColor(R/G/B)
3
填充色按钮
IDC_FillColorButton
10
填充色(R/G/B)
IDC_FillColor(R/G/B)
4
高度
IDC_High
11
原点X
IDC_OrgX
5
宽度
IDC_Width
12
原点Y
IDC_OrgY
6
线宽
IDC_LineWidth
13
填充风格
IDC_m_ComBoxFillType
图5.构造对话框结果示意图
4.控件的关联
要实现这个步骤,首先要明白在MFC中变量的声明定义,对于控件关联型的数值变量,value类型(double,int,CString等等),在生成时向导帮你做了3件事:
1)在.h文件中进行声明;
2)在.cpp中的构造函数中,进行了初始化;
3)在.cpp文件中的DoDataExchange()中进行控件关联;
DDX_Text(pDX,IDOK,m_btnTest);
所以,要进行控件关联,要做的也是这三件事(可在ClassWizard中进行添加,则系统自动生成。
下面介绍手动添加,以图元类型IDC_m_ComBox_TuYuanType为例)
1)在Type.h中声明:
protected:
CComboBoxm_ComBox_TuYuanType;
2)在Type.cpp中进行初始化:
BOOLCType:
:
OnInitDialog()(在ClassWizard中添加)
{
CDialog:
:
OnInitDialog();
//TODO:
Addextrainitializationhere
m_ComBox_TuYuanType.AddString("正方形");
m_ComBox_TuYuanType.AddString("矩形");
m_ComBox_TuYuanType.AddString("三角形");
m_ComBox_TuYuanType.AddString("圆");
m_ComBox_TuYuanType.AddString("椭圆");
m_ComBox_TuYuanType.AddString("文本");
m_ComBox_TuYuanType.SetCurSel(0);
}
3)在Type.cpp中进行控件关联(DoDataExchange()中):
DDX_Control(pDX,IDC_ComBox_TuYuanType,m_ComBox_TuYuanType);
5.枚举型
枚举类型定义的一般形式为:
enum枚举名{ 枚举值表}。
在枚举值表中应罗列出所有可用值。
这些值也称为枚举元素。
注意枚举值是常量,不是变量,不能再对它赋值。
枚举元素本身由系统定义了一个表示序号的数值,从0开始顺序定义为0,1,2……
1)定义(Type.h)
public:
EnumTuYuanTypm_TuYuanTyp;
2)枚举(Type.h)
enumEnumTuYuanTyp
{
EnumTuYuanTyp_Square,//正方形
EnumTuYuanTyp_Rectangle,//矩形
EnumTuYuanTyp_Triangle,//三角形
EnumTuYuanTyp_Circle,//圆
EnumTuYuanTyp_Ellipse,//椭圆
EnumTuYuanTyp_Text//文本
};
3)利用枚举型传参(Type.cpp)
voidCType:
:
OnOK()
{
UpdateData();
//TODO:
Addextravalidationhere
intiSel=m_ComBox_TuYuanType.GetCurSel();//得到当前选择的索引值
switch(iSel)
{
case0:
m_TuYuanTyp=EnumTuYuanTyp_Square;
break;
case1:
m_TuYuanTyp=EnumTuYuanTyp_Rectangle;
break;
case2:
m_TuYuanTyp=EnumTuYuanTyp_Triangle;
break;
case3:
m_TuYuanTyp=EnumTuYuanTyp_Circle;
break;
case4:
m_TuYuanTyp=EnumTuYuanTyp_Ellipse;
break;
case5:
m_TuYuanTyp=EnumTuYuanTyp_Text;
break;
default:
ASSERT(0);
}
CDialog:
:
OnOK();
}
6.定义动态数组
1)定义(LwhDoc.h)
public:
CObArraym_Elements;
2)清除(LwhDoc.cpp)
//清除图元地址,释放空间
CLwhDoc:
:
~CLwhDoc()
{
for(inti=0;i { deletem_Elements[i]; m_Elements[i]=NULL; } m_Elements.RemoveAll(); } 7.建立Shape类及其子类 一个类要支持支持序列化Serialize,必须从CObject派生,并且在类的声明(.h文件)中包含DECLARE_SERIAL申明,在类的实现(.cpp)中包含IMPLEMENT_SERIAL申明。 所以,要建立支持序列化的Shape类,首先选择ClassView,鼠标右键单击工程名,选择NewClass,在类的类型中选择GenericClass,输入类名CShape,并在下方DerivedFrom中输入CObject,继承类型为public,点击确定,系统会生成相应的Shape.cpp文件和Shape.h文件。 在Shape.h中定义其成员变量和成员函数,注意OnDraw函数应定义为纯虚函数(参见附表1.函数定义与功能一览表)。 然后由Shape类派生其六个子类CSquare,CRectangle,CTriangle,CCircle,CEllipse,CText,继承方式均为public,在子类中也定义其成员函数及变量(以CSquare为例) classCShape: publicCObject { public: CShape(); virtual~CShape(); virtualvoidDraw(CDC*pDC)=0;//绘制图元 virtualboolIsMatched(CPointpnt)=0;//点是否落在图形内部 virtualvoidSerialize(CArchive&ar)=0; intOrgX; intOrgY; intwidth; inthigh; intlinewidth; intR1,R2,G1,G2,B1,B2; }; classCSquare: publicCShape { public: CSquare(); CSquare(intx,inty,intw,intline,intr1,intg1,intb1,intr2,intb2,intg2); voidDraw(CDC*pDC);//绘制 boolIsMatched(CPointpnt);//重载点pnt是否落在图元内 virtualvoidSerialize(CArchive&ar);//序列化正方形图元 private: DECLARE_SERIAL(CSquare)//声明类CSquare支持序列化 }; 在Shape.cpp中对Shape类极其子类进行序列化,并写入子类的成员函数,完成绘图和进行图元匹配功能(以CSquare为例) IMPLEMENT_SERIAL(CSquare,CObject,1)//实现类CSquare的序列化,指定版本为1 voidCSquare: : Serialize(CArchive&ar) { if(ar.IsStoring()) { ar< ar< ar< } else { ar>>OrgX>>OrgY;//原点坐标 ar>>width; ar>>linewidth;//线宽 } } CSquare: : CSquare()//缺省构造函数,初始化 { OrgX=400;//原点坐标 OrgY=400; linewidth=1;//线宽 width=100; } CSquare: : CSquare(intx,inty,intw,intline,intr1,intg1,intb1,intr2,intb2,intg2) { OrgX=x;//原点坐标 OrgY=y; linewidth=line; width=w; R1=r1; R2=r2; G1=g1; G2=g2; B1=b1; B2=b2; } voidCSquare: : Draw(CDC*pDC)//绘制函数 { CPenpen,*pOldPen; pen.CreatePen(PS_SOLID,linewidth,RGB(R1,G1,B1)); pOldPen=(CPen*)pDC->SelectObject(&pen); CBrushbrush,*pOldBrush; brush.CreateHatchBrush(HS_DIAGCROSS,RGB(R2,G2,B2)); pOldBrush=(CBrush*)pDC->SelectObject(&brush); pDC->Rectangle(OrgX-width/2,OrgY-width/2,OrgX+width/2,OrgY+width/2); pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush); } boolCSquare: : IsMatched(CPointpnt)//图元匹配函数 { if((OrgX-width/2<=pnt.x&&pnt.x<=OrgX+width/2)&&(OrgY-width/2<=pnt.y&&pnt.y<=OrgY+width/2)) returntrue; else returnfalse; } 8.OnDraw() 由于Shape.cpp调用了Ondraw()函数,而OnDraw()函数的定义是在LwhView.cpp中(参见附表1.函数定义与功能一览表),故应该在LwhView.cpp中对Ondraw()进行调用声明,代码如下: voidCLwhView: : OnDraw(CDC*pDC) { CLwhDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); CShape*p=NULL; if(pDoc->m_Elements.GetSize()>0) { for(inti=0;i { p=(CShape*)pDoc->m_Elements[i]; p->Draw(pDC); } } //TODO: adddrawcodefornativedatahere } 9.鼠标左键消息响应函数 按下Ctrl+W组合键,在弹出的MFCClassWizard对话框中选择MessageMap,在Classname选择CLwhView类,在ObjectID中选择CLwhView,在右边的Messages中为其添加鼠标左键的消息响应函数OnLButtonDown,双击OnLButtonDown函数(参见附表1.函数定义与功能一览表),出现OnLButtonDown()的定义模块,写入以下代码: CTypedlg; if((nFlags&MK_CONTROL)==MK_CONTROL)//Ctrl键按下 dlg.DoModal(); 即可实现在单文档运行界面按下Ctrl+鼠标左键弹出对话框的操作,但是,要实现当弹出对话框按下OK键就可以画出图形的操作,就得利用枚举型传过来的参数进行选择判断(switch语句),然后执行画图操作(以CSquare为例) if(dlg.DoModal()==IDOK) { switch(dlg.m_TuYuanTyp) { caseEnumTuYuanTyp_Square: { p=newCSquare(dlg.X,dlg.Y,dlg.Width,dlg.LineWidth, dlg.LineColorR,dlg.LineColorG,dlg.LineColorB, dlg.FillColorR,dlg.FillColorG,dlg.FillColorB); break; } …… } } 当不按下Ctrl键,直接按左键,要进行修改图元属性的功能,则也是在此处添加相应代码,对应之前的按下Ctrl键的if语句,写入else语句,添加重新绘图的功能代码即可。 (具体见主要代码清单) 10.鼠标右键双击消息响应函数 与添加鼠标左键消息相应的方法一样(参见附表1.函数定义与功能一览表),先在ClassWizard中添加,双击进入定义模块,要实现右键双击删除,并弹出一个警告是否删除的对话框,首先得明白我们基于图元的数据存储在于动态数组m_Elements,所以,要删除图元,只需删除该图元对应数组中存储的数据即可,主要代码如下: for(inti=0;i { p=(CShape*)pDoc->m_Elements[i]; if(p->IsMatched(pntLogical)) { CCutcut; if(cut.DoModal()==IDOK) { pDoc->m_Elements.RemoveAt(i); deletep; Invalidate(); } } } 11.颜色按钮 CColorDialog类实现了标准的颜色对话框,因此用创建CColorDialog类的对象去调用DoModal()函数,即可显示出对话框,如果DoModal()返回IDOK, 则用GetColor()来获取颜色对话框中选择的颜色值,以下是线色按钮的相关代码: voidCType: : OnLineColorButton() { //TODO: Addyourcontrolnotificationhandlercodehere COLORREFcolor=RGB(47,78,107);//颜色对话框的初始颜色 CColorDialogcolorDlg(color);//构造颜色对话框,传入初始颜色值 if(IDOK==colorDlg.DoModal()) { color=colorDlg.GetColor();//
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MFC 课程设计 实验 报告