MFC创建自己的计算器


前言

最近在学习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仓库链接

还没弄好,弄好后会重新放进来

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值