简单计算器(图形界面)(double型计算,四舍五入,精度可选)定时器实现

看网课的时候,跟着学了一下计算器,但是老师只讲了int型的计算,

于是自己研究了一下double型的,结果还真是遇到了不少麻烦;

因为我用的是VS2017  wsprintf 不支持 浮点数 找了好多网上的帖子,但是C语言的没找到合适的

所以自己用整数 小数分开处理的方式解决了一下(如果哪位有更好的办法,请指点)

运行过程中先后发现了一些小bug,已经处理

1、对于分开处理的小数部分,如果是负数,会在小数点后出现“-”号,已经处理

2、当精度选择为“0”时,两数相除,结果为 -1~0 之间会出现“-”号丢失的情况,原因是转 int ,已经处理

3、 当精度选择为“0”时,四舍五入时,整数 ++ 负数 --,已经处理,并且,最后只有整数部分转为TCHAR

4、精度选择非 0,两数相除为负数,且整数部分等于 0 的,会丢失 “-”号,已经处理

5、当两数计算记过整数(小数部分为“0”)时,精度选择除0,1外,其他均不增加尾部的“0”

程序界面的日历 和 时间 菜单 图片 是随便放置的  只是为了记录一下,相关代码及插件的用法,可以忽略

后面还有两种代码,都不是很完善,留作纪念吧,怎么说也记录了我的“折腾”

闲话不多说了

计算器功能:

1、double 型处理 (保证计算结果准确性)

2、精度选择(这里精度设定,恰好与getcursel取值一致,省去了变量)

3、计算结果,四舍五入(正+负-)

4、因为计算精度那里也用的buttion,所以也实现了计算功能

运行截图

乘法

 

除法

加法

减法

 

