WindowsAPI编程 简单的计算器

                                                   WindowsAPI编程 简单的计算器

一、简述

    记--使用WindowsAPI开发图形界面应用--简单的计算器。

    例子:链接: https://pan.baidu.com/s/1SDg5RByN4xQohoi-ao8Wzg 提取码: kv42 

二、效果

        

                  

三、工程结构

        

四、源文件

main.cpp文件

#define _CRT_SECURE_NO_WARNINGS  //有一些函数有新的安全版本,使用就之前的会报警告
#include <windows.h>
#include "resource.h"
#include <stdio.h>

#define EXP_MAX_LEN 22

char gSign[3] = {0};//运算符×÷+-

//判断指定的字符是否是运算符
int IsASign(const char* _char,unsigned char _flag)
{
	if(NULL == _char)
	{
		return 0;
	}

	if(1 == _flag)//ASCII模式
	{
		if(_char[0] == '+' )
		{
			return 3;
		}
		else if(_char[0] == '-' )
		{
			return 4;
		}
	}	
	
	if(strlen(_char)>1)//×÷是中文字符,占2个字节
	{
		if(_char[0] == "×"[0] && _char[1] == "×"[1] )
		{
			return 1;
		}

		if(_char[0] == "÷"[0] && _char[1] == "÷"[1] )
		{
			return 2;
		}

		if(2 == _flag)//判断最后一个字符的时候
		{
			if(_char[1] == '+' )
			{
				return 3;
			}
			else if(_char[1] == '-' )
			{
				return 4;
			}
		}	
	}

	return 0;
}

//判断表达式是否含有运算符
int ExpIsHasSign(const char* _exp)
{
	int i;
	int len;
	if(NULL != _exp)
	{
		len = strlen(_exp);
		for(i=0; i<len; i++)
		{
			if(IsASign(&(_exp[i]),1)>0)
			{
				return 1;
			}
		}
	}
	return 0;
}

//计算两个运算数的结果
int GetResult(long long _leftVal, long long _rightVal, char _sign, long long* _result)
{
	int ret = 0;
	if(_sign == '*')
	{
		*_result = _leftVal*_rightVal;
		ret = 1;
	}
	else if(_sign == '/')
	{
		if(0 != _rightVal)
		{
			*_result = _leftVal/_rightVal;
			ret = 1;
		}
	}
	else if(_sign == '+')
	{
		*_result = _leftVal+_rightVal;
		ret = 1;
	}
	else if(_sign == '-')
	{
		*_result = _leftVal-_rightVal;
		ret = 1;
	}
	return ret;
}

//判断字符串最后一个字符是否是运算符
int StrLastCharIsSign(char* _str)
{
	UINT len = 0;
	if(NULL == _str)
	{
		return 0;
	}

	len = strlen(_str);
	if(len>512)
	{
		len = 511;
		_str[512] = '\0';
	}
	if(len>0)
	{
		if(IsASign(&(_str[len-1]),1)>0 )
		{
			return 1;
		}
		if(len>1)
		{
			if(IsASign(&(_str[len-2]),2)>0)
			{
				return 1;
			}
		}
	}
	return 0;
}

//判断表达式最后一个字符是否是运算符
int LastCharIsSign(HWND _hwndDlg, int _nID)
{
	char buf[512] = {0};
	GetDlgItemText(_hwndDlg, _nID, buf, sizeof(buf));
	return StrLastCharIsSign(buf);
}

//判断一个字符是否是数字
char IsANum(const char _ch)
{
	if(_ch>= '0' && _ch<='9')
	{
		return _ch;
	}
	return -1;
}

//将字符串形式的运算数转化为数字
int StrToDec(const char* strNum, long long* num)
{
	if(NULL == strNum)
	{
		return -1;
	}
	*num = 0;
	int len = strlen(strNum);
	int i;
	for(i=0; i<len; i++)
	{
		if(IsANum(strNum[i])>0)
		{
			*num = (*num*10) + (strNum[i] - '0');
		}
	}
	return 0;
}

