C++ 非可视化编程的windows窗口计算器(简易版)

一个在Dev-C++中写的非可视化编程的windows窗口计算器简易版,其运行效果如下图:

C++ 非可视化编程的windows窗口计算器(简易版)

所有框架和单目运算已经做好,+-*/暂未完成,代码还有改进空间...... 

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <cmath>
#include <windows.h>

using namespace std;

struct button {
	int x;	int y;  //坐标
	int w;	int h;  //宽高
	const char *szText;  //Caption
}
Buttons[] = {
	30, 370,0,0,"0",
	30, 310,0,0,"1",
	90, 310,0,0,"2",
	150,310,0,0,"3",
	30, 250,0,0,"4",
	90, 250,0,0,"5",
	150,250,0,0,"6",
	30, 190,0,0,"7",
	90, 190,0,0,"8",
	150,190,0,0,"9",
	150,370,0,0," .",
	210,370,0,0,"+",
	210,310,0,0,"-",
	210,250,0,0,"×",
	210,190,0,0,"÷",
	210,130,0,0,"±",
	150,130,0,0,"%",
	270,310,0,0,"=",
	270,250,0,0,"1/x",
	270,190,0,0,"√x",
	270,130,0,0,"y^2",
	90, 130,0,0,"C",
	30, 130,0,0,"←"
};

#define NUM (sizeof Buttons / sizeof Buttons[0])

string i2str(int i)
{
	string s;
	stringstream ss;
	ss<<i;
	s=ss.str();
	ss.clear();
	return s;
}

int str2i(string s)
{
	int i;
	stringstream ss;
	ss<<s;
	ss>>i;
	ss.clear();
	return i;
}

string d2str(long double d)
{
	string s;
	stringstream ss;
	ss<<setprecision(16)<<d;
	s=ss.str();
	ss.clear();
	return s;
}
 
long double str2d(string s)
{
	long double d;
	stringstream ss;
	ss<<s;
	ss>>setprecision(16)>>d;
	ss.clear();
	return d;
}

