C++程序设计课程设计报告
题目:用VC++制作多功能计算器
学生姓名: 学 号: 院 (系): 专 业:
2011 年 9 月 9 日
目 录
摘要 .......................................................................................................................... 2 1 引言 .................................................................................................................... 2
1.1 课题背景 ................................................................................................... 2 1.2课程设计目的 ............................................................................................ 2 2 开发工具的介绍 ................................................................................................ 3 2.1关于Visual C++ ......................................................................................... 3 2.2可行性分析 ................................................................................................ 4 2.3需求分析 .................................................................................................... 4 3 功能说明 ............................................................................................................ 4 4 系统的实现 ........................................................................................................ 5
4.1窗体设计 .................................................................................................... 5 4.2编辑资源 .................................................................................................... 6 4.3实现高级按钮控件类 ................................................................................ 8 4.4实现高级编辑控件类 .............................................................................. 12 4.5对话框界面设计 ...................................................................................... 15 4.6数值计算功能的实现 .............................................................................. 20 5 程序结果的演示 .............................................................................................. 21
5.1测试的研究与选择 .................................................................................. 21 5.2测试环境 .................................................................................................. 21 5.3实例测试结果 .......................................................................................... 22 结束语 .................................................................................................................... 23 参考文献 .............................................................................................................. 23
用VC++制作多功能计算器
摘 要 本课程设计将实现一个简单计算器。其类似于Windows附件中自带的计算器。这个计算器不仅实现了简单的四则运算功能,还实现了高级的科学计算功能,而且具有简洁大方的图文外观。它的设计按软件工程的方法进行,系统具有良好的界面、必要的交互信息和较好的健壮性使用人员能快捷简单地进行操作。即时准确地获得需要的计算的结果,充分降低了数字计算的难度和节约了时间,对人们的生活有一定的帮助。在课程设计中,系统开发平台为Windows 2000XP,程序设计设计语言采用Visual C++,在程序设计中,采用了结构化与面向对象两种解决问题的方法。
关键词 程序设计;计算器;MFC;按钮控件
1 引 言
本课程设计主要在运算过程中,如果通过计算器来完成,就会减少计算量,该程序即可以在简单计算器键面下进行简单运算,也可以在科学计算器键面下进行高级的科学计算。并且可以分别计算弧度、角度的三角函数的计算等较为复杂的运算。
1.1 课题背景
计算器是日常生活中十分便捷有效的工具,能实现加、减、乘、除、开方、求倒数等简单运算的工具。要实现计算功能,可以用VC++的知识编写程序来解决此问题。该计算器大大的降低了数字计算的难度及提高了计算的准确度和精确度。该计算器使用非常简单和方便,对广大中小学生的学习有巨大帮助作用,也对在职人员的工作有点帮助作用。
1.2 课程设计目的
在程序设计中,通过设计、编制、调试一个模拟计算器的程序,加深对语法及语义分析原理的理解,并实现对命令语句的灵活应用。在程序设计中,可以用两种方法解决问题:一是传统的结构化程序设计方法,二是更先进的面向对象程序设计方法。
由于多个函数均需要访问某些数据,这些数据常被设计为全局变量。
而在面向对象程序设计中关键是如何将问题域中的实体(即日常所见的概念)抽取出来,作为C++程序中的类,而属性与行为作为类的两类要素通常是必不可少的,甚至还应考虑类必须满足的约束。
2 开发工具的介绍
2.1 关于Visual C++
Visual C++6.0 是Microsoft公司在1998年推出的基于Windows 9X和Windows NT的优秀集成开发环境。该环境为用户提供了良好的可视化编程环境,程序员可以里利用该开发环境轻松地访问C++源代码编辑器,资源编辑器和使用内部调试器,并且可以创建项目文件。Visual C++6.0不仅包括编译器,而且它还包括许多有用组件,通过这些组件的协同工作,可以在Visual C++6.0集成环境中轻松地完成创建源文件,编辑资源,以及对程序的编译,连接和调试等各项工作。
VC++6.0是Windows 95/98、XP或Windows NT下的一个应用程序,本身对软硬件没有特殊要求。就是说它对环境的要求与Windows 95/98、Windows NT要求是一致的。
硬件要求:一般在586以上的处理器、16MB以上内存、100MB以上的硬盘。 软件要求:Windows 95/98或Windows NT3.51以上版本。
VC++ 6.0系统可以在一张CD盘上,也可以在“Visual Studio( Visual C++、Visual Foxpro)”等产品的第一张CD盘上。一般都有一个VC的自动安装程序,也可以执行VC6目录下的setup.exe,在安装包的提示下进行,对初学者可采用“典型安装”方式。
在安装好VC 6.0系统后,有时根据需要添加或删除某些部件,可插入CD盘重新执行setup.exe安装程序,安装程序会检测当前系统安装VC6的足件,用户单击“添加/删除”按钮后,在“安装维护”对话框中选定要添加的部件或撤消选定要删除的部件。 与一般的应用软件一样,有以下两种启动方式:
(1)通过“开始”按钮,选择“程序”菜单,然后打开“Microsoft Visual studio 6.0中文版”子菜单中的“Microsoft Visual C++ 6.0 中文版”程序。
(2)用户也可以使用命令行启动VC。单击“开始”按钮后选择“运行”命令,在“运行”对话框中输入c:\\Program Files\\Microsoft Visual Studio\\VC98\\VC6.exe(按默认盘符和路径安装)即可。
2.2 可行性分析
本设计是简单计算器。日常计算机使用中,常常涉及到一些有关计算的问题,一个小型的计算器软件变得非常有用,该校型计算器需要空间资源较少,对电脑其他程序的应用影响较小。它的设计按软件工程的方法进行,系统具有良好的界面、必要的交互信息和较好的健壮性;醒目美观的软件封面。使用人员能快捷简单地进行操作。即时准确地获得需要的计算的结果,充分降低了数字计算的难度和节约了时间,对人们的生活有一定的帮助。
2.3 需求分析
本软件主要用于计算机windows 2000/XP以上版本的用户的使用,这次课程设计一般是实现简单计算器的功能。要程序能实现:加,减,乘,除,开方,倒数等运算功能;还要实现数据的输入,输出,计算,显示及程序退出等功能。另外还可以实现多种科学计算的功能,如:三角函数的计算,弧度与角度间的转换,对数指数的计算等等。
3 功能说明
它的设计按软件工程的方法进行,系统具有良好的界面;必要的交互信息;简约美观的效果。使用人员能快捷简单地进行操作。即可单机按钮进行操作,也可直接通过键盘直接输入。即时准确地获得需要的计算的结果,充分降低了数字计算的难度和节约了时间,对人们的生活有一定的帮助。
(1)包含的功能有:加、减、乘、除运算,开方、求倒数等功能[1].
(2)计算器上数字0—9为一个控件数组,加、减、乘、除为一个控件数组,其余为单一的控件。
(3)给对话框添加菜单。
(4)制定高级按钮控件,该按钮具有不规则的形状,可以根据用户鼠标的位置和单击状态的不同,显示不同的颜色[3]。
(5)制定高级编辑控件,该编辑控件可以指定文本文字的字体和颜色。
(6)输入的原始数据、运算中间数据和结果都显示在窗口顶部的同一个标签中。 (7)实现对话框的扩展功能[2]。
(8)计算功能基本上是用系统内部函数。
(9)程序可以能自动判断输入数据的正确性,保证不出现多于一个小数点、以0开头等不正常现象。
(10)“CE”按钮可以清除所有已输入的数据从头计算 功能模块的实现:
(1)首先,添加高级按钮控件类,在这个类中实现高级的按钮控件。在此类中对于所有的对于按钮的绘制工作都是在DrawItem函数中完成的,实现按钮对鼠标不同的位置和动作改变不同的颜色,并且按钮的客户区域变成一个椭圆。
(2)其次,添加一个高级编辑控件类,在此类的基础上实现高级编辑控件。在OnDisplay函数中设置编辑框的显示文本,再调用OnDraw函数将其显示出来,并用指定的画刷填充客户区,并且用指定的颜色绘制显示文本。
(3)最后,实现主对话框界面功能,主要是加载菜单资源和对话框扩展功能的实现。在CCalculatorDlg::OnCreate函数中设定对话框的初始大小与位置,可以在这个对话框中进行窗口风格修改,位置设置等操作,然后添加菜单项ID_EXTEND的响应函数OnExtend。
4 系统的实现
4.1 窗体设计
利用MFC AppWinzard生成计算器应用程序框架具体步骤如下:
(1)执行VC程序,选择File|New命令,弹出New对话框.单击Projects标签,转到Projects选项卡,选择MFC AppWizard(exe)选项,然后在Project name文本框中输入Calculator 。Lacation文本框是指项目的本地路径。
(2)单击OK按钮,弹出MFC AppWinzard_Step1对话框。选中单选按钮,如图所示。 (3)单击Next按钮,弹出MFC AppWinzard_Step2 of4对话框,如图所示。 (4)单击Next按钮,弹出MFC AppWinzard_Step3 of4对话框,如图所示。 (5)单击Next按钮,弹出MFC AppWinzard_Step4 of4对话框,如图所示。单击Finish按钮,创建框架。
4.2 编辑资源
(1)编辑对话框及控件资源
利用Visual C++提供的资源编辑器对对话框资源进行编辑。删除对话框中默认的OK和Cancel按钮。添加一个Edit控件,其控件ID为IDC_DSPEDIT。添加若干按钮控件,其ID如表4-1所示。
表4-1 按钮控件资源清单
按钮名称 0 1 2 3 4 5 6 7 8 9 。 = + - * / CE Sqrt 1/x sin cos tan x^2 x^3 x^y exp ln log -/+ 按钮ID BTN_0 BTN_1 BTN_2 BTN_3 BTN_4 BTN_5 BTN_6 BTN_7 BTN_8 BTN_9 BTN_10 BTN_11 BTN_12 BTN_13 BTN_14 BTN_15 BTN_16 BTN_17 BTN_18 BTN_19 BTN_20 BTN_21 BTN_22 BTN_23 BTN_24 BTN_25 BTN_26 BTN_27 BTN_29 按键0 按键1 按键2 按键3 按键4 按键5 按键6 按键7 按键8 按键9 用途 小数点 求值 加号 减号 乘号 除号 清屏 开方 倒数 正弦 余弦 正切 平方 立方 以X为底的y次幂 以e为底的幂 以e为底的对数 对数 正负号
10^x n! BTN_30 BTN_31 10的x次方 N的阶层 添加2个单选按钮,按钮资源清单如下
表4-2 单选按钮控件资源清单
控件名 DEGREE RADIAN 设置ID BTN_DEGREE BTN_RAD 添加4个静态框,将编辑控件,普通计算,高级计算分别分组。其效果如图4-1所示。
图4-1编辑对话框资源
(2)编辑菜单资源
在Visual C++中的Workspace工具栏中,选中ResourceView选项卡。在其中的Menu项上右击,在弹出的快捷菜单中选择Insert命令,如图4-2所示。
图4-2添加菜单资源
将添加的菜单资源的ID更改为IDR_MENU。利用资源编辑器对菜单进行编辑,编辑后的菜单如图4-3所示。
图4-3 编辑菜单资源
4.3 实现高级按钮控件类
利用ClassWizard添加一个新类,如图4-5所示。
图4-5添加CAdvButton类
(1)添加成员变量和成员函数
为实现高级按钮控件对鼠标的移动和单击作出相应的颜色变化。首先在CAdvButton的头文件中加入几种预定义颜色,其代码如下:
#define DesiableColor RGB(192,192,192) //灰色, 按钮不可用 #define FocusColor RGB(255,0,0) //红色, 按钮拥有焦点 #define SelectColor RGB(0,255,0) //绿色, 按钮被按下 #define DefaultColor RGB(0,0,255) //蓝色, 默认 #define TextColor RGB(128,128,128) //浅灰色, 文本颜色 接下来,添加成员变量: public:
CRect m_ClientRect; //用来保存按钮的客户的矩形区域 CRgn m_ClientRgn ; //用来保存按钮的客户区域,非矩形 UINT m_State; //按钮所处状态 CPoint m_Point; //当前鼠标位置
BOOL m_IsTimerOn; //标识计时器是否已经打开 利用ClassWizard添加消息映射和响应函数:
图4-6添加响应函数
再利用ClassWizard覆盖父类中的两个关键的虚函数: //{{AFX_VIRTUAL(CAdvButton) public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); protected:
virtual void PreSubclassWindow(); //}}AFX_VIRTUAL
其中对于所有的对于按钮的绘制工作都是在DrawItem函数中完成的。
(2)添加创建按钮控件代码
按钮的创建分两步完成。首先,调用构造函数对按钮对象进行初始化;其次,调用Create函数创建按钮。代码如附录1所示。
(3)设置按钮形状、外观、颜色、标题
PreSubclassWindow函数在窗口被创建之前就被调用,因此,在PreSubclassWindow函数中,将按钮的风格设为BS_OWNERDRAW。实现代码如下:
//修改按钮控件风格
ModifyStyle(0,BS_OWNERDRAW|BS_PUSHBUTTON);
要使按钮能对鼠标的移动与单击作出不同的变化,那么按钮就需要时刻知道鼠标的位置与动作。所以,必须在鼠标的单击、弹起及移动消息的响应函数中填加相应的代码,
以获取鼠标的位置与动作。
在鼠标左键按下时,得到按钮窗口客户区域的屏幕坐标位置和鼠标的屏幕坐标位置。当鼠标坐标位落于窗口客户区域内,且当前按钮控件处于非选中状态时,将按钮状态标识设为选中状态,即将m_State设为2。接着,调用Invalidate函数,使客户区无效,框架会自动调用DrawItem函数,重绘客户区。实现代码如下:
//当鼠标在按钮的客户区内按下时,改变按钮状态
void CAdvButton::OnLButtonDown(UINT nFlags, CPoint point) {
CRect rect;
GetWindowRect(&rect); //得到按钮客户区域的屏幕坐标位置 GetCursorPos(&m_Point); //得到鼠标的屏幕坐标位置 if((rect.PtInRect(m_Point))&&(m_State != 2)) {
m_State = 2; //2:select state Invalidate(); //重绘客户区 }
CButton::OnLButtonDown(nFlags, point); }
在鼠标左键抬起时,得到按钮窗口客户区域的屏幕坐标位置和鼠标的屏幕坐标位置。当鼠标坐标位置落于窗口客户区域内,且当前按钮控件处于选中状态时,将按钮状态标识设为非选中状态,即将m_State设为1。接着,调用Invalidate函数,使客区无效,框架会自动调用DrawItem函数,重绘客户区。其代码如附录1所示。
在用户移动鼠标时,如果计时器没有启动,则启动计时器,并将计时器启动标识m_IsTimerOn设为TRUE。其实现代码如下:
if(!m_IsTimerOn) //如果计时器没用启动 {
SetTimer(1000,100,NULL); //启动计时器 m_IsTimerOn = TRUE; }
如果鼠标已经移出了按钮的客户区,则消毁计时器,并将计时器的起始标识 m_IsTimerOn设为FALSE。OnTimer函数的实现代码如附录1所示。
实现客户区的绘置函数DrawItem。在DrawItem函数中,首先得到窗口的有效矩形区域,在此矩形区域内创建椭圆。调用SetWindowRgn函数,设置窗口的有效区域为椭圆。从参数lpDrawItemStruct结构中得到按钮控件客户区域的设备环境变量指针。根据按钮当前状态,创建不同的画笔。调用设备环境类的成员函数,设置背景模式为透明,选择画笔,在按钮客户区内绘制椭圆及显示文本。其实现代码如附录1所示。
通过上面操作,按钮已经具有对鼠标不同的位置和动作改变不同的颜色。并且,按钮的客户区域已经是一个椭圆,而不再是一个矩形。正是下面的代码将按钮的客户区域设定为椭圆形:
GetClientRect(&m_ClientRect); //通到窗口的有效矩形区域 m_ClientRgn.DeleteObject(); //删除区域对象
m_ClientRgn.CreateEllipticRgnIndirect(&m_ClientRect); //在矩形区域内创建椭圆 //设置窗口的有效区域为椭圆 SetWindowRgn(m_ClientRgn,FALSE);
至此,一个完整的高级按钮类全部完成。其效果如图4-7所示。
图4-7运行结果
4.4 实现高级编辑控件类
利用ClassWizard添加一个新类,如图4-8所示.
图4-8添加CAdvEdit
(1)添加成员变量和成员函数
为CAdvEdit类添加一个字符串类型的成员变量m_Caption,用来记录编辑框中的文本内容。其实现代码如下:
//CAdvEdit头文件 public:
CString m_Caption; //编辑框文本
利用AppWizard添加消息函数OnPaint。如图4-9所示。
图4-9添加函数
添加两个public类型的成员函数,分别用来绘制编辑控件客户区和设置编辑控件的显示文本。实现代码如下:
public:
void OnDraw(); //绘制编辑控件客户区
void OnDisplay(LPCTSTR lpszStr); //设置编辑控件显示文本 protected:
//{{AFX_MSG(CAvEdit)
Afx_msg void OnPaint(); //WM_ON_PAINT消息的响应函数 //}}AFX_MSG
图4-10添加成员变量
(2)添加编辑控件代码
在OnDisplay函数中设置编辑框的显示文本。实现代码如下: m_Caption = lpszStr;
OnDraw();
在OnPaint函数中调用自定义函数OnDraw。实现代码如下:
CPaintDC dc(this); // device context for painting OnDraw();
在OnDraw函数中,在编辑控件客户区域内绘制文本。首先,得到编辑控件客户区的矩形域;其次,得到编辑控件客户区的设备环境变量;接着,用指定的画刷填充客户区,并且用指定的颜色绘制显示文本。效果如图4-11所示,其代码如附录2所示。
图4-11运行结果
4.5 对话框界面设计
对主对话框添加成员变量和函数。 主要成员变量:
//CCalculatorDlg.h头文件 CButton m_DspStatic;
CAdvEdit m_DspEdit; //显示计算结果的编辑框 CMenu* m_Menu; //对话框菜单按钮 BOOL m_IsExtend; //标志对话框是否已扩展
主要成员函数: //CCalculatorDlg.h头文件
//{{AFX_VIRTUAL(CCalculatorDlg) Protected:
virtual void DoDataExchange(CDataExchange*pDX);//数据交换函数 //}}AFX_VIRTUAL
virtual BOOL OnInitDialog();//虚函数,可覆盖用来进行用户初始化操作 virtual void OnOK();//虚函数,覆盖用来屏蔽Enter操作
//{{AFX_MSG(CCalculatorDlg)
//响应消息 ON_WM_CTLCOLOR,用以修改对话框及其控件颜色 afx_msg HBRUSH OnCtlColor(CDC*Pdc,CWnd*pWnd,UINT nCtlColor);
afx_msg void OnPaint(); //响应消息WM_ON_PAINT
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);//响应消息WM_ON_CREATE //}}AFX_MSG
除以上主要成员外,还要对每个按钮控件定义一个CAdvButton的对象与之相关联,并为每个按钮控件建军立一个成员函数来响应其EN_CLICKED消息。如图4-12所示:
图4-12为按钮控件添加消息响应
(1)加载菜单资源
在3.2节中,已经为工程新建了一个菜单资源IDR_MENU,现将其添加到计算器
对话框上。利用CMenu类的LoadMenu函数,将菜单资源加载到内存中。再调用SetMenu函数,将菜单添加到对话框上,代码如附录3所示。如图4-13所示:
图4-13运行结果
(2)关联控件与对象
在CCalculatorDlg类的声明中,已经为编辑框、静态框及每一个按钮声明了相应类型的对象与之对应。但这些控件与对象的关联工作是在DoDataExchange函数中DDX_Control宏来完成的。
图4-14关联控件与对象
(3)实现对话框扩展功能
首先在CCalculatorDlg::OnCreate函数中,设定对话框的初始大小与位置。实现代码如下:
CRect rect;
GetWindowRect(&rect); //得到对话框的窗口区域矩形 //指定窗口大小与位置:宽为186像素,高度为245像素
SetWindowPos(&wndTop,0,0,186,245,SWP_NOMOVE|SWP_NOZORDER); 其次,添加菜单项ID_EXTEND的响应函数OnExtend。在OnExtend函数中,首先判断当前对话框状态,即是否已经被扩展。
如果对话框已被扩展,则收缩对话框。首先得到对话框的当前位置,将其指定为新的宽度,但高度维持不变。再将其中的编辑控件和编辑控件外的静态框收缩到合理位置。最后将菜单项ID_EXTENDR的显示文本设置为“扩展”,将表示对话框是否扩展标识变量m_IsExtend设置为FALSE。
如果对话框为非扩展,则扩展对话框。首先得到对话框的当前位置,将其指定为新的宽度,但高度不变。再将其中的编辑控件和编辑控件外的静态框收缩到合理的位置。最后将菜单项ID_EXTEND的显示文本设置为“收缩”,将表示对话框是否扩展的标识
变量m_IsExtend设置为TURE,实现代码如附录3所示。效果如图4-15和4-16所示:
图4-15扩展图
图4-16收缩图
(4)屏蔽Enter键
直到现在为止,虽然计算器的界面已经完成。但是,它还有一个缺陷:当Enter键按下时,对话框应付突然关掉。这是因为对话框默认具有焦点的控件是OK键,当Enter键按下时,框架会自动执行当前拥有焦点的控件的响应函数,所以对话框自然就关闭了。要屏蔽这一功能,只要执行下面的代码就可以。
void CCalculatorDlg::OnOK() {
//CDialog::OnOK(); //屏蔽掉此句代码 }
(5)添加背景图
为对话框添加背景图,以增加界面的美观性。首先为工程添加一幅位图资源,以作为对话框的背景。然后加入一个Static控件,将其Type属性设为Bitmap,并为Image
属性选择位图资源,如图4-17所示。
图4-17添加位图
参数设置后对话框的外观如图4-18所示。
图4-18运行结果图
4.6 数值计算功能的实现
具体功能的实现首先添加成员变量。该计算器中所有的运算都是二元运算,即需要两个操作数,一个二元运算操作符。所以必须声明两个浮点数,分别用来表示初始操作数和结果操作数,同时,必须声明两个字符串类型的变量,分别用来显示初始操作数。还需要一个整形变量来记录当前运算符,以及一个整形变量来记录当前小数点按钮是否被单击过。实现代码如下:
//CCalculatorDlg.h头文件 private:
char m_buffer[100];//用来存贮需要显示的数字 CString m_StrBegin;//记录初始操作数的字符串 float DtoR; //
double m_end;//记录结果操作数 double m_begin;//记录初始操作数 int m_bit;//记录运算符
int m_IsCheckPoint;//判断是否按下了小数点符号,当其为0时,表示没有按下 当数字键0—9被单击时,则将当前所按键加到初始操作数末尾,并将初始操作数显示出来。以数字键盘被单击为例,实现代码如下:
//以按键0的响应为例,其余0—9的响应完全类似
m_StrBegin = m_StrBegin+\"0\";
if (!m_IsCheckPoint) //如果小数点按下了
m_DspEdit.OnDisplay(m_StrBegin+\".\");
else //如果小数点没有按下
m_DspEdit.OnDisplay(m_StrBegin);
当小数点键被单击时,首先判断小数点键是否已经被单击过,以及当前初始操作数字符串是否为空。如果小数点键没有被单击过,而且当前初始操作数字符串不为空,则将小数点追加到初始操作数末尾,并且修改小数点标识m_IsCheckPoint为TRUE。实现代码如下:
if (!m_IsCheckPoint && m_StrBegin != \"\") //如果小数点没有按下,且字符不为空 {
m_StrBegin = m_StrBegin+\".\";
m_DspEdit.OnDisplay(m_StrBegin); //显示文本 m_IsCheckPoint = true; //改变标识
}
当清除键CE被单击时,则对所有的成员变量进行初始化。清除小数点标识,将保存初始操作数和结果操作数的字符串清空,将保存初始操作数和结果操作数的浮点数清0,将当前操作符清0。实现代码如下:
m_IsCheckPoint = false; //消除小数点按下标记 m_StrBegin = \"\"; m_begin = 0.0; //清0
m_end = 0.0; //清0
m_bit = 0; //当前操作符为无效操作
当任何一个运算符键被单击时,首先根据当前运算符计算运算结果,再修改记录当
前运算符的变量的值。以加号键被按下为例,实现代码如下:
//以加号为例,其余的操作符也采用类似操作 Result(); //计算运算结果
m_bit = 1; //设置当前运算类型;1代表加法运算
计算器的核心运算函数——Result。在Result中,首先将记录当前操作数的字符串中保存的字符串转化为浮点数;其次根据当前操作符的类型,选择适当的运算操作;再将记录结果操作数的浮点变量中的值转化为字符串,并显示在结果编辑框中。Result函数实现代码如附录3所示。
5 程序结果的演示
5.1测试的研究与选择
测试过程中要判断测试是否成功,要分析程序界面的变化和计算数据的结果是否正确以及各功能键是否能正常使用。
5.2 测试环境
测试环境如下: 测试系统: Windows XP
测试工具: Visual Studio C++ 6.0
5.3 实例测试结果
首先,在运行界面测试简单运算是否能正常运算,输入“34+87=”见结果图5-1所示,观察计算结果是否正确属实
图5-1“34+78=”的运行结果
其次,展开计算器,选中“度数”输入“30”单击“sin”观察结果,见图5-2所示
图5-2“sin30°”的运行结果
最后,选中“弧度”输入“15”单击“sin”观察结果,见图5-3所示
图5-3“sin15”的运行结果
结束语
经过一个月的努力,课程设计基本完成了。在课程设计的实践中,学到很多有用的知识,也积累了不少宝贵的经验。课程设计是以一个计算器的实现为基础,掌握一个基于对话框的应用程序的编程方法以及对话框常用控件的高级编程。在课程设计中我了解到到对话框应用程序的编程模式、改变按钮的客户区形状、在按钮客户区内作图及对话框的扩展等知识。在此期间,遇上了不少的技术难题,但是经过努力,通过查找资料,难题还是一个个被解决了,我从中学到了许多课堂上没学到的东西,这使得我很高兴。
经过设计的各个环节,从中学到了很多,锻炼了自己系统的设计的能力,从系统的需求到系统的功能,到系统的测试,到系统的发布,可以掌握到一个完全的过程,这样对我们以后在工作中或学习中得到很好的锻炼,为用VC++编辑软件奠定基础。
本系统适合于运行在Microsoft Windows 的各个版本下,包括Windows98、Windows Me、Windows2000、Windows XP等系统平台下。
当然,本论文所采取的解决问题的方法并不是非常完善的,在今后的学习、工作中,将继续研究并改进。
参考文献
[1] 严华峰. Visual C++课程设计案例精编. 北京:中国水利水电出版社,2002
[2] 张宏军,党留群,赵天巨.Visual C++ 6.0编程案例精解.北京:电子工业出版社,2005
[3] 郑阿奇,丁有和.Visual C++教程.北京:机械工业出版社,2006 附录1:结构化设计源程序清单
//程序名称:AdvButton.cpp //程序功能:实现高级按钮控件类。 // 程序作者:范菊花 // 最后修改日期:2005-9-21 //构造函数
CAdvButton::CAdvButton() {
//初始化m_ClientRect m_ClientRect.left = 0;
m_ClientRect.top = 0; m_ClientRect.right = 0; m_ClientRect.bottom= 0;
m_ClientRgn.DeleteObject(); //删除区域对象
m_ClientRgn.CreateEllipticRgnIndirect(&m_ClientRect); //创建椭圆区域
m_State = 0;
m_Point.x = m_Point.y = 0; m_IsTimerOn = FALSE;
}
//重载父类Create函数
BOOL CAdvButton::Create(LPCTSTR lpszCaption,DWORD dwStyle,const rect,CWnd *pParentWnd,UINT nID) { return CButton::Create(lpszCaption, dwStyle, rect, pParentWnd, nID);
}
//当鼠标在按钮的客户区内弹起时,改变按钮状态
void CAdvButton::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CRect rect;
GetWindowRect(&rect); //得到按钮客户区域的屏幕坐标位置 GetCursorPos(&m_Point); //得到鼠标的屏幕坐标位置 if((rect.PtInRect(m_Point))&&(m_State != 1)) { m_State = 1; //1:focus state Invalidate(); //重绘客户区
}
CButton::OnLButtonUp(nFlags, point);
RECT&
}
//计时器消息的响应函数
void CAdvButton::OnTimer(UINT nIDEvent) { }
if(rect.PtInRect(m_Point)) //如果鼠标在按钮的客户区内 { }
else //如果鼠标已经不在按钮的客户区内了 { }
CButton::OnTimer(nIDEvent);
if(m_State != 0) { }
KillTimer(nIDEvent); //关闭计时器 m_IsTimerOn = FALSE;
m_State = 0;
Invalidate(); //重绘客户区 if((m_State != 1)&&(m_State != 2)) { }
m_State = 1; Invalidate();
CRect rect;
GetWindowRect(&rect); //得到按钮客户区域的屏幕坐标位置 GetCursorPos(&m_Point); //得到鼠标的屏幕坐标位置 // TODO: Add your message handler code here and/or call default
//在按钮控件客户区的绘置函数,也是实现所有高级控件的关键 void CAdvButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) {
//get client rect
GetClientRect(&m_ClientRect); //得到窗口的有效矩形区域 m_ClientRgn.DeleteObject();//
m_ClientRgn.CreateEllipticRgnIndirect(&m_ClientRect); //在矩形区域内创建椭圆 //设置窗口的有效区域为椭圆 SetWindowRgn(m_ClientRgn,FALSE);
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);//得到按钮控件客户区域的
设备环境变量指针
pDC->SetBkMode(TRANSPARENT);//设置背景模式为透明 pPen = pDC->SelectObject(pPen);
pDC->Ellipse(&m_ClientRect); //在按钮客户区内绘制椭圆 CPen* pPen = NULL;
switch (m_State) //根据按钮不同的状态,创建不同的画笔 { }
case 0:
pPen = new CPen(PS_SOLID,1,DefaultColor); break;
case 1:
pPen = new CPen(PS_SOLID,1,FocusColor); break;
case 2:
pPen = new CPen(PS_SOLID,1,SelectColor); break;
case 3:
pPen = new CPen(PS_SOLID,1,DesiableColor); break;
pPen = pDC->SelectObject(pPen); if(pPen) delete pPen;
LPTSTR pCaption = new char[MAXCAPTIONLEN]; // int iLen = GetWindowText(pCaption,MAXCAPTIONLEN); pDC->SetTextColor(TextColor); //指定文本颜色 //绘制文本,作为按钮标题
pDC->DrawText(pCaption,iLen,&m_ClientRect,DT_SINGLELINE|DT_CENTER|DT_V
CENTER); }
附录2:面向对象设计源程序清单
// 程序名称:CAdvEdit.cpp
// 程序功能:实现高级编辑控件类。 // 程序作者:范菊花 // 最后修改日期:2007-09-21
//绘制编辑控件客户区 void CAdvEdit::OnDraw() {
CDC* pDC = GetDC(); //得到编辑控件设备环境变量 pDC->SetBkMode(TRANSPARENT); //设置背景模式为透明 CRect rect;
GetClientRect(&rect); //得到客户区矩形区域
}
CBrush * pBrush = new CBrush(RGB(255,255,255)); //创建白色画刷 pDC->FillRect(&rect,pBrush); //用画刷填充客户区 pDC->SetTextColor(RGB(92,92,92));//设置文本颜色 //绘制文本,用指定的颜色和字体
pDC->DrawText(m_Caption,rect,DT_SINGLELINE|DT_VCENTER|DT_RIGHT);
附录3:面向对象设计源程序清单
// 程序名称:CalculatorDlg.cpp
// 程序功能:实现对话框界面设计和计算器数值计算功能 // 程序作者:范菊花 // 最后修改日期:2007-09-21
//初始化对话框函数
BOOL CCalculatorDlg::OnInitDialog() {
CDialog::OnInitDialog(); //调用父类的初始化代码
//其他的初始化代码
m_Menu = new CMenu; //
m_Menu->LoadMenu(IDR_MENU); //加载菜单资源模板 SetMenu(m_Menu); //将菜单添加到对话框
return TRUE; //return TRUE unless you set the focus to a control
//菜单命令ID_EXTEND的响应函数 void CCalculatorDlg::OnExtend() {
CRect rect;
GetWindowRect(&rect);
if(m_IsExtend) //如果当前对话框已被扩展 {
GetWindowRect(&rect); //得到对话框的窗口区域矩形
//设置对话框窗口位置与大小;宽为186像素,高度不变
SetWindowPos(&wndTop,0,0,186,rect.Height(),SWP_NOMOVE|SWP_NOZORDER);
//得到编辑框的窗口区域矩形
m_DspEdit.GetWindowRect(&rect);
//设置编辑框窗口位置与大小;宽为155像素,高度不变
m_DspEdit.SetWindowPos(NULL,rect.left,rect.top,155,rect.Height(),SWP_NOMOVE|S
WP_NOZORDER);
//得到静态框的窗口区域矩形
m_DspStatic.GetWindowRect(&rect); //设置表态框窗口位置与大小
m_DspStatic.SetWindowPos(NULL,rect.left,rect.top,168,rect.Height(),SWP_NOMOVE|
SWP_NOZORDER);
//更改菜单项显示文本
m_Menu->ModifyMenu(ID_EXTEND,MF_BYCOMMAND|MF_STRING,ID_EXTEN
D,\"扩展\");
} else {
//设置对话框窗口位置与大小:宽为330像素,高度不变 m_IsExtend = FALSE;
SetWindowPos(&wndTop,0,0,330,rect.Height(),SWP_NOMOVE|SWP_NOZORDER);
//得到编辑框的窗口区域矩形
m_DspEdit.GetWindowRect(&rect);
//设置编辑框窗口位置与大小:宽为155像素,高度不变
m_DspEdit.SetWindowPos(NULL,rect.left,rect.top,155,rect.Height(),SWP_NOMOVE|S
WP_NOZORDER);
//得到静态框的窗口区域矩形
m_DspStatic.GetWindowRect(&rect); //设置静态框窗口位置与大小
m_DspStatic.SetWindowPos(NULL,rect.left,rect.top,168,rect.Height(),SWP_NOMOVE|
SWP_NOZORDER);
//更改菜单项显示文本
m_Menu->ModifyMenu(ID_EXTEND,MF_BYCOMMAND|MF_STRING,ID_EXTEND,\"标准\");
//角度和弧度间转换的实现 void CCalculatorDlg::OnRad() { }
void CCalculatorDlg::OnDegree() { }
//按键1-9的响应
void CCalculatorDlg::AdvButton1()//按下1键时的处理函数
m_isDegree=0; DtoR=(2*PI)/360; UpdateData(FALSE); m_isDegree=1; DtoR=1;
UpdateData(TRUE); }
m_IsExtend = TRUE;
{ }
void CCalculatorDlg::AdvButton2()//按下2键时的处理函数 { }
void CCalculatorDlg::AdvButton3()//按下3键时的处理函数 { }
void CCalculatorDlg::AdvButton4()//按下4键时的处理函数 {
if (!m_IsCheckPoint) //如果小数点按下了
m_DspEdit.OnDisplay(m_StrBegin+\".\"); m_StrBegin = m_StrBegin+\"3\";
if (!m_IsCheckPoint) //如果小数点按下了
m_DspEdit.OnDisplay(m_StrBegin+\".\"); m_StrBegin = m_StrBegin+\"2\";
if (!m_IsCheckPoint) //如果小数点按下了
m_DspEdit.OnDisplay(m_StrBegin+\".\"); m_StrBegin = m_StrBegin+\"1\";
else //如果小数点没有按下
m_DspEdit.OnDisplay(m_StrBegin);
else //如果小数点没有按下
m_DspEdit.OnDisplay(m_StrBegin);
else //如果小数点没有按下
m_DspEdit.OnDisplay(m_StrBegin);
}
m_StrBegin = m_StrBegin+\"4\";
if (!m_IsCheckPoint) //如果小数点按下了
m_DspEdit.OnDisplay(m_StrBegin+\".\");
else //如果小数点没有按下
m_DspEdit.OnDisplay(m_StrBegin);
void CCalculatorDlg::AdvButton5()//按下5键时的处理函数 { }
void CCalculatorDlg::AdvButton6()//按下6键时的处理函数 { }
void CCalculatorDlg::AdvButton7()//按下7键时的处理函数 {
m_StrBegin = m_StrBegin+\"7\";
if (!m_IsCheckPoint) //如果小数点按下了
m_DspEdit.OnDisplay(m_StrBegin+\".\"); m_StrBegin = m_StrBegin+\"6\";
if (!m_IsCheckPoint) //如果小数点按下了
m_DspEdit.OnDisplay(m_StrBegin+\".\"); m_StrBegin = m_StrBegin+\"5\";
else //如果小数点没有按下
m_DspEdit.OnDisplay(m_StrBegin);
else //如果小数点没有按下
m_DspEdit.OnDisplay(m_StrBegin);
}
void CCalculatorDlg::AdvButton8()//按下8键时的处理函数 { }
void CCalculatorDlg::AdvButton9()//按下9键时的处理函数 { }
void CCalculatorDlg::Result()//用来处理按下符号键时的函数,是计算的核心函数 {
m_IsCheckPoint = false; //清除小数点标记
m_begin = atof(m_StrBegin); //当输入数据转为浮点数 if (!m_IsCheckPoint) //如果小数点按下了
m_DspEdit.OnDisplay(m_StrBegin+\".\"); m_StrBegin = m_StrBegin+\"9\";
if (!m_IsCheckPoint) //如果小数点按下了
m_DspEdit.OnDisplay(m_StrBegin+\".\"); m_StrBegin = m_StrBegin+\"8\";
if (!m_IsCheckPoint) //如果小数点按下了
m_DspEdit.OnDisplay(m_StrBegin+\".\");
else //如果小数点没有按下
m_DspEdit.OnDisplay(m_StrBegin);
else //如果小数点没有按下
m_DspEdit.OnDisplay(m_StrBegin);
else //如果小数点没有按下
m_DspEdit.OnDisplay(m_StrBegin);
switch(m_bit) {
case 1: //处理+号
m_end += m_begin; break;
case 2: //处理-号
m_end -= m_begin; break;
case 3: //处理*号,即乘法
m_end *= m_begin; break;
case 4: //处理/号,即除法
if (m_begin==0) { }
m_end /= m_begin; break;
m_DspEdit.OnDisplay(\"除数不能为零!\"); return;
case 5: //处理sqrt号,即开方
if (m_end<0) { }
m_end = sqrt(m_end); break;
m_DspEdit.OnDisplay(\"函数输入无效!\"); return;
case 6: //处理1/x号,即求倒数
m_end = 1/m_end;
case 7: //处理=号
break;
case 8: //处理sin号
m_end = sin(m_end*DtoR); break;
case 9: //处理cos号
m_end = cos(m_end*DtoR); break;
case 10: //处理tan号
m_end = tan(m_end*DtoR); break;
case 11: //处理x^2号,即平方
m_end = m_end*m_end; break;
case 12: //处理x^3号,即立方
m_end = m_end*m_end*m_end; break;
case 13: //处理x^y号,即求x的y次方
m_end = pow(m_end,m_begin); break;
case 14: //处理Exp号,即求e的x次方
m_end = exp(m_end); break;
case 15: //处理ln号
if (m_end<=0) { }
m_end = log(m_end); break;
m_DspEdit.OnDisplay(\"函数输入无效!\"); return;
case 16: //处理log号
}
}
if (m_end<=0) { }
m_end = log10(m_end); break;
m_DspEdit.OnDisplay(\"函数输入无效!\"); return;
case 17: //处理n!号
if (m_end<=0) { } int i;
for(i=m_end-1;i>=1;i--)
m_end*=i;
m_DspEdit.OnDisplay(\"函数输入无效!\"); return;
break;
case 18: //处理品10^x
m_end=pow(10, m_end); break;
default: //
m_end = m_begin; break;
m_begin = 0.0; m_bit = 0; m_StrBegin = \"\";
int i = sprintf(m_buffer,\"%10.12f\将结果转换为字符串 TrimZero(m_buffer,i);//去掉字符串尾部多余的零 m_DspEdit.OnDisplay(m_buffer); //显示结果
因篇幅问题不能全部显示,请点此查看更多更全内容