MFC学习笔记2---简单计算器
前言
学习了鸡啄米网页的前三部分后,我们就可以做一个小软件出来了,我选择先做一个计算器。
这是Win7系统自带的计算器:
为了提升成就感,我将计算器的大部分内容去除,于是就变成这样:
这样就只剩下了16个按钮和一个文本显示框,这样就简单多了!
新建一个MFC对话框应用程序
打开VS2010点击Start Page中的New Project(新建工程),或者菜单栏File -> New -> Project 弹出新建项目对话框,在左侧选择MFC,然后在中间选择MFC Application
在下面三个编辑框中输入工程名称及路径。VS2010会在Location中选择的路径下建立名为Solution Name的文件夹用来放置工程有关的所有文件包括源文件、资源文件、工程文件、调试记录、可执行文件等等,并在该文件夹下创建名为Name的文件夹放置程序员编写的.h和.cpp文件以及程序员建立的一些资源文件,当然这个文件夹可以有程序员根据自己的编程习惯进行一些修改。
下一步进入VS的新建MFC应用程序欢迎对话框:
下一步选择工程类型:
在1处选择基于对话框的应用程序,2处可以选择对话框使用的语言(我暂时未发现使用英文版对创建中文对话框的影响),3处去掉勾,我在这里不使用宽字符,4处我选择第二项,使用静态链接库。
接下来的几步都选择默认即可,也可以在设置完工程类型后直接点击Finish按钮完成创建工程。
这样,我们就得到了一个基于MFC对话框的应用程序模板
使用键盘快捷键Alt+Enter调出Properties窗口,Ctrl+Shift+C调出ClassView窗口,Ctrl+Alt+X调出Toolbox窗口,Ctrl+Shift+E调出资源窗口,这些都是在MFC中常用的一些窗口。
建立计算器外观框架
1、将MFC默认的控件删除:选中后按下键盘【Delete】
2、从Toolbox中拖出16个按钮控件(Button)输入内容并调整大小、位置
选中一个按钮控件,在Properties窗口中将Caption属性改为“1”,用类似的方法更改其他15个按钮内容;将其中一个按钮选中更改为合适的大小,按下键盘【Ctrl】,同时鼠标点击选中其他所有的按钮,最后点击选中已经调整好大小的按钮,放开键盘【Ctrl】,在工具栏找到[Make Same Width]和[Make Same Height](图片中红色方框)并点击;
通过图片中黄色方框中的几个工具将按钮位置调整好。
3、从Toolbox中拖出一个文本编辑框(EditControl),调整大小和位置,调整属性ModalFrame为True,ReadOnly为True
4、调整对话框的大小
这样就可以得到一个建议的计算器了,不过编译链接后只是显示出了计算器的外观而已,按下按钮并没有任何反应,这是因为还没有对按钮添加响应事件:
工程文件
创建应用程序后,VS2010会在工程下自动创建一些文件和资源:
如果在新建工程选择工程类型时选择简体中文,那么工程文件说明在ReadMe.txt中以中文的形式呈现给程序员。
同时,可见的这3个cpp源文件中,程序员并不会找到应用程序的入口函数WinMain(),这是因为VS已经封装好了,VS将入口函数放在appmodul.cpp中,为AfxWinMain()函数(可以按下F10键进入调试状态,自动定位到程序入口处)。
在ReadMe.txt中这样描述对话框类:
应用程序向导创建一个对话框类:
CalculatorDlg.h,CalculatorDlg.cpp - 对话框
这些文件包含 CCalculatorDlg 类。该类定义应用程序主对话框的行为。该对话框的模板位于 Calculator.rc 中,该文件可以在 Microsoft Visual C++ 中进行编辑。
在CalculatorDlg.h 中可以看到类CCalculatorDlg是基于类CDialogEx的,这样,我们可以编辑这个类从而使软件运行起来。
为对话框类添加变量及响应函数
1、打开类视图,为对话框类CCalculatorDlg添加变量:右键点击类名称:
出现添加成员变量的对话框,添加CString类型变量m_strCal用来储存用户输入的算式
2、右键点击编辑框,为控件添加变量Control类型CEdit变量m_edRes:
3、为类添加无返回值无参成员函数UpdateEditRes:
进入CalculatorDlg.cpp中进行编辑,代码如下:
void CCalculatorDlg::UpdateEditRes(void) { m_edRes.SetWindowTextA(m_strCal); }
4、右键点击按钮“1”,添加事件处理程序OnBn1,点击Add and Edit转到CalculatorDlg.cpp中进行编辑:
代码如下:
void CCalculatorDlg::OnBn1() { // TODO: Add your control notification handler code here m_strCal += "1"; this->UpdateEditRes(); }
5、同理为其他按钮添加事件处理,除了“C”按钮和“=”按钮外其他事件处理基本相同。
6、“C”按钮用于初始化类成员变量:
void CCalculatorDlg::OnBnC() { // TODO: Add your control notification handler code here m_edRes.SetWindowTextA(""); m_strCal = ""; }
7、“=”按钮由于计算最终用户输入的算式:(为了演示效果简化算法只进行一步运算)
void CCalculatorDlg::OnBnEqual() { // TODO: Add your control notification handler code here CString str; char *a; int num[2] = {0, 0}; //储存左右两个操作数 int i = 0; char op; //储存操作运算符 while (!m_strCal.IsEmpty())//分析输入的字符串获得操作数和运算符 { str = m_strCal.Left(1); a = str.GetBuffer(1); str.ReleaseBuffer(); switch (a[0]) { case '0': num[i]=num[i]*10+0; break; case '1': num[i]=num[i]*10+1; break; case '2': num[i]=num[i]*10+2; break; case '3': num[i]=num[i]*10+3; break; case '4': num[i]=num[i]*10+4; break; case '5': num[i]=num[i]*10+5; break; case '6': num[i]=num[i]*10+6; break; case '7': num[i]=num[i]*10+7; break; case '8': num[i]=num[i]*10+8; break; case '9': num[i]=num[i]*10+9; break; default: op= a[0]; i++; break; } m_strCal = m_strCal.Mid(1); } int res; //储存运算结果 switch (op) //分析操作符,得到结果 { case '+': res=num[0]+num[1]; break; case '-': res=num[0]-num[1]; break; case '*': res=num[0]*num[1]; break; case '/': if(num[1]==0) AfxMessageBox("除数不能为"); else res=num[0]/num[1]; break; } CString strres; strres.Format("%d", res); //将结果数拼装为字符串用于显示 m_edRes.SetWindowTextA(strres); m_strCal = ""; }
8、界面优化
根据软件功能分析效果:只能有两个操作数,只能在两个操作数之间放置一个操作运算符,所以为了防止用户误操作,我们可以使用控件的EnableWindow函数控制按钮的可用与否:
为按钮“+” “-” “*” “/”添加变量m_bnPlus,m_bnMinus,m_bnMultiply,m_bnDivide:并调整他们的属性Disabled为True
在CCalculatorDlg类中添加bool类型变量m_bOp
然后在按钮“+” “-” “*” “/”消息函数中添加如下代码:
m_bnPlus.EnableWindow(FALSE); m_bnMinus.EnableWindow(FALSE); m_bnMultiply.EnableWindow(FALSE); m_bnDivide.EnableWindow(FALSE); m_bOp = true;
在按钮“C”消息函数中添加如下代码:
m_bnPlus.EnableWindow(FALSE);
m_bnMinus.EnableWindow(FALSE);
m_bnMultiply.EnableWindow(FALSE);
m_bnDivide.EnableWindow(FALSE);
在按钮“1”“2”“3”“4”“5”“6”“7”“8”“9”“0”中添加如下代码:
if (!m_bOp) { m_bnPlus.EnableWindow(); m_bnMinus.EnableWindow(); m_bnMultiply.EnableWindow(); m_bnDivide.EnableWindow(); }
在“=”按钮最开始处中添加如下代码:
if (m_strCal.IsEmpty()) { return ; }
在“=”按钮末尾处中添加如下代码:
m_bnPlus.EnableWindow(FALSE); m_bnMinus.EnableWindow(FALSE); m_bnMultiply.EnableWindow(FALSE); m_bnDivide.EnableWindow(FALSE); m_bOp = false;
这样一个最简单的计算器程序就做好了!!!
总结
整个对话框工程中运用了按钮和文本编辑框两类控件及其简单的成员函数,包括设置编辑框文本、设置按钮可用与否状态;为对话框添加成员变量、成员函数;一个调出消息框的函数AfxMessageBox函数;CString类的一些简单成员函数应用如CString:: IsEmpty(),CString:: Left(),CString::Mid(),CString:: Format()等。
最后,望各位同道中人给我提出宝贵意见