300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 非可视化编程的windows窗口 C++ 代码设计:附例程并多多知识点

非可视化编程的windows窗口 C++ 代码设计:附例程并多多知识点

时间:2021-11-03 01:03:44

相关推荐

非可视化编程的windows窗口 C++ 代码设计:附例程并多多知识点

我用Dev-C++写了一个的非可视化编程条件下的windows窗口计算器例程,在此分享给广大初学者。其运行效果如下图:

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

#include <iostream>#include <iomanip>#include <sstream>#include <string>#include <array>#include <cmath>#include <windows.h>using namespace std;#define myClassName "WindowCalculator"#define NUM (sizeof Buttons / sizeof Buttons[0])#define WarningBeep Beep(400,100)#define OutErrorText(s) SetWindowText(tHwnd[1], TEXT(s))#define OutResultText SetWindowText(tHwnd[2], tmp.c_str())#define ClearText SetWindowText(tHwnd[1],"");SetWindowText(tHwnd[2],"0")#define AboutMe ShellAbout(hwnd, "我的计算器",\"我的Windows窗口计算器 by Hann Yang, .2.21", NULL)struct button {int x;int y; //坐标int w;int h; //宽高const char *szText; //Caption}Buttons[] = {30, 370,0,0,TEXT("0"),30, 310,0,0,TEXT("1"),90, 310,0,0,TEXT("2"),150,310,0,0,TEXT("3"),30, 250,0,0,TEXT("4"),90, 250,0,0,TEXT("5"),150,250,0,0,TEXT("6"),30, 190,0,0,TEXT("7"),90, 190,0,0,TEXT("8"),150,190,0,0,TEXT("9"),150,370,0,0,TEXT(" ."),210,370,0,0,TEXT("+"),210,310,0,0,TEXT("-"),210,250,0,0,TEXT("×"),210,190,0,0,TEXT("÷"),210,130,0,0,TEXT("±"),270,310,0,0,TEXT("="),270,250,0,0,TEXT("1/x"),270,190,0,0,TEXT("√x"),270,130,0,0,TEXT("y2"),150,130,0,0,TEXT("%"),90, 130,0,0,TEXT("C"),30, 130,0,0,TEXT("←")};HFONT hFont[3];HWND tHwnd[3], bHwnd[NUM];string GetStaticText(short i=2){char buf[64] = {0};GetWindowText(tHwnd[i], buf, 64);return string(buf);}void myCreateFont(){hFont[0] = (HFONT)GetStockObject(SYSTEM_FIXED_FONT);/* windows系统基本字体:ANSI_FIXED_FONT DEFAULT_GUI_FONT ANSI_VAR_FONTDEVICE_DEFAULT_FONT SYSTEM_FIXED_FONT SYSTEM_FONT OEM_FIXED_FONT */hFont[1] = CreateFont(-15, -8, /* 字符的逻辑单位高宽值(也被称为em高度)>0:字体映射器转换这个值以设备单位,并和已有字体的单元高度相匹配。=0:字体映射器转换在选择匹配时用一个缺省的高度值。<0:字体映射器转换这个值到设备单位,并将它的绝对值和已有字体的字符高度相匹配。 */ 0, /*指定移位向量和设备X轴之间的一个角度,以十分之一度为单位*/ 0, /*指定每个字符的基线和设备X轴之间的角度*/400, /*字体权值:400表示标准体,700表示黑(粗)体*/FALSE, FALSE, FALSE, /*字体样式参数对应:斜体、下划线、删除线*/DEFAULT_CHARSET, /*默认字符集*/OUT_DEFAULT_PRECIS, /*默认裁剪状态*/CLIP_DEFAULT_PRECIS, /*默认输出精度*/DEFAULT_QUALITY, /*默认输出质量*/DEFAULT_PITCH|FF_DONTCARE, /*默认字体间距|不关心字体族*/TEXT("微软雅黑") ); /*字体名称*/hFont[2] = CreateFont(30, 10, 0, 0, 700, FALSE, FALSE, FALSE, DEFAULT_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE,TEXT("仿宋") );}void myCreateWindow(HWND hwnd, LPARAM lParam){tHwnd[0] = CreateWindow( TEXT("button"),NULL,WS_CHILD | WS_VISIBLE | BS_GROUPBOX, /*分组框*/30, 25, 290, 80,hwnd,(HMENU)31,((LPCREATESTRUCT) lParam)->hInstance,NULL);if (!tHwnd[0]) MessageBox(NULL,"创建分组框失败","Message",MB_OK|MB_ICONERROR);ShowWindow(tHwnd[0], SW_SHOW);UpdateWindow(tHwnd[0]);tHwnd[1] = CreateWindow( TEXT("static"),NULL,WS_CHILD | WS_VISIBLE ,36, 40, 278, 22,hwnd,(HMENU)32,((LPCREATESTRUCT) lParam)->hInstance,NULL);if (!tHwnd[1]) MessageBox(NULL,"创建文本框失败","Message",MB_OK|MB_ICONERROR);ShowWindow(tHwnd[1],SW_SHOW);SendMessage(tHwnd[1], WM_SETFONT, (WPARAM)hFont[1], lParam); //设置控件字体SetWindowLong(tHwnd[1], GWL_STYLE, GetWindowLong(tHwnd[1], GWL_STYLE)|ES_RIGHT|SS_CENTERIMAGE); //设置右对齐、垂直居中 UpdateWindow(tHwnd[1]);tHwnd[2] = CreateWindow( TEXT("static"),"0",WS_CHILD | WS_VISIBLE ,36, 62, 278, 35,hwnd,(HMENU)33,((LPCREATESTRUCT) lParam)->hInstance,NULL);if (!tHwnd[2]) MessageBox(NULL,"创建文本框失败","Message",MB_OK|MB_ICONERROR);ShowWindow(tHwnd[2],SW_SHOW);SetWindowLong(tHwnd[2], GWL_STYLE, GetWindowLong(tHwnd[2], GWL_STYLE) | ES_RIGHT);SendMessage(tHwnd[2], WM_SETFONT, (WPARAM)hFont[2], lParam);UpdateWindow(tHwnd[2]);for(int i = 0; i < NUM; i++) {Buttons[i].w = 50;Buttons[i].h = 50;Buttons[0].w = 110; //0双倍宽 Buttons[16].h = 110; //=双倍高 bHwnd[i] = CreateWindow( TEXT("button"),Buttons[i].szText,WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_FLAT,Buttons[i].x, Buttons[i].y,Buttons[i].w, Buttons[i].h,hwnd,(HMENU)(WPARAM)i, //(WPARAM)强制转换用于消除警告 ((LPCREATESTRUCT) lParam)->hInstance, NULL);if (!bHwnd[i]) MessageBox(NULL,"创建命令按钮失败","Message",MB_OK|MB_ICONERROR);ShowWindow(bHwnd[i],SW_SHOW);SendMessage(bHwnd[i], WM_SETFONT, (WPARAM)hFont[0], lParam); //设置控件字体UpdateWindow(bHwnd[i]);}}template<typename T>string num2str(T d){string s;stringstream ss;ss<<setprecision(15)<<d;s=ss.str();ss.clear();return s;}template<typename T>T str2num(string s){T d;stringstream ss;ss<<s;ss>>setprecision(15)>>d;ss.clear();return d;}LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam){string tmp;array <string,4> strSign={"+","-","*","/"};static bool num_input_state = true;static bool sgn_input_state = false;unsigned int lWord = LOWORD(wParam);switch(Message) {case WM_CREATE: // WM_CREATE事件中创建所有子窗口控件 myCreateFont();myCreateWindow(hwnd, lParam);break;case WM_COMMAND: // WM_COMMAND响应的wParam值对应控件的(HMENU)(WPARAM)i参数tmp = GetStaticText();if(lWord>=0 && lWord<=10){ //0~9、.if (lWord==10 && tmp.find(".")!=tmp.npos){OutErrorText("无效输入:已有小数点");WarningBeep;break;}if (sgn_input_state) tmp="";sgn_input_state = false;tmp = (tmp=="0"&&lWord!=10?"":tmp) + (lWord==10?".":num2str<int>(lWord));if (num_input_state) OutResultText; }else if(lWord>=11 && lWord<=14){ //+、-、*、/ num_input_state = true;sgn_input_state = true;if (GetStaticText(1).back()=='+'){//MessageBox(hwnd, "+++", NULL, 0);}tmp = tmp + strSign.at(lWord-11);OutErrorText(tmp.c_str());}else{num_input_state = false;switch (lWord){case 15: //±OutErrorText(("-("+tmp+")").c_str());if (tmp.substr(0, 1) == "-")tmp.erase(tmp.begin(),tmp.begin()+1);elseif (tmp!="0") tmp = "-" + tmp;OutResultText;break;case 16: // =num_input_state = true;break;case 17: //1/xif (tmp=="0") {OutErrorText("除0错:#DIV/0!");WarningBeep;break;}OutErrorText(("1/"+tmp).c_str());tmp = num2str<long double>(1/str2num<long double>(tmp));OutResultText;break;case 18: //sqrt(x)if (str2num<long double>(tmp)<0) {OutErrorText("无效输入:负数开平方");WarningBeep;break;}OutErrorText(("sqrt("+tmp+")").c_str());tmp = num2str<long double>(sqrt(str2num<long double>(tmp)));OutResultText;break;case 19: //y^2OutErrorText(("pow("+tmp+",2)").c_str());tmp = num2str<long double>(pow(str2num<long double>(tmp),2.0));OutResultText;if (GetStaticText()=="inf"){OutErrorText("无效输入:平方值超出允许范围");WarningBeep;tmp="0";OutResultText;}break;case 20: //%if (tmp.find("e")==tmp.npos)OutErrorText((tmp+"%").c_str());elseOutErrorText(("0.01*("+tmp+")").c_str());tmp = num2str<long double>(str2num<long double>(tmp) * 0.01);OutResultText;break;case 21: //C clearClearText;num_input_state = true;break;case 22: //BackSpacetmp = tmp.substr(0, tmp.size()-1);if (tmp.empty()) tmp = "0";OutResultText;num_input_state = true;break;default:MessageBox(hwnd, num2str<int>(lWord).c_str(), NULL, 0);}}break; //end case WM_COMMANDcase WM_KEYDOWN://返回的wParam为按键的虚拟键码: 110(orNumPAD190)=='.' 48~57(orNumPAD96~105)=='0'~'9'tmp = num2str<int>(LOWORD(wParam)).c_str();OutResultText;break;case WM_SYSCHAR://返回的wParam为按键的虚拟键码: 110(orNumPAD190)=='.' 48~57(orNumPAD96~105)=='0'~'9'tmp = num2str<int>(LOWORD(wParam)).c_str();OutResultText;break;case WM_CLOSE:if (IDYES==MessageBox(hwnd, "是否真的要退出?", "确认", MB_ICONQUESTION | MB_YESNO))DestroyWindow(hwnd); //销毁窗口return 0;case WM_HELP: //响应 F1功能键 AboutMe;break;case WM_DESTROY:AboutMe;PostQuitMessage(0);return 0;default:return DefWindowProc(hwnd, Message, wParam, lParam);}return 0;}ATOM myRegisterClass(HINSTANCE hInstance){WNDCLASSEX wc;memset(&wc, 0, sizeof(wc));wc.cbSize = sizeof(WNDCLASSEX);wc.lpfnWndProc = WndProc;wc.hInstance = hInstance;wc.hCursor = LoadCursor(NULL, IDC_ARROW);wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.lpszMenuName = NULL;//无菜单;MAKEINTRESOURCE(IDC_MYMENU);wc.lpszClassName = myClassName;wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);return RegisterClassEx(&wc);}BOOL myInitInstance(HINSTANCE hInstance, int nCmdShow){HWND hwnd;RECT rect;int dtWidth, dtHeight;hwnd = GetDesktopWindow(); //取桌面句柄 GetWindowRect(hwnd,&rect); //取桌面范围 dtWidth = rect.right-rect.left; //桌面宽度 dtHeight = rect.bottom-rect.top; //桌面高度 hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,myClassName,TEXT("我的计算器"),WS_VISIBLE|WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX,(dtWidth-360)/2, /*窗体居中*/ (dtHeight-480)/2,360, 480,NULL,NULL,hInstance,NULL);if (!hwnd) return false;ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);return true;}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){MSG msg;HWND hwnd;if(!myRegisterClass(hInstance)) {MessageBox(NULL, "Window Registration Failed!","Error!", MB_ICONEXCLAMATION|MB_OK);return 0;}if(!myInitInstance(hInstance, nCmdShow)) {MessageBox(NULL, "Window Creation Failed!","Error!", MB_ICONEXCLAMATION|MB_OK);return 0;}while(GetMessage(&msg, NULL, 0, 0) > 0) { if(!IsDialogMessage(hwnd, &msg)){ TranslateMessage(&msg); DispatchMessage(&msg);}//IsDialogMessage使得TAB和ARROW键可切换控件焦点,前提是控件有设WS_TABSTOP参数}return msg.wParam;}

感兴趣的话可以阅读一下本文的前篇:《C++ 用DEV-C++建一个Windows窗口程序带文本框和命令按钮》。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。