前言
最近在学习MFC,正好制作一个计算器程序,用来学习的同时也可以练习MFC的使用
一、界面布局
二、主要代码
1.CalculatorDlg.cpp文件代码
代码如下:
// CalculatorDlg.cpp: 实现文件
//
#include "pch.h"
#include "framework.h"
#include "Calculator.h"
#include "CalculatorDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CCalculatorDlg 对话框
CCalculatorDlg::CCalculatorDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_CALCULATOR_DIALOG, pParent)
, mEdit(_T("0"))
//, current_operator(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCalculatorDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, mEdit);
}
BEGIN_MESSAGE_MAP(CCalculatorDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &CCalculatorDlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &CCalculatorDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON3, &CCalculatorDlg::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON4, &CCalculatorDlg::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON5, &CCalculatorDlg::OnBnClickedButton5)
ON_BN_CLICKED(IDC_BUTTON6, &CCalculatorDlg::OnBnClickedButton6)
ON_BN_CLICKED(IDC_BUTTON7, &CCalculatorDlg::OnBnClickedButton7)
ON_BN_CLICKED(IDC_BUTTON8, &CCalculatorDlg::OnBnClickedButton8)
ON_BN_CLICKED(IDC_BUTTON9, &CCalculatorDlg::OnBnClickedButton9)
ON_BN_CLICKED(IDC_BUTTON0, &CCalculatorDlg::OnBnClickedButton0)
ON_BN_CLICKED(IDC_BUTTONPoint, &CCalculatorDlg::OnBnClickedButtonpoint)
ON_BN_CLICKED(IDC_BUTTONGetResult, &CCalculatorDlg::OnBnClickedButtongetresult)
ON_BN_CLICKED(IDC_BUTTONAdd, &CCalculatorDlg::OnBnClickedButtonadd)
ON_BN_CLICKED(IDC_BUTTONSubtract, &CCalculatorDlg::OnBnClickedButtonsubtract)
ON_BN_CLICKED(IDC_BUTTONMultiple, &CCalculatorDlg::OnBnClickedButtonmultiple)
ON_BN_CLICKED(IDC_BUTTONDivide, &CCalculatorDlg::OnBnClickedButtondivide)
ON_BN_CLICKED(IDC_BUTTONClear, &CCalculatorDlg::OnBnClickedButtonclear)
ON_BN_CLICKED(IDC_BUTTONDeleta, &CCalculatorDlg::OnBnClickedButtondeleta)
END_MESSAGE_MAP()
// CCalculatorDlg 消息处理程序
BOOL CCalculatorDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 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
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CCalculatorDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
/// <summary>
/// 如果点击了清除按钮,则按下数字键时先清空显示
/// </summary>
void CCalculatorDlg::IsClear()
{
if (IsClickedClear) {
mEdit = "";
UpdateData(false);
IsClickedClear = false;
}
}
/// <summary>
/// 是否连续点击,用于运算符的判断
/// </summary>
bool CCalculatorDlg::IsContinuousClicks()
{
int length = mEdit.GetLength();
if (length == 0) {
MessageBox(_T("运算符前不能为空"));
return true;
}
auto _operator = mEdit.GetAt(length - 1);
if (_operator == '.' || _operator == '+' || _operator == '-' || _operator == '*' || _operator == '/') {
MessageBox(_T("不可连续使用运算符或."));
return true;
}
return false;
}
/// <summary>
/// 计算过程实现
/// </summary>
/// <param name="resultString">显示框的计算字符串</param>
/// <returns></returns>
double CCalculatorDlg::Calculate(CString resultString)
{
//如果字符串为空,返回0
if (resultString.GetLength() == 0) {
return 0;
}
else
{
std::vector<CString> number_operator;
CString temp{};
//获取字符串中所有的数字和运算符,将相连数字字符作为一个数字和运算符按顺序分别存储起来
for (int i = 0; i < resultString.GetLength(); i++) {
//如果是数字字符或者.
if (isdigit(resultString[i]) || resultString[i] == '.') {
temp += resultString[i];
if (i != resultString.GetLength() - 1) {
continue;
}
}
number_operator.push_back(temp);
if (i != resultString.GetLength() - 1) {
number_operator.push_back((CString)resultString[i]);
}
temp = "";
}
return Calculate(number_operator);
}
}
double CCalculatorDlg::Calculate(std::vector<CString> number_operator)
{
//按照运算规则进行计算,有乘除先算乘除
if (std::find(number_operator.begin(), number_operator.end(), "/") != number_operator.end()) {
auto temp = std::find(number_operator.begin(), number_operator.end(), "/");
int index = std::distance(number_operator.begin(), temp);
auto _pre = _tstof(number_operator[index - 1]);//运算符前一个数
auto _aft = _tstof(number_operator[index + 1]);//运算符后一个数
result = (_pre / _aft);
number_operator.erase(number_operator.begin() + (index - 1), number_operator.begin() + (index + 2));
std::string str = std::to_string(result);
CString cstr(str.c_str());
if (index - 1 >= number_operator.size()) {
number_operator.push_back(cstr);
}
else
{
number_operator.insert(number_operator.begin() + index - 1, cstr); //12+2*2-12/3
}
Calculate(number_operator);
}
else if (std::find(number_operator.begin(), number_operator.end(), "*") != number_operator.end()) {
auto temp = std::find(number_operator.begin(), number_operator.end(), "*");
int index = std::distance(number_operator.begin(), temp);
auto _pre = _tstof(number_operator[index - 1]);//运算符前一个数
auto _aft = _tstof(number_operator[index + 1]);//运算符后一个数
result = (_pre * _aft);
number_operator.erase(number_operator.begin() + (index - 1), number_operator.begin() + (index + 2));
std::string str = std::to_string(result);
CString cstr(str.c_str());
if (index - 1 >= number_operator.size()) {
number_operator.push_back(cstr);
}
else
{
number_operator.insert(number_operator.begin() + index - 1, cstr); //12+2*2-12/3
}
Calculate(number_operator);
}
else if (std::find(number_operator.begin(), number_operator.end(), "-") != number_operator.end()) {
auto temp = std::find(number_operator.begin(), number_operator.end(), "-");
int index = std::distance(number_operator.begin(), temp);
auto _pre = _tstof(number_operator[index - 1]);//运算符前一个数
auto _aft = _tstof(number_operator[index + 1]);//运算符后一个数
result = (_pre - _aft);
number_operator.erase(number_operator.begin() + (index - 1), number_operator.begin() + (index + 2));
std::string str = std::to_string(result);
CString cstr(str.c_str());
if (index - 1 >= number_operator.size()) {
number_operator.push_back(cstr);
}
else
{
number_operator.insert(number_operator.begin() + index - 1, cstr); //12+2*2-12/3
}
Calculate(number_operator);
}
else if (std::find(number_operator.begin(), number_operator.end(), "+") != number_operator.end()) {
auto temp = std::find(number_operator.begin(), number_operator.end(), "+");
int index = std::distance(number_operator.begin(), temp);
auto _pre = _tstof(number_operator[index - 1]);//运算符前一个数
auto _aft = _tstof(number_operator[index + 1]);//运算符后一个数
result = (_pre + _aft);
number_operator.erase(number_operator.begin() + (index - 1), number_operator.begin() + (index + 2));
std::string str = std::to_string(result);
CString cstr(str.c_str());
if (index - 1 >= number_operator.size()) {
number_operator.push_back(cstr);
}
else
{
number_operator.insert(number_operator.begin() + index - 1, cstr); //12+2*2-12/3
}
Calculate(number_operator);
}
return result;
}
void CCalculatorDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
UpdateData(true);
mEdit += "1";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
UpdateData(true);
mEdit += "2";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
UpdateData(true);
mEdit += "3";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
UpdateData(true);
mEdit += "4";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButton5()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
UpdateData(true);
mEdit += "5";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButton6()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
UpdateData(true);
mEdit += "6";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButton7()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
UpdateData(true);
mEdit += "7";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButton8()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
UpdateData(true);
mEdit += "8";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButton9()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
UpdateData(true);
mEdit += "9";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButton0()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
UpdateData(true);
mEdit += "0";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButtonpoint()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
if (IsContinuousClicks()) {
return;
}
UpdateData(true);
mEdit += ".";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButtongetresult()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
if (IsContinuousClicks()) {
return;
}
UpdateData(true);
result = Calculate(mEdit);
mEdit += "=";
std::string str = std::to_string(result);
CString cstr(str.c_str());
mEdit += cstr;
IsClickedClear = true;
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButtonadd()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
if (IsContinuousClicks()) {
return;
}
UpdateData(true);
mEdit += "+";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButtonsubtract()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
if (IsContinuousClicks()) {
return;
}
UpdateData(true);
mEdit += "-";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButtonmultiple()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
if (IsContinuousClicks()) {
return;
}
UpdateData(true);
mEdit += "*";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButtondivide()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
if (IsContinuousClicks()) {
return;
}
UpdateData(true);
mEdit += "/";
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButtonclear()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
result = 0;
mEdit = "0";
IsClickedClear = true;
UpdateData(false);
}
void CCalculatorDlg::OnBnClickedButtondeleta()
{
// TODO: 在此添加控件通知处理程序代码
IsClear();
UpdateData(true);
mEdit.Delete(mEdit.GetLength() - 1, 1);
if (mEdit.GetLength() < 1) {
mEdit = "0";
}
UpdateData(false);
}
2.CalculatorDlg.h文件代码
代码如下:
// CalculatorDlg.h: 头文件
//
#include <iostream>
#include <string>
#include <vector>
#pragma once
// CCalculatorDlg 对话框
class CCalculatorDlg : public CDialogEx
{
// 构造
public:
CCalculatorDlg(CWnd* pParent = nullptr); // 标准构造函数
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_CALCULATOR_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
private:
bool IsClickedClear = false;
void IsClear();
bool IsContinuousClicks();//是否连续点击,用于运算符的判断
double Calculate(CString resultString);//计算过程实现
double Calculate(std::vector<CString> number_operator);
public:
afx_msg void OnBnClickedButton1();
CString mEdit;
double result = 0;
afx_msg void OnBnClickedButton2();
afx_msg void OnBnClickedButton3();
afx_msg void OnBnClickedButton4();
afx_msg void OnBnClickedButton5();
afx_msg void OnBnClickedButton6();
afx_msg void OnBnClickedButton7();
afx_msg void OnBnClickedButton8();
afx_msg void OnBnClickedButton9();
afx_msg void OnBnClickedButton0();
afx_msg void OnBnClickedButtonpoint();
afx_msg void OnBnClickedButtongetresult();
afx_msg void OnBnClickedButtonadd();
afx_msg void OnBnClickedButtonsubtract();
afx_msg void OnBnClickedButtonmultiple();
afx_msg void OnBnClickedButtondivide();
afx_msg void OnBnClickedButtonclear();
afx_msg void OnBnClickedButtondeleta();
};
运行结果显示
Github仓库链接
还没弄好,弄好后会重新放进来