资源描述
题目 基于MFC的多功能计算器设计
一、 设计目标
编写一个计算器。
二、 语言环境
编程语言: C++
开发环境: VS
目标软件运行平台: Windows 64位机
三、 软件功能:
1. 图形化界面。
2. 实现计算器的功能。
3. 输入加减乘除表示式, 能够计算其结果。
4. 基本功能: 计算表示式, 计算阶乘, 计算组合数, 次幂, 求次幂后取余, 简单的分数加减乘除计算。
5. 扩展功能: 在以上功能完成的基础上, 可完成更高精度的计算, 实现简单高精度的加减乘除阶乘运算。
基于MFC的多功能计算器设计
摘要
计算器是人们日常生活中常见的电子产品之一, 在人们的生活中有着非常广泛的应用, 随着科学的进步, 计算器的种类和功能也更加丰富。本次课程设计旨在基于MFC框架设计一个多功能计算器, 能够实现含括号的表示式计算, 三角函数、 开方、 阶乘、 排列组合等数学计算, 进制转换, 超过long long范围的整数运算以及简单的分数四则运算。此次设计的多功能计算器是基于MFC的框架, 以C++编程语言完成的, 计算器使用中缀表示式求值的算法计算含括号的表示式, 使用C++标准库函数进行相应的数学计算, 利用Boost库实现高精度的整数运算。本计算器不但功能丰富, 而且具有美观、 功能清晰且操作方便的界面。经多次测试, 本计算器能即时准确地获得所需的计算结果, 而且能在输入错误时进行相应处理, 充分降低了计算时的难度, 节约了时间。经过本次课程设计, 掌握了MFC基本框架, 对基本算法有了更加深入的了解。
关键词: 多功能计算器; MFC; C++编程语言; 表示式计算; 高精度
目录
课题分析 3
总体设计 3
详细设计 4
3.1普通计算与科学计算 4
3.2高精度计算 7
3.3其他计算 8
3.3.1分数计算 8
3.3.2组合数计算 8
3.3.3进制转换 8
程序调试与问题解决 9
4.1输入表达式错误引发程序异常 9
4.2输入表达式格式有误 9
4.3计算排列组合溢出 10
运行结果 10
总结 12
课题分析
本次设计为多功能计算器, 需要实现多种功能, 为了使界面更加美观, 功能更加清晰明了, 也为了让使用者便于操作, 因此本计算器使用MFC中的Tab Control控件对计算器进行分页[1], 将计算器分为了四个板块, 分别为: 普通计算、 科学计算、 高精度计算和其它计算。普通计算板块不但能够实现普通四则运算、 次幂及取模的运算, 还能够经过使用中缀表示式求值的算法计算表示式的值[2]; 科学计算板块不但包含普通计算板块中的功能, 还能够进行三角函数、 阶乘、 根号以及对数的运算; 高精度板块能够实现大整数的加减乘除次幂与取模计算; 其它板块中含有分数的四则运算、 组合数计算以及进制转换功能。程序总体功能框图如图1。
图1 程序功能框图
总体设计
图2所示为整体设计流程框图。由于本次课程设计要实现的功能较多, 如果放到一个页面上, 既不美观, 功能也不清晰, 于是本计算器使用了MFC中的Tab Control控件, 将计算器分为四个部分, 每个部分拥有不同的功能。打开本计算器后, 计算器的变量自动初始化, 接着用户选择自己所需要的功能模块进行操作。
选择普通计算或者科学计算页面后, 用户需要点击计算器上的按钮来输入所需计算的表示式, 用户所输入的表示式会在编辑框中显示出来, 当用户按下等于后, 计算器会执行操作, 计算当前编辑框中的值, 并将结果返回到结果框中进行显示; 否则, 计算器会继续等待用户输入。
选择高精度计算的页面后, 用户能够进行超过64位整数的加减乘除、 次幂以及取模的连续运算。用户经过按钮输入两个变量以及运算符, 按下等号即可得到答案, 接着用户能够选择继续按下运算符, 使用本次得到的答案作为变量继续运算, 也能够重新输入进行运算。
选择其它计算的页面之后, 能够看到该页面分为三个部分, 分别是分数计算、 组合数计算和进制转换。在分数计算部分, 用户经过键盘输入分数的分子和分母, 能够进行两个分数之间的加减乘除运算; 在组合数计算部分, 用户输入两个整数n和m, 点击计算后能够得到A(n,m)与C(n,m)的值; 在进制转换部分, 用户输入一个数字, 选择当前数字的进制后, 再点击需要转换的进制即可得到转换后的结果。
图2 整体设计流程图
详细设计
3.1普通计算与科学计算
科学计算板块与普通计算板块相比, 新增了圆周率的按钮与三角函数、 阶乘、 根号与对数的计算, 其它功能与普通计算板块一致, 因此一起说明。
首先, 给编辑框添加类型为Value的控件变量, 变量类型为CString, 变量名为result。接下来为每个按键添加事件处理程序, 而且给清空键C添加bool型变量Restarted, 初始化为true; 给等号添加bool型变量OperatorPressed, 初始化为true; 给小数点添加bool型变量pt, 初始化为false; 给左括号和右括号分别添加int型变量cntleft和cntright, 初始化为0。
每个按键的事件处理程序如下所述:
( 1) 按下0到9的数字按钮。先将编辑框中的内容更新到编辑框所对应的变量result中, 判断上一次的按键是否为等于, 或者上一次操作是否将编辑框清空, 或者当前result的末尾字符是否为”)”, 若满足三个中任意一个, 那么result等于现在所按下的字符, 否则, 在result末尾追加当前所按下的字符。更新当前编辑框关联变量result的值到编辑框内。具体流程如图3a所示。
图3a 按下数字按钮 图3b 按下小数点按钮
( 2) 按下小数点按钮。如果当前数字中没有出现过小数点( pt为false) 而且最后一位为运算符, 则在result末尾追加”0.”, 否则判断上一次按键是否为等于或上一次操作是否将编辑框清空或者result的末尾是否为右括号, 如果满足, 那么也在末尾追加”0.”, 否则在末尾追加”.”。更新变量到编辑框。过程如图3b所示。
图3c 按下双目运算符按钮 图3d 按下单目运算符按钮
( 3) 按下运算符。在本计算器中, 有双目运算符和单目运算符两种。如图3c所示, 按下双目运算符按钮后, 首先需要判断当前已输入字符串的末尾是否也是一个运算符, 如果是则将之前的运算符替换为现在所按下的运算符, 如果末尾是左括号, 那么在末尾追加0和当前的运算符; 若前一位不是运算符且当前不是第一次按键, 就在字符串末尾追加该运算符, 否则字符串等于该运算符。这样做就避免了输入错误而导致计算错误甚至程序崩溃。如图3d所示, 按下单目运算符之后, 将编辑中的字符转换为数字后进行计算, 将结果转化为字符串显示出来即可。如果编辑框中还存在运算符, 那么会取第一个运算符之前的数字进行运算。
图3e 按下左括号按钮 图3f 按下右括号按钮
( 4) 按下括号。如图3e所示, 按下左括号后, 先判断编辑框是否已经清空, 若是, 则result等于左括号, 否则, 找到从右往左的第一个运算符, 在该运算符后面加上一个左括号, 左括号个数cntleft加一, 更新result的值到编辑框。如图3f所示, 按下右括号后, 首先要判断右括号的个数是否少于左括号的个数, 如果满足才能添加右括号, 否则忽略该次添加操作; 左括号个数大于右括号个数时, 若result的最后一位就是左括号, 那么在其后面添加0和右括号, 如果是其它运算符, 那么去掉该运算符再添加右括号, 如果是数字, 则直接添加右括号。右括号个数cntright加一, 更新result的值到编辑框。
( 5) 退格按钮与清空按钮。按下退格按钮时, 若当前编辑框尚未清空, 就将该字符串末尾一位删去, 此时需要判断是否删除了左括号、 右括号或者是小数点, 删除左右括号时, 对应的cntleft和cntright需要减一, 删除小数点时, 小数点的标志pt要变为false。按下清空按钮时, 编辑框内容显示0, 所有变量重新初始化。
( 6) 按下等于按钮。该处为本计算器的核心, 使用了中缀表示式求值的算法, 如图3g所示。由于输入的表示式是一个字符串, 因此首先需要经过循环将其中的数字与字符提取出来。使用两个栈分别存放数字与运算符[3], 如果当前运算符优先级比栈顶元素优先级高, 则入栈, 否则从数字栈中弹出两个元素, 从符号栈中弹出一个符号, 计算其结果, 再将结果压入数字栈。最后表示式的结果即为数字栈的栈顶元素, 将该数字转化为字符串后更新到编辑框即可。
图3g 按下等于按钮
3.2高精度计算
高精度计算部分能够进行连续的四则运算与取模、 次幂的操作, 每次两个变量参与运算, 得到的结果能够继续作为一个变量参与下一次的运算。
在高精度计算当中, 按钮的事件响应与普通计算和科学计算中的按键的事件响应是相似的, 编辑框关联CString类型的变量result, 给清空键添加bool类型变量Restarted, 给等号添加bool类型变量OperatorPressed。
图4 高精度计算
实现高精度的方法有很多, 此处选用了一种较为便捷又准确的操作, 使用C++的Boost库中的multiple precision工具。输入需要计算的式子, 按下等于即可进行计算, 如果式子中包含两个及其以上的双目运算符, 只计算第一次出现的运算符和其前后的数字所得值, 具体流程图如4所示。
3.3其它计算
3.3.1分数计算
分数计算中, 用户输入待计算的两个分数, 点击所需要进行的运算类型, 再按下等号即可进行计算。计算过程模拟手动计算过程, a/b+c/d = (a*d+b*c)/(b*d),a/b-c/d = (a*d-b*c)/(b*d),a/b*c/d=ac/bd,a/b / c/d = a*d / b*c, 最后再将得到的结果化简。将结果的分子与分母的GCD( 最大公约数) 求出, 分子与分母同时除以GCD即可得到答案。
3.3.2组合数计算
组合数计算中, 用户输入整数n和m, 点击计算按钮, 即可求出A(n,m)与C(n,m)的值。计算过程与手动计算过程一致, 求得n!,(n-m)!,A(n,m) = n!/(n-m)!,求得m!,C(n,m)=A(n,m)/m!。
3.3.3进制转换
进制转换中, 用户在转换数字框中输入需要转换的数字, 选择该数字当前进制, 点击需要转换的进制即可在下方得到转换后的结果。由于输入的N进制的数字是字符串, 因此计算器会先将输入的字符串转化为十进制的整数, 接着调用_itoa_s函数将该十进制数进行进制转换。
程序调试与问题解决
4.1输入表示式错误引发程序异常
图5 输入错误引发异常
将基本功能编写完成开始测试程序时, 发现, 如果输入的表示式不规范, 程序将会出现异常, 如图5所示。引发该异常的错误输入有很多情况, 经过多次重复测试, 发现了以下几种会引发该异常的情况:
( 1) 连续输入运算符。
( 2) 右括号个数多于左括号个数。
( 3) 运算符后直接加上右括号。
( 4) 以运算符开头或者左括号后直接加上运算符。
经过断点调试发现, 计算器每次运算时, 数字栈每次弹出两个元素, 符号栈弹出一个元素, 可是进行以上不规范的操作, 导致数字栈中元素只剩下一个时, 符号栈中元素的个数依然大于等于一, 因此数字栈空时仍进行弹栈操作, 出现错误。
做出以下处理:
( 1) 在计算部分, 每次判断数字栈或者符号栈是否为空, 而且在输入时判断是否连续点击了运算符, 如果是, 只保留最后一次的运算符。
( 2) 保证右括号的个数恒小于等于左括号个数。
( 3) 如果运算符后直接点击右括号按钮, 则去掉该运算符后加上右括号。
( 4) 若表示式以非*/%^运算符开头, 则在前方补0, 若左括号为运算符, 则在左括号与运算符之间补0。
4.2输入表示式格式有误
除引发异常的错误输入外, 还有多种错误的输入格式, 有以下处理:
( 1) 以小数点或运算符开头。如表示式”*3+5””(.3+5)”, 在这种情况下, 在小数点或者运算符前自动补零, 使显示正确。
( 2) 数字后加左括号。如输入”3+5(”, 根据Windows自带计算器的处理, 该括号应该放在从右往左的第一个运算符之后, 应显示为”3+(5”。
( 3) 左括号后加右括号。错误显示为”( ) ”, 同样按照Windows自带计算器的处理, 在两个括号中间补零。
( 4) 一个数字中出现多个小数点。最初能够输入”3.14159.2”这种不正确的数字, 因此添加一个叫做pt的bool型变量, 来判断该数字中是否已经出现过小数点。
4.3计算排列组合溢出
计算A(100,50)时, 是将100的阶乘除以50的阶乘, 这个数字显然超过了longlong的范围, 因此此处选用cpp_int进行计算。
运行结果
图6 普通计算板块
( 1) 选择普通计算板块, 输入一个包含加减乘除、 次幂和取模的表示式, 按下等于后, 得到计算结果, 与实际结果一致。
图7 科学计算板块
( 2) 选择科学计算板块, 计算sin( 98) , 计算结果与Windows自带计算器结果一致。
图8 高精度计算板块
( 3) 选择高精度计算板块, 计算100! , 计算结果与Windows自带计算器结果一致。
图9a 分数计算板块( 一)
图9b 分数计算板块( 二)
( 4) 选择分数计算板块, 计算2/5 * 4/6得到结果4/15, 与实际结果一致, 如图9a所示。当输入的分数分母为0时, 分母显示input error, 如图9b所示。
图10a 排列组合板块( 一)
图10b 排列组合板块( 二)
( 5) 选择计算排列组合板块, 如图10a所示, 计算A(100,20)与C(100,20), 结果与实际计算结果一致。如图10b所示, 当输入的n小于m、 n小于零、 m小于零时, 提示error。
图11a 进制转换板块( 一)
图11b 进制转换板块( 二)
( 6) 选择进制转换板块, 如图11a所示, 将十进制数45487转化为16进制数, 得到结果b1af, 与实际结果一致; 如图11b所示, 当输入的待转换数字的进制有误时, 显示input error。
总结
本次课程设计, 不但能够让我们学习到新的知识, 同时也能反应我们对所学知识的掌握程度。从最开始的茫然, 不知道如何去, 做到逐步掌握MFC框架的基本应用, 这段过程中, 我的基础知识和技能, 以及自己的自学能力都得到了很大的提高。此次课程设计是用C++语言编写的, 而且使用了MFC框架。在这个过程中, 最明显的收获就是理解和较为熟练地掌握并利用了VS 开放工具来设计界面并编写程序。这个过程中最困难的不是做完一个简单的计算器, 而是在初步完成之后不停地测试以及调试, 发现程序中所存在的问题, 并一一解决。这个过程毫无疑问是非常漫长的, 可是我的收获却是非常丰富的。我懂得了在今后的工作发展和学习实践的过程中, 要有细心与耐心, 要肯付出努力, 知难而上。经过本次的课程设计, 我的专业知识以及能力都得到了很大的提升, 而且还让我了解到了自己能够提升的空间还有很大。在今后的学习生活和工作当中, 都要独立思考, 自己动手操作, 接受挑战, 迎难而上。
参考文献:
[1]侯俊杰.深入浅出MFC[M].湖北: 华中理工大学出版社,
[2]王迤冉,王华东.表示式求值的一种实现方法[J].周口师范学院学报, ,18(2):31-33
[3]李橙, 丁国栋.栈在表示式求值中的应用[J].电脑知识与技术, ( 34) : 8156-5157
// CalculatorDlg.cpp: 实现文件
//
#include "stdafx.h"
#include "Calculator.h"
#include "CalculatorDlg.h"
#include "afxdialogex.h"
#include "map"
#include "stack"
#include "Page1.h"
#include "Page2.h"
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序”关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CCalculatorDlg 对话框
CCalculatorDlg::CCalculatorDlg(CWnd* pParent /*=NULL*/)
: CDialog(IDD_CALCULATOR_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCalculatorDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TAB1, m_tab);
}
BEGIN_MESSAGE_MAP(CCalculatorDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, &CCalculatorDlg::OnTcnSelchangeTab1)
END_MESSAGE_MAP()
// CCalculatorDlg 消息处理程序
BOOL CCalculatorDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将”关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时, 框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
//SetWindowText(_T("Calculator"));
CRect temprect(0, 0, 670, 450);
CWnd::SetWindowPos(NULL, 0, 0, temprect.Width(), temprect.Height(), SWP_NOZORDER | SWP_NOMOVE);
//为Tab Control增加两个页面
m_tab.InsertItem(0, _T("普通"));
m_tab.InsertItem(1, _T("科学"));
m_tab.InsertItem(2, _T("高精度"));
m_tab.InsertItem(3, _T("其它"));
m_page1.Create(IDD_DIALOG1, GetDlgItem(IDC_TAB1));
m_page2.Create(IDD_DIALOG2, GetDlgItem(IDC_TAB1));
m_page3.Create(IDD_DIALOG3, GetDlgItem(IDC_TAB1));
m_page4.Create(IDD_DIALOG4, GetDlgItem(IDC_TAB1));
//创立两个对话框
//设定在Tab内显示的范围
CRect rc;
m_tab.GetClientRect(&rc);
rc.top += 20;
rc.bottom -= 0;
rc.left += 0;
rc.right -=0;
m_page1.MoveWindow(&rc);
m_page2.MoveWindow(&rc);
m_page3.MoveWindow(&rc);
m_page4.MoveWindow(&rc);
//分别设置隐藏和显示
m_page1.ShowWindow(true);
m_page2.ShowWindow(false);
m_page3.ShowWindow(false);
m_page4.ShowWindow(false);
m_tab.SetCurSel(0);
//保存当前选择
return TRUE; // 除非将焦点设置到控件, 否则返回 TRUE
}
void CCalculatorDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮, 则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CCalculatorDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CCalculatorDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CCalculatorDlg::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 在此添加控件通知处理程序代码
int CurSel = m_tab.GetCurSel();
switch (CurSel)
{
case 0:
m_page1.ShowWindow(true);
m_page2.ShowWindow(false);
m_page3.ShowWindow(false);
m_page4.ShowWindow(false);
break;
case 1:
m_page1.ShowWindow(false);
m_page2.ShowWindow(true);
m_page3.ShowWindow(false);
m_page4.ShowWindow(false);
break;
case 2:
m_page1.ShowWindow(false);
m_page2.ShowWindow(false);
m_page3.ShowWindow(false);
m_page4.ShowWindow(true);
break;
case 3:
m_page1.ShowWindow(false);
m_page2.ShowWindow(false);
m_page3.ShowWindow(true);
m_page4.ShowWindow(false);
break;
}
*pResult = 0;
}
// Page1.cpp : 实现文件
//
#include "stdafx.h"
#include "CalculatorDlg.h"
#include "Calculator.h"
#include "Page1.h"
#include "afxdialogex.h"
#include "map"
using namespace std;
// CPage1 对话框
IMPLEMENT_DYNAMIC(CPage1, CDialogEx)
CPage1::CPage1(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_DIALOG1, pParent)
, OperatorPressed(true)
, Restarted(true)
, result(_T("0"))
, cntleft(0)
, cntright(0)
, pt(false)
, realans(_T(""))
{
}
CPage1::~CPage1()
{
}
void CPage1::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, result);
DDX_Text(pDX, IDC_ans, realans);
}
BEGIN_MESSAGE_MAP(CPage1, CDialogEx)
ON_BN_CLICKED(IDC_BUTTON7, &CPage1::OnBnClickedButton7)
ON_BN_CLICKED(IDC_BUTTON0, &CPage1::OnBnClickedButton0)
ON_BN_CLICKED(IDC_BUTTON1, &CPage1::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &CPage1::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON3, &CPage1::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON4, &CPage1::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON5, &CPage1::OnBnClickedButton5)
ON_BN_CLICKED(IDC_BUTTON6, &CPage1::OnBnClickedButton6)
ON_BN_CLICKED(IDC_BUTTON8, &CPage1::OnBnClickedButton8)
ON_BN_CLICKED(IDC_BUTTON9, &CPage1::OnBnClickedButton9)
ON_BN_CLICKED(IDC_BUTTON_plus, &CPage1::OnBnClickedButtonplus)
ON_BN_CLICKED(IDC_BUTTON_sub, &CPage1::OnBnClickedButtonsub)
ON_BN_CLICKED(IDC_BUTTON_multi, &CPage1::OnBnClickedButtonmulti)
ON_BN_CLICKED(IDC_BUTTON_div, &CPage1::OnBnClickedButtondiv)
ON_BN_CLICKED(IDC_BUTTON_back, &CPage1::OnBnClickedButtonback)
ON_BN_CLICKED(IDC_BUTTON_left, &CPage1::OnBnClickedButtonleft)
ON_BN_CLICKED(IDC_BUTTON_right, &CPage1::OnBnClickedButtonright)
ON_BN_CLICKED(IDC_BUTTON_mod, &CPage1::OnBnClickedButtonmod)
ON_BN_CLICKED(IDC_BUTTON_clear, &CPage1::OnBnClickedButtonclear)
ON_BN_CLICKED(IDC_BUTTON_power, &CPage1::OnBnClickedButtonpower)
ON_BN_CLICKED(IDC_BUTTON_equal, &CPage1::OnBnClickedButtonequal)
ON_BN_CLICKED(IDC_BUTTON_point, &CPage1::OnBnClickedButtonpoint)
END_MESSAGE_MAP()
// CPage1 消息处理程序
void CPage1::OnBnClickedButton0()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
int pos = result.GetLength() - 1;
if (OperatorPressed == true || Restarted == true || result.GetAt(pos) == ')')
result = "0";
else result += "0";
OperatorPressed = false;
Restarted = false;
UpdateData(FALSE);
}
void CPage1::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
int pos = result.GetLength() - 1;
if (OperatorPressed == true || Restarted == true || result.GetAt(pos) == ')')
result = "1";
else result += "1";
OperatorPressed = false;
Restarted = false;
UpdateData(FALSE);
}
void CPage1::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
int pos = result.GetLength() - 1;
if (OperatorPressed == true || Restarted == true || result.GetAt(pos) == ')')
result = "2";
else result += "2";
OperatorPressed = false;
Restarted = false;
UpdateData(FALSE);
}
void CPage1::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
int pos = result.GetLength() - 1;
if (OperatorPressed == true || Restarted == true || result.GetAt(pos) == ')')
result = "3";
else result += "3";
OperatorPressed = false;
Restarted = false;
UpdateData(FALSE);
}
void CPage1::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
int pos = result.GetLength() - 1;
if (OperatorPress
展开阅读全文