最终代码如下:(后面两种代码,仅为记录,请忽略

 

/*RM Calculator
Powered By RedMaple
双精度计算,精度0-7可选
四舍五入*/

#include <Windows.h>
#include <Windowsx.h>
#include <Mmsystem.h>
#include "resource.h"

INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
VOID CALLBACK LocalTimerProc(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTime);
INT_PTR CALLBACK _COMMAND(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
HINSTANCE hgInst;
int WINAPI WinMain(HINSTANCE hThisApp, HINSTANCE hPrevApp, LPSTR lpCmd, int nShow)
{
	hgInst = hThisApp;
	HWND hdlg = CreateDialog(hThisApp, MAKEINTRESOURCE(IDD_DIALOGRedMaple), GetDesktopWindow(), (DLGPROC)DlgProc);
	if (!hdlg)
	{
		return 0;
	}
	ShowWindow(hdlg, SW_SHOW);
	UpdateWindow(hdlg);
	SetTimer(hdlg, 1, 1000, &LocalTimerProc);//设置定时器
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	
	return 0;
}

INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	
	switch (msg)
	{
	case WM_INITDIALOG:	
	{	// 设置对话框的图标
		SendMessage(hDlg, WM_SETICON, IDI_ICONRMC, (LPARAM)LoadIcon(hgInst, MAKEINTRESOURCE(IDI_ICONRMC)));
		/*初始化运算符号 “+,-,*,/”*/
		HWND COMBOBOXJJCC = GetDlgItem(hDlg, IDC_COMBOjjcc);
		ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("+"));
		ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("-"));
		ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("*"));
		ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("/"));	
		ComboBox_SetCurSel(COMBOBOXJJCC, 0);//设置默认运算为“+”
		/*初始化精度 “0,1,2,3,4,5,6,7”*///恰好和句柄index一致
		HWND COMBOBOXJD = GetDlgItem(hDlg, IDC_COMBOJD);
		ComboBox_InsertString(COMBOBOXJD, -1, TEXT("0"));
		ComboBox_InsertString(COMBOBOXJD, -1, TEXT("1"));
		ComboBox_InsertString(COMBOBOXJD, -1, TEXT("2"));
		ComboBox_InsertString(COMBOBOXJD, -1, TEXT("3"));
		ComboBox_InsertString(COMBOBOXJD, -1, TEXT("4"));
		ComboBox_InsertString(COMBOBOXJD, -1, TEXT("5"));
		ComboBox_InsertString(COMBOBOXJD, -1, TEXT("6"));
		ComboBox_InsertString(COMBOBOXJD, -1, TEXT("7"));
		ComboBox_SetCurSel(COMBOBOXJD, 2);//设置默认精度为“2”,小数点后保留2位
		
	}
	case WM_COMMAND:
	{
		 _COMMAND(hDlg, msg, wParam,lParam);//函数调用
	}
	break;
	case WM_SYSCOMMAND:
		if (wParam == SC_CLOSE)
		{
			PostQuitMessage(0);//退出
		}
		return 0;
	
	}
		
	return (INT_PTR)FALSE;
}
INT_PTR CALLBACK _COMMAND(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (wParam)
	{
		case IDC_BUTTON2JD://精度按钮,触发计算
		case IDC_BUTTON1DH://等于按钮,触发计算
		{
			//设置缓存
			TCHAR strc1[256];
			TCHAR strc2[256];
			TCHAR strc3[256];
			//获取字符串
			GetDlgItemText(hDlg, IDC_EDIT1, strc1, sizeof(strc1));
			GetDlgItemText(hDlg, IDC_EDIT2, strc2, sizeof(strc2));
			//转换字符串 to double
			double i1 = _wtof(strc1);
			double i2 = _wtof(strc2);
			double i3 = 0;//计算结果
			//获取运算符选择情况
			HWND COMBOBOXJJCC = GetDlgItem(hDlg, IDC_COMBOjjcc);
			int count = ComboBox_GetCurSel(COMBOBOXJJCC);
			//计算
			switch (count)
			{
			case 0:
			{
				i3 = i1 + i2;
			}
			break;
			case 1:
			{
				i3 = i1 - i2;
			}
			break;
			case 2:
			{
				i3 = i1 * i2;
			}
			break;
			case 3:
			{
				i3 = i1 / i2;
			}
			break;
			}
			//_gcvt_s(strc3,sizeof(strc3),i3, 15 );
			//获取精度选择情况
			HWND COMBOBOXJD = GetDlgItem(hDlg, IDC_COMBOJD);
			int curjd = ComboBox_GetCurSel(COMBOBOXJD);
			//double 类型转 TCHAR,没有找到很好的函数,所以自己写了
			//方法是将 double分为整数部分和小数部分分别转换为 int
			//然后用 wsprintf 转 TCHAR 
			//实现精度可选,四舍五入,
			int j;
			int i3integer = (int)i3;//整数部分
			int i3decimal;//小数部分
			//根据精度计算小数部分,i3tem为临时变量
			double i3tem = i3- i3integer;
			if (i3tem < 0)//符号转换,避免小数点后出现"-"号
			{
				i3tem = -1* i3tem ;
			}
			//小数部分转整数
			for (j = 0; j < curjd; j++)
			{
				i3tem *= 10;
			}
			//小数部分有效取值(int)
			i3decimal = (int)i3tem;
			//有效位,下一位四舍五入计算
			if (((i3tem - (int)i3tem))*10 > 4)
			{
				i3decimal++;
			}
			//精度选择 0 的处理
			if (0 == curjd)
			{
				if (i3 < 0 && (int)i3 == 0)//两数相除为负数,且整数部分等于 0 的处理
				{
					i3integer = 0;//因为不能显示"-0",所以符号另作处理
				}
				else
				{
					if (i3tem * 10 >= 5 && (int)i3 > 0)//正数 5入 整数部分 +1
					{
						i3integer++;
					}
					else if (i3tem * 10 >= 5 && (int)i3 < 0)//负数 5入 整数部分 -1
					{
						i3integer--;
					}
				}
				wsprintf(strc3, L"%d", i3integer);//字符串中只保留整数部分
			}
			else//精度选择非 0 的处理
			{
				if (i3 < 0 && (int)i3 == 0)//两数相除为负数,且整数部分等于 0 的处理
				{
					wsprintf(strc3, L"-0.%d", i3decimal);//手动添加 -0. 只存入小数部分
				}
				else//正常情况下,将整数部分 "." 小数部分存入字符串
				{
					wsprintf(strc3, L"%d.%d", i3integer, i3decimal);
				}
			}
			SetDlgItemText(hDlg, IDC_EDIT3, strc3);//显示结果
	}
	break;
	case ID_OK:
	{
		MessageBox(hDlg, TEXT("确定按键被按下"), TEXT("按键选择"), MB_OK);

	}
	break;
	case ID_CANCEL:
	{
		MessageBox(hDlg, TEXT("取消按键被按下,即将退出"), TEXT("按键选择"), MB_OK);
		PostQuitMessage(0);//退出
	}
	break;
	}
	return 0;
}
//定时器,显示时钟
VOID CALLBACK LocalTimerProc(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTime)
{
	SYSTEMTIME slt;
	GetLocalTime(&slt);
	TCHAR ltime[256];
	wsprintf(ltime, L"%d年%d月%d日 %d:%d:%d", slt.wYear, slt.wMonth, slt.wDay,
		slt.wHour, slt.wMinute, slt.wSecond);
	//SetDlgItemText(hDlg, IDC_EDITTIME, ltime);
	HWND hwndEdit = GetDlgItem(hDlg, IDC_EDITTIME);
	Edit_SetText(hwndEdit, ltime);
}

 

 