//计算表达式结果
int GetExpResult(HWND hwndDlg, int nID)
{
	char buf[512] = {0};
	GetDlgItemText(hwndDlg, nID, buf, sizeof(buf));
	char* bufPtr = buf;
	
	int len = strlen(gSign);
	if(len<=0)
	{
		return -1;
	}

	int isNagtive = 0;//标识左值是否是负数
	if(buf[0] == '-')
	{
		isNagtive = 1;
		bufPtr++;
	}

	len = strlen(bufPtr);
	if(len<3)
	{
		return -2;
	}
	

	char* signPtr = strstr(bufPtr, gSign);
	if(NULL != signPtr && 0 == StrLastCharIsSign(bufPtr))//有运算符并且不是最后一个字符的(也就是用户输入了两个运算数和一个运算符了才进行运算)
	{
		int signIndex = strlen(signPtr);
		char chLeftVal[512] = {0};//左值
		char chRightVal[512] = {0};//右值
		long long numLeftVal = 0;
		long long numRightVal = 0;
		long long result = 0;//结果
		int sign = IsASign(gSign,1);
		
		memcpy(chLeftVal,bufPtr,len-signIndex);
		memcpy(chRightVal,&bufPtr[len-signIndex+1+(sign/3+1)%2],signIndex-strlen(gSign));

		int ret1, ret2, ret3 = 0;
		ret1 = StrToDec(chLeftVal, &numLeftVal);
		ret2 = StrToDec(chRightVal, &numRightVal);
		if(1 == isNagtive)
		{
			numLeftVal = -numLeftVal;
		}
		
		if(ret1 == 0 && ret2 == 0)
		{
			switch(sign)
			{
				case 1:
					ret3 = GetResult(numLeftVal, numRightVal, '*', &result);
					break;
				case 2:
					ret3 = GetResult(numLeftVal, numRightVal, '/', &result);
					break;
				case 3:
					ret3 = GetResult(numLeftVal, numRightVal, '+', &result);
					break;
				case 4:
					ret3 = GetResult(numLeftVal, numRightVal, '-', &result);
					break;
				default:
					ret3 = GetResult(numLeftVal, numRightVal, '+', &result);
					break;
			}
			if(1 == ret3)
			{
				char tmp[128] = {0};
				sprintf(tmp, "%lld", result);
				if(strlen(tmp)<=0)
				{
					memcpy(tmp, "0", 2);
				}
				SetDlgItemText(hwndDlg, IDC_EXP, tmp);//设置结果
				memset(gSign,0,3);
			}	
		}
		
		
		
	}
	return 0;
}

//追加文本到编辑框
int AppendText(HWND hwndDlg, int nID, const char* str)
{
	if(NULL == str)
	{
		return 0;
	}

	char buf[EXP_MAX_LEN+2] = {0};
	int len1,len2;
	GetDlgItemText(hwndDlg, nID, buf, sizeof(buf));
	len1 = strlen(buf);
	len2 = strlen(str);
	if(len1+len2>=EXP_MAX_LEN)
	{
		return 0;
	}
	memcpy(&buf[len1], str, EXP_MAX_LEN-len1);
	len1 = strlen(buf);
	if(0 >= len1)
	{
		SetDlgItemText(hwndDlg, IDC_EXP, "0");
		return 0;
	}

	int i = 0;
	if(len1>1)
	{	
		for(i=0; i<len1; i++)//找到首个不为0的字符
		{
			if(buf[i] != '0')
				break;
		}
	}
	
	if(0 == buf[i] || IsASign(&buf[i],1)>0 )//如果全是0,或者首个非0字符是运算符就可以保留一个0
	{
		if(buf[0] != '-' &&buf[i] != '-')//如果上一次计算结果不是负数
		{
			i--;
		}		
	}
	SetDlgItemText(hwndDlg, IDC_EXP, &buf[i]);
	return 0;
}

//退格--将编辑框文本内容最后一个字符删除
int DeleteAChar(HWND hwndDlg, int nID)
{
	char buf[512] = {0};
	UINT len = 0;
	GetDlgItemText(hwndDlg, nID, buf, sizeof(buf));
	len = strlen(buf);
	if(len>512)
	{
		len = 511;
		buf[512] = '\0';
	}
	if(len > 0)
		buf[len-1] = '\0';

	len = strlen(buf);
	if(len == 0)//表达式不为空
	{
		buf[0] = '0';
		buf[1] = '\0';
	}
	SetDlgItemText(hwndDlg, IDC_EXP, buf);
	return 0;
}