/* This is where all the input to the window goes to */
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	char buf[1024] = {0};
	string tmp;
	unsigned int lWord = LOWORD(wParam);
	HDC	hdc;
	PAINTSTRUCT	ps;
	HWND tHwnd, bHwnd;
	static HWND sHwnd1, sHwnd2;
	HFONT hFont = (HFONT)GetStockObject(SYSTEM_FIXED_FONT); 
	switch(Message) {
		//在 WM_CREATE 事件中创建所有控件 
		case WM_CREATE: {
	        tHwnd = CreateWindow( TEXT("button"),NULL,
					WS_CHILD | WS_VISIBLE | BS_GROUPBOX, /*分组框*/
                    30, 25,
                    290, 80,
					hwnd,(HMENU)31,NULL,NULL);
			if (!tHwnd) MessageBox(NULL,"创建分组框失败","Message",MB_OK|MB_ICONERROR);
			ShowWindow(tHwnd,SW_SHOW);
			//SendMessage(tHwnd, WM_SETFONT, (WPARAM)hFont, lParam);  //设置控件字体
            UpdateWindow(tHwnd);
            
	        sHwnd1 = CreateWindow( TEXT("static"),NULL,
					WS_CHILD | WS_VISIBLE ,
                    36, 40,
                    278, 22,
					hwnd,(HMENU)32,NULL,NULL);
			if (!sHwnd1) MessageBox(NULL,"创建文本框失败","Message",MB_OK|MB_ICONERROR);
			ShowWindow(sHwnd1,SW_SHOW);
			SendMessage(sHwnd1, WM_SETFONT, (WPARAM)hFont, lParam);  //设置控件字体
			SetWindowLong(sHwnd1,GWL_STYLE,GetWindowLong(sHwnd1,GWL_STYLE) | ES_RIGHT); //设置右对齐 
            UpdateWindow(sHwnd1);
            
	        sHwnd2 = CreateWindow( TEXT("static"),"0",
					WS_CHILD | WS_VISIBLE ,
                    36, 62,
                    278, 35,
					hwnd,(HMENU)33,NULL,NULL);
			if (!sHwnd2) MessageBox(NULL,"创建文本框失败","Message",MB_OK|MB_ICONERROR);
			ShowWindow(sHwnd2,SW_SHOW);
			SetWindowLong(sHwnd2,GWL_STYLE,GetWindowLong(sHwnd2,GWL_STYLE) | ES_RIGHT);
			SendMessage(sHwnd2, WM_SETFONT, (WPARAM)hFont, lParam);
            UpdateWindow(sHwnd2);
            
			for(int i = 0; i < NUM; i++) 
			{
				Buttons[i].w = 50;
				Buttons[i].h = 50;
				Buttons[0].w = 110;	 //0双倍宽 
				Buttons[17].h = 110; //=双倍高 

				bHwnd = CreateWindow( TEXT("button"),
						Buttons[i].szText,
						WS_CHILD | WS_VISIBLE  | BS_PUSHBUTTON,
						Buttons[i].x, Buttons[i].y,
						Buttons[i].w, Buttons[i].h,
						hwnd,
						(HMENU)i,
						((LPCREATESTRUCT) lParam)->hInstance,
						NULL);
				if (!bHwnd) MessageBox(NULL,"创建命令按钮失败","Message",MB_OK|MB_ICONERROR);
				ShowWindow(bHwnd,SW_SHOW);
				SendMessage(bHwnd, WM_SETFONT, (WPARAM)hFont, lParam);  //设置控件字体
            	UpdateWindow(bHwnd);						
			}
						
			break;
		}

		case WM_COMMAND: {
			GetWindowText(sHwnd2, buf, 1024);
			tmp = string(buf);
			if(lWord>=0 && lWord<=10){
				if (lWord==10 && tmp.find(".")!=tmp.npos){
					SetWindowText(sHwnd1, TEXT("已有小数点"));
					Beep(400,100);
					break;
				}
				tmp = (tmp=="0"&&lWord!=10?"":tmp) + (lWord==10?".":i2str(lWord));
				SetWindowText(sHwnd2, tmp.c_str()); 
			}
			else switch (lWord){
				case 21: //C clear
					SetWindowText(sHwnd1, "");
					SetWindowText(sHwnd2, "0");
					break;
				case 22: //BackSpace
					tmp = tmp.substr(0, tmp.size()-1);
					if (tmp.empty()) tmp = "0";
					SetWindowText(sHwnd2, tmp.c_str());
					break;
				case 15: //±
					if (tmp.substr(0, 1) == "-")
						tmp.erase(tmp.begin(),tmp.begin()+1);
					else
						if (tmp!="0") tmp = "-" + tmp;
					SetWindowText(sHwnd2, tmp.c_str());
					break;
				case 16: //%
					tmp = d2str(str2d(tmp) * 0.01);
					SetWindowText(sHwnd2, tmp.c_str());
					break;
				case 18: //1/x
					if (tmp=="0") {
						SetWindowText(sHwnd1, TEXT("除0错"));
						Beep(400,100);
						break;
					}
					tmp = d2str(1/str2d(tmp));
					SetWindowText(sHwnd2, tmp.c_str());
					break;
				case 19: //sqrt(x)
					if (str2d(tmp)<0) {
						SetWindowText(sHwnd1, TEXT("负数不能开平方"));
						Beep(400,100);
						break;
					}
					tmp = d2str(sqrt(str2d(tmp)));
					SetWindowText(sHwnd2, tmp.c_str());
					break;
				case 20: //y^2
					tmp = d2str(pow(str2d(tmp),2.0));
					SetWindowText(sHwnd2, tmp.c_str());
					break;
				default:
					MessageBox(hwnd, i2str(lWord).c_str(), NULL, 0);
			}
			break;
		}

		case WM_CLOSE:
			if (IDYES==MessageBox(hwnd, "是否真的要退出?", "确认", MB_ICONQUESTION | MB_YESNO))
				DestroyWindow(hwnd);  //销毁窗口
			return 0;
		  
		case WM_DESTROY:
			ShellAbout(hwnd, "我的计算器", "我的Windows窗口计算器 by Hann Yang, 2021.2.21", NULL);
			PostQuitMessage(0);
			return 0;
		
		default:
			return DefWindowProc(hwnd, Message, wParam, lParam);
	}
	return 0;
}
 
/* The 'main' function of Win32 GUI programs: this is where execution starts */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	int dtWidth, dtHeight;
	WNDCLASSEX wc; /* A properties struct of our window */
	HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
	RECT rect;
	MSG msg; /* A temporary location for all messages */
 
	/* zero out the struct and set the stuff we want to modify */
	memset(&wc,0,sizeof(wc));
	wc.cbSize		 = sizeof(WNDCLASSEX);
	wc.lpfnWndProc	 = WndProc; /* This is where we will send messages to */
	wc.hInstance	 = hInstance;
	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
	
	/* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.lpszClassName = "WindowCalculator";
	wc.hIcon		 = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */
 
	if(!RegisterClassEx(&wc)) {
		MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
		return 0;
	}
 
 	hwnd = GetDesktopWindow(); //取桌面句柄 
	GetWindowRect(hwnd,&rect); //取桌面范围 
	dtWidth = rect.right-rect.left; //桌面宽度 
	dtHeight = rect.bottom-rect.top; //桌面高度 

	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
		wc.lpszClassName,
		TEXT("我的计算器"),
		WS_VISIBLE|WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX,
		(dtWidth-360)/2,   /*窗体居中*/ 
		(dtHeight-480)/2,
		360, /* width */
		480, /* height */
		NULL,NULL,hInstance,NULL);
 
	if(hwnd == NULL) {
		MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
		return 0;
	}

	while(GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received... */
		TranslateMessage(&msg); /* Translate key codes to chars if present */
		DispatchMessage(&msg); /* Send it to WndProc */
	}
	return msg.wParam;
}

 

上一篇:如何写好轮播图


下一篇:Optimal Size and Spacing for Mobile Buttons