前面文章介绍了Button的使用方式,这篇写一下应用案例。比较常规的MFC设计,计算器设计。
设计前大概想了下如何去实现,需要实现什么功能,列了以下几点。
- 基本运算功能:加法,减法,乘法,除法,除以零处理。
- 用户界面设计:按钮布局(数字按钮(0-9);运算符按钮(+、-、×、÷、=);清除按钮(C、CE);显示框)
- 计算逻辑:运算顺序,简单的运算顺序(从左到右);简单的条件判断和运算;使用基本数据类型(整型、浮点型)
- 技术实现:编程语言C++,编程环境MFC
- 扩展功能(未来考虑):历史记录,记忆功能,键盘快捷键。
思维导图如下
着手开始设计,打开vs2022,创建一个MFC应用,应用程序类型选择,基于对话框。
首先界面设计,按钮加文本框的形式
第一个Edit用于显示公式;第二个文本框用于显示结果。
1)给每个按钮ID重命名, 区分按钮,方便代码设计。
2) 给每个按钮增加BN_CLICKED消息。双击添加。
public:
afx_msg void OnClickedBtnNum0();
afx_msg void OnClickedBtnNum1();
afx_msg void OnClickedBtnNum2();
afx_msg void OnClickedBtnNum3();
afx_msg void OnClickedBtnNum4();
afx_msg void OnClickedBtnNum5();
afx_msg void OnClickedBtnNum6();
afx_msg void OnClickedBtnNum7();
afx_msg void OnClickedBtnNum8();
afx_msg void OnClickedBtnNum9();
afx_msg void OnClickedBtnPoint();
afx_msg void OnClickedBtnAdd();
afx_msg void OnClickedBtnSubtract();
afx_msg void OnClickedBtnMultiply();
afx_msg void OnClickedBtnDivide();
afx_msg void OnClickedBtnClear();
afx_msg void OnClickedBtnEqual();
3)创建几个全局变量,用于传递结果和状态标志
public:
CString str_formula = L"";//表达式字符串
CString str_num;//单个数据字符串
double calculateNum = 0;//计算结果
double num1 = 0 ;//运算符前的数据1
int calculateType = 4;//运算符的类型。0:加法;1:减法;2:乘法;3:除法;4:初始值。
4)给每个按钮添加单击指令函数。
数字按钮输入以下指令代码。如按钮1输入
str_formula += L"1";//根据按钮编号来
str_num += L"1";//根据按钮编号来
SetDlgItemTextW(IDC_EDIT_Formula, str_formula);//计算式显示在文本框1中
SetDlgItemTextW(IDC_EDIT_Result, L"输入中...");//计算结果框显示输入中
5)添加四则运算指令
void CMFCApplication1Dlg::OnClickedBtnAdd()
{
// TODO: 在此添加控件通知处理程序代码
num1 = _tcstod(str_num.GetString(), NULL);
bool flag = CalculateFunction(calculateType, num1);
num1 = 0;
str_num = L"";
str_formula += L"+";
calculateType = 0;
SetDlgItemTextW(IDC_EDIT_Formula, str_formula);
if (flag)
{
SetDlgItemTextW(IDC_EDIT_Result, L"输入中...");
}
else
{
SetDlgItemTextW(IDC_EDIT_Result, L"计算式有异常...");
str_formula = L"";
}
}
void CMFCApplication1Dlg::OnClickedBtnSubtract()
{
// TODO: 在此添加控件通知处理程序代码
num1 = _tcstod(str_num.GetString(), NULL);
bool flag = CalculateFunction(calculateType, num1);
num1 = 0;
str_num = L"";
str_formula += L"-";
calculateType = 1;
SetDlgItemTextW(IDC_EDIT_Formula, str_formula);
if (flag)
{
SetDlgItemTextW(IDC_EDIT_Result, L"输入中...");
}
else
{
SetDlgItemTextW(IDC_EDIT_Result, L"计算式有异常...");
str_formula = L"";
}
}
void CMFCApplication1Dlg::OnClickedBtnMultiply()
{
// TODO: 在此添加控件通知处理程序代码
num1 = _tcstod(str_num.GetString(), NULL);
bool flag = CalculateFunction(calculateType, num1);
num1 = 0;
str_num = L"";
str_formula += L"*";
calculateType = 2;
SetDlgItemTextW(IDC_EDIT_Formula, str_formula);
if (flag)
{
SetDlgItemTextW(IDC_EDIT_Result, L"输入中...");
}
else
{
SetDlgItemTextW(IDC_EDIT_Result, L"计算式有异常...");
str_formula = L"";
}
}
void CMFCApplication1Dlg::OnClickedBtnDivide()
{
// TODO: 在此添加控件通知处理程序代码
num1 = _tcstod(str_num.GetString(), NULL);
bool flag = CalculateFunction(calculateType, num1);
num1 = 0;
str_num = L"";
str_formula += L"/";
calculateType = 3;
SetDlgItemTextW(IDC_EDIT_Formula, str_formula);
if (flag)
{
SetDlgItemTextW(IDC_EDIT_Result, L"输入中...");
}
else
{
SetDlgItemTextW(IDC_EDIT_Result, L"计算式有异常...");
str_formula = L"";
}
}
6)复位按钮指令
str_formula = L"";
str_num = L"";//数据
calculateNum = 0;//计算结果
num1 = 0;//数据1
calculateType = 4;
SetDlgItemTextW(IDC_EDIT_Formula, str_formula);
SetDlgItemTextW(IDC_EDIT_Result, L"清零...");
7)等于按钮指令
void CMFCApplication1Dlg::OnClickedBtnEqual()
{
// TODO: 在此添加控件通知处理程序代码
num1 = _tcstod(str_num.GetString(), NULL);
bool flag = CalculateFunction(calculateType, num1);
CString str = ResultFunction(calculateNum);//结果显示前,清零,小数位数处理
if (str_formula == L"")//判断计算式是否为空
{
SetDlgItemTextW(IDC_EDIT_Formula, L"0");
SetDlgItemTextW(IDC_EDIT_Result, L"0");
}
else
{
SetDlgItemTextW(IDC_EDIT_Formula, str_formula);
if (flag)//判断计算有无异常
{
SetDlgItemTextW(IDC_EDIT_Result, str);
}
else
{
SetDlgItemTextW(IDC_EDIT_Result, L"出错了");
}
str_formula = L"";
}
//结果复位
calculateNum = 0;
num1 = 0;
str_num = L"";
calculateType = 4;
}
这里用到了两个自定义函数CalculateFunction()
四则运算函数,ResultFunction()
结果处理函数
bool CMFCApplication1Dlg::CalculateFunction(int type, double& value)
{
switch (type)
{
case 0:
calculateNum += value;
break;
case 1:
calculateNum -= value;
break;
case 2:
calculateNum *= value;
break;
case 3:
if (value == 0)
{
MessageBox(L"除数不能是0", L"错误");
calculateNum = 0;
return false;
}
else
{
calculateNum /= value;
}
break;
default:
calculateNum = value;
break;
}
return true;
}
CString CMFCApplication1Dlg::ResultFunction(double resultnum)
{
CString str;
str.Format(_T("结果是:%.12f"), resultnum);
if (str.Find('.'))
{
int length = str.GetLength();
while (length > 0 && str[length - 1] == '0') {
str.Delete(length - 1);
length--;
if (str[length - 1] == '.')
{
str.Delete(length - 1);
break;
}
}
}
return str;
}
最终效果展示
加法
减法,负数计算,
乘法展示
除法与小数展示
除数为0时,提示,并停止计算。