以下是不完善的代码,仅作为记录:

/*int数据类型计算器*/

#include <Windows.h>
#include <Windowsx.h>
#include <Mmsystem.h>
#include "resource.h"

INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
VOID CALLBACK LocalTimerProc(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTime);
INT_PTR CALLBACK _COMMAND(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
HINSTANCE hgInst;
int WINAPI WinMain(HINSTANCE hThisApp, HINSTANCE hPrevApp, LPSTR lpCmd, int nShow)
{
	hgInst = hThisApp;
	HWND hdlg = CreateDialog(hThisApp, MAKEINTRESOURCE(IDD_DIALOGRedMaple), GetDesktopWindow(), (DLGPROC)DlgProc);
	if (!hdlg)
	{
		return 0;
	}
	ShowWindow(hdlg, SW_SHOW);
	UpdateWindow(hdlg);
	SetTimer(hdlg, 1, 1000, &LocalTimerProc);//设置定时器
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	
	return 0;
}

INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	
	switch (msg)
	{
	case WM_INITDIALOG:	
	{	// 设置对话框的图标
		//SendMessage(hDlg, WM_SETICON, IDI_ICONRM, (LPARAM)LoadIcon(hgInst, MAKEINTRESOURCE(IDC_EDIT1)));
		HWND COMBOBOXJJCC = GetDlgItem(hDlg, IDC_COMBOjjcc);
		ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("+"));
		ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("-"));
		ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("*"));
		ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("/"));	
	}
	case WM_COMMAND:
	{
		 _COMMAND(hDlg, msg, wParam,lParam);
	}
	break;
	case WM_SYSCOMMAND:
		if (wParam == SC_CLOSE)
		{
			PostQuitMessage(0);//退出
		}
		return 0;
	
	}
		
	return (INT_PTR)FALSE;
}
INT_PTR CALLBACK _COMMAND(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (wParam)
	{
	case IDC_BUTTON1:
	{
		TCHAR strc1[256];
		TCHAR strc2[256];
		TCHAR strc3[256];
		//char strc3[256];
		GetDlgItemText(hDlg, IDC_EDIT1, strc1, sizeof(strc1));
		GetDlgItemText(hDlg, IDC_EDIT2, strc2, sizeof(strc2));
		int i1 = _wtoi(strc1);
		int i2 = _wtoi(strc2);
		int i3 = 0;
		HWND COMBOBOXJJCC = GetDlgItem(hDlg, IDC_COMBOjjcc);
		int count = ComboBox_GetCurSel(COMBOBOXJJCC);
		switch (count)
		{
		case 0:
		{
			i3 = i1 + i2;
		}
		break;
		case 1:
		{
			i3 = i1 - i2;
		}
		break;
		case 2:
		{
			i3 = i1 * i2;
		}
		break;
		case 3:
		{
			i3 = i1 / i2;
		}
		break;
		}
		//_gcvt_s(strc3,sizeof(strc3),i3, 15 );
		
		wsprintf(strc3, L"%d", i3);
		SetDlgItemText(hDlg, IDC_EDIT3, strc3);
	}
	break;
	case ID_OK:
	{
		MessageBox(hDlg, TEXT("确定按键被按下"), TEXT("按键选择"), MB_OK);

	}
	break;
	case ID_CANCEL:
	{
		MessageBox(hDlg, TEXT("取消按键被按下,即将退出"), TEXT("按键选择"), MB_OK);
		PostQuitMessage(0);//退出
	}
	break;
	}
	return 0;
}
VOID CALLBACK LocalTimerProc(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTime)
{
	SYSTEMTIME slt;
	GetLocalTime(&slt);
	TCHAR ltime[256];
	wsprintf(ltime, L"%d年%d月%d日 %d:%d:%d", slt.wYear, slt.wMonth, slt.wDay,
		slt.wHour, slt.wMinute, slt.wSecond);
	//SetDlgItemText(hDlg, IDC_EDITTIME, ltime);
	HWND hwndEdit = GetDlgItem(hDlg, IDC_EDITTIME);
	Edit_SetText(hwndEdit, ltime);
}

 