//回调函数--接受并处理 点击(操作)窗口、控件 后产生的各种消息
INT_PTR CALLBACK MyDialogProcess(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	unsigned short id = 0;
	
	switch(uMsg)
	{
		case WM_INITDIALOG://初始化对话框的时候,将编辑框内容设置为0
			SetDlgItemText(hwndDlg, IDC_EXP, "0");
			//窗体句柄,窗体的顺序,窗体位置x,y;窗体大小宽高,参数可选项
			SetWindowPos(hwndDlg,HWND_TOPMOST,200,200,100,100,SWP_NOSIZE);//设置窗体位置,HWND_TOPMOST:窗体置顶,SWP_NOSIZE:忽略设置的窗体大小设置,即不改变窗体大小。
			break;
		case WM_COMMAND:
			id =  LOWORD(wParam);
			
			switch(id)
			{
				case IDCANCEL:
					EndDialog(hwndDlg, IDCANCEL);//退出,关闭对话框
					break;
				case IDC_BUTTON9:
					AppendText(hwndDlg, IDC_EXP, "9");
					break;
				case IDC_BUTTON8:
					AppendText(hwndDlg, IDC_EXP, "8");
					break;
				case IDC_BUTTON7:
					AppendText(hwndDlg, IDC_EXP, "7");
					break;
				case IDC_BUTTON6:
					AppendText(hwndDlg, IDC_EXP, "6");
					break;
				case IDC_BUTTON5:
					AppendText(hwndDlg, IDC_EXP, "5");
					break;
				case IDC_BUTTON4:
					AppendText(hwndDlg, IDC_EXP, "4");
					break;
				case IDC_BUTTON3:
					AppendText(hwndDlg, IDC_EXP, "3");
					break;
				case IDC_BUTTON2:
					AppendText(hwndDlg, IDC_EXP, "2");
					break;
				case IDC_BUTTON1:
					AppendText(hwndDlg, IDC_EXP, "1");
					break;
				case IDC_BUTTON0:
					AppendText(hwndDlg, IDC_EXP, "0");
					break;
				case IDC_BUTTONPlus:
					GetExpResult(hwndDlg, IDC_EXP);	
					if(1 != LastCharIsSign(hwndDlg,IDC_EXP))//前面不是运算符时,才能添加(两个运算符不能在一块)
					{
						AppendText(hwndDlg, IDC_EXP, "+");
						memcpy(gSign,"+",2);
					}
					break;
				case IDC_BUTTONSub:
					GetExpResult(hwndDlg, IDC_EXP);	
					if(1 != LastCharIsSign(hwndDlg,IDC_EXP))
					{
						AppendText(hwndDlg, IDC_EXP, "-");
						memcpy(gSign,"-",2);
					}
					
					break;
				case IDC_BUTTONMul:
					GetExpResult(hwndDlg, IDC_EXP);	
					if(1 != LastCharIsSign(hwndDlg,IDC_EXP))
					{
						AppendText(hwndDlg, IDC_EXP, "×");
						memcpy(gSign,"×",2);
					}
					break;
				case IDC_BUTTONDiv:
					GetExpResult(hwndDlg, IDC_EXP);	
					if(1 != LastCharIsSign(hwndDlg,IDC_EXP))
					{
						AppendText(hwndDlg, IDC_EXP, "÷");
						memcpy(gSign,"÷",2);
					}
					break;
				case IDC_BUTTONClear:
					SetDlgItemText(hwndDlg, IDC_EXP, "0");
					memset(gSign,0,3);
					break;
				case IDC_BUTTONDel:
					DeleteAChar(hwndDlg, IDC_EXP);
					break;
				case IDC_BUTTONEqual://计算结果
					GetExpResult(hwndDlg, IDC_EXP);						
					break;
				case IDC_MenuAbout:
					//参数:父窗口 内容 标题 按钮类型及个数
					MessageBox(NULL, "这是一个简单的计算器!!!", "提示", MB_ICONINFORMATION|MB_OKCANCEL);//消息框,返回的是按钮编号
					break;
			}

			break;
		
	}
	return 0;
}

//程序主入口
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmd, int nCmdShow)
{	
	//添加图标,直接添加即可
	
	//参数:资源 对话框ID 父窗口 回调函数
	DialogBox(hInstance,(LPSTR)IDD_DIALOG1, NULL, MyDialogProcess);//弹出一个对话框

	return 0;
}

五、总结

5.1  一些函数的简单介绍

hwnd:窗口句柄
nID:控件ID
int GetDlgItemInt(hwnd, nID, NULL, TRUE);获取编辑框内容为一个数字
SetDlgItemInt(hwnd, nID, aNumber, TRUE);设置编辑框内容为一个数字,aNumber:要设置的数字
GetDlgItemText(hwnd, nID, str, sizeof(str));获取编辑框文本内容,(放到str中,通常str是字符数组)
SetDlgItemText(hwnd, nID, str);设置编辑框文本内容,str:要设置的文本
SetWindowText(hwnd, str);设置窗口标题,str:要设置的标题
SetWindowPos(hwnd,HWND_TOPMOST,X,Y,cx,cy,uFlags);设置窗体位置,HWND_TOPMOST:窗口显示在最前面

以上API函数相关细节请参考:WinUser.h

5.2 添加资源

-

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值