/*DOUBLE类型数值计算器*/

#include <Windows.h>
#include <Windowsx.h>
#include <Mmsystem.h>
#include "resource.h"

INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
VOID CALLBACK LocalTimerProc(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTime);
INT_PTR CALLBACK _COMMAND(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
HINSTANCE hgInst;
int WINAPI WinMain(HINSTANCE hThisApp, HINSTANCE hPrevApp, LPSTR lpCmd, int nShow)
{
	hgInst = hThisApp;
	HWND hdlg = CreateDialog(hThisApp, MAKEINTRESOURCE(IDD_DIALOGRedMaple), GetDesktopWindow(), (DLGPROC)DlgProc);
	if (!hdlg)
	{
		return 0;
	}
	ShowWindow(hdlg, SW_SHOW);
	UpdateWindow(hdlg);
	SetTimer(hdlg, 1, 1000, &LocalTimerProc);//设置定时器
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	
	return 0;
}

INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	
	switch (msg)
	{
	case WM_INITDIALOG:	
	{	// 设置对话框的图标
		//SendMessage(hDlg, WM_SETICON, IDI_ICONRM, (LPARAM)LoadIcon(hgInst, MAKEINTRESOURCE(IDC_EDIT1)));
		HWND COMBOBOXJJCC = GetDlgItem(hDlg, IDC_COMBOjjcc);
		ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("+"));
		ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("-"));
		ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("*"));
		ComboBox_InsertString(COMBOBOXJJCC, -1, TEXT("/"));	
	}
	case WM_COMMAND:
	{
		 _COMMAND(hDlg, msg, wParam,lParam);
	}
	break;
	case WM_SYSCOMMAND:
		if (wParam == SC_CLOSE)
		{
			PostQuitMessage(0);//退出
		}
		return 0;
	
	}
		
	return (INT_PTR)FALSE;
}
INT_PTR CALLBACK _COMMAND(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (wParam)
	{
	case IDC_BUTTON1:
	{
		TCHAR strc1[256];
		TCHAR strc2[256];
		TCHAR strc31[256];
		char strc3[256];
		GetDlgItemText(hDlg, IDC_EDIT1, strc1, sizeof(strc1));
		GetDlgItemText(hDlg, IDC_EDIT2, strc2, sizeof(strc2));
		double i1 = _wtof(strc1);
		double i2 = _wtof(strc2);
		double i3 = 0;
		HWND COMBOBOXJJCC = GetDlgItem(hDlg, IDC_COMBOjjcc);
		int count = ComboBox_GetCurSel(COMBOBOXJJCC);
		switch (count)
		{
		case 0:
		{
			i3 = i1 + i2;
		}
		break;
		case 1:
		{
			i3 = i1 - i2;
		}
		break;
		case 2:
		{
			i3 = i1 * i2;
		}
		break;
		case 3:
		{
			i3 = i1 / i2;
		}
		break;
		}
		_gcvt_s(strc3,sizeof(strc3),i3, 15 );
		
		//wsprintfA(strc3, "%lf", i3);
		SetDlgItemTextA(hDlg, IDC_EDIT3, strc3);
	}
	break;
	case ID_OK:
	{
		MessageBox(hDlg, TEXT("确定按键被按下"), TEXT("按键选择"), MB_OK);

	}
	break;
	case ID_CANCEL:
	{
		MessageBox(hDlg, TEXT("取消按键被按下,即将退出"), TEXT("按键选择"), MB_OK);
		PostQuitMessage(0);//退出
	}
	break;
	}
	return 0;
}
VOID CALLBACK LocalTimerProc(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTime)
{
	SYSTEMTIME slt;
	GetLocalTime(&slt);
	TCHAR ltime[256];
	wsprintf(ltime, L"%d年%d月%d日 %d:%d:%d", slt.wYear, slt.wMonth, slt.wDay,
		slt.wHour, slt.wMinute, slt.wSecond);
	//SetDlgItemText(hDlg, IDC_EDITTIME, ltime);
	HWND hwndEdit = GetDlgItem(hDlg, IDC_EDITTIME);
	Edit_SetText(hwndEdit, ltime);
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值