纯C语言写计算器界面,GDI绘制控件,HOOK拦截键盘按键。
主文件源码预览:
// Calculator.cpp : 定义应用程序的入口点。 // #include "stdafx.h" #include "Calculator.h" #include using namespace std; #define MAX_LOADSTRING 100 // 全局变量: HINSTANCE hInst; // 当前实例 TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本 TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名 map mapSubHWndRect; //子窗口区域集合 SIZE szPreWnd; //窗口之前的大小 HWND hWndText = NULL; HHOOK hKeyHook = NULL; // 此代码模块中包含的函数的前向声明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); HWND CreateStaticForMainWnd(HWND hWnd, LPCTSTR strText, LONG lStyle, int x, int y, int iWidth, int iHeight); void CreateButtonForMainWnd(HWND hWnd, int iID, LPCTSTR strText, int x, int y, int iWidth, int iHeight); LRESULT CALLBACK HookKeyProc(int iCode, WPARAM wParam, LPARAM lParam); void OnShowNum(int iNum); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此放置代码。 MSG msg; HACCEL hAccelTable; // 初始化全局字符串 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_CALCULATOR, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // 执行应用程序初始化: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CALCULATOR)); // 主消息循环: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // 函数: MyRegisterClass() // // 目的: 注册窗口类。 // // 注释: // // 仅当希望 // 此代码与添加到 Windows 95 中的“RegisterClassEx” // 函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要, // 这样应用程序就可以获得关联的 // “格式正确的”小图标。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON3)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_CALCULATOR); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_ICON2)); return RegisterClassEx(&wcex); } // // 函数: InitInstance(HINSTANCE, int) // // 目的: 保存实例句柄并创建主窗口 // // 注释: // // 在此函数中,我们在全局变量中保存实例句柄并 // 创建和显示主程序窗口。 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // 将实例句柄存储在全局变量中 // hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX, // CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX |WS_CLIPCHILDREN, 500, 200, 228, 322, NULL, NULL,hInstance, NULL); if (!hWnd) { return FALSE; } SetWindowText(hWnd,L"计算器"); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // 函数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: 处理主窗口的消息。 // // WM_COMMAND - 处理应用程序菜单 // WM_PAINT - 绘制主窗口 // WM_DESTROY - 发送退出消息并返回 // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_CREATE: { RECT rect = {0}; GetClientRect(hWnd, &rect); szPreWnd.cx = rect.right - rect.left; szPreWnd.cy = rect.bottom - rect.top; CreateStaticForMainWnd(hWnd, _T(""), WS_CHILD|WS_VISIBLE, 10, 15, 195, 50); hWndText = CreateStaticForMainWnd(hWnd, _T("0"), WS_CHILD|WS_VISIBLE|SS_RIGHT, 12, 35, 191, 20); CreateStaticForMainWnd(hWnd, _T(""), WS_CHILD|WS_VISIBLE|SS_GRAYFRAME, 10, 15, 195, 50); CreateButtonForMainWnd(hWnd, ID_BTN_MC, _T("MC"), 10, 75, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_MR, _T("MR"), 50, 75, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_MS, _T("MS"), 90, 75, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_M_ADD, _T("M+"), 130, 75, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_M_SUBTRACT, _T("M-"), 170, 75, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_DELETE, _T("Del"), 10, 105, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_CE, _T("CE"), 50, 105, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_C, _T("C"), 90, 105, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_AS, _T("+-"), 130, 105, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_TICE, _T("V"), 170, 105, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_NUM7, _T("7"), 10, 135, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_NUM8, _T("8"), 50, 135, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_NUM9, _T("9"), 90, 135, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_DIVIDE, _T("/"), 130, 135, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_PERCENT, _T("%"), 170, 135, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_NUM4, _T("4"), 10, 165, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_NUM5, _T("5"), 50, 165, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_NUM6, _T("6"), 90, 165, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_MULTIPLY, _T("*"), 130, 165, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_RECIPROCAL, _T("1/x"), 170, 165, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_NUM1, _T("1"), 10, 195, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_NUM2, _T("2"), 50, 195, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_NUM3, _T("3"), 90, 195, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_SUBTRACT, _T("-"), 130, 195, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_EQUAL, _T("="), 170, 195, 35, 55); CreateButtonForMainWnd(hWnd, ID_BTN_NUM0, _T("0"), 10, 225, 75, 25); CreateButtonForMainWnd(hWnd, ID_BTN_POINT, _T("."), 90, 225, 35, 25); CreateButtonForMainWnd(hWnd, ID_BTN_ADD, _T("+"), 130, 225, 35, 25); hKeyHook = SetWindowsHookEx(WH_KEYBOARD, HookKeyProc, NULL, GetCurrentThreadId()); break; } case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); if (wmId == ID_BTN_MC) { SetWindowText(hWndText, _T("MC")); } else if (wmId == ID_BTN_MR) { SetWindowText(hWndText, _T("MR")); } else if (wmId == ID_BTN_MS) { SetWindowText(hWndText, _T("MS")); } else if (wmId == ID_BTN_M_ADD) { SetWindowText(hWndText, _T("M+")); } else if (wmId == ID_BTN_M_SUBTRACT) { SetWindowText(hWndText, _T("M-")); } else if (wmId == ID_BTN_DELETE) { SetWindowText(hWndText, _T("DEL")); } else if (wmId == ID_BTN_CE) { SetWindowText(hWndText, _T("CE")); } else if (wmId == ID_BTN_C) { SetWindowText(hWndText, _T("C")); } else if (wmId == ID_BTN_AS) { SetWindowText(hWndText, _T("+-")); } else if (wmId == ID_BTN_TICE) { SetWindowText(hWndText, _T("V")); } else if (wmId == ID_BTN_DIVIDE) { SetWindowText(hWndText, _T("/")); } else if (wmId == ID_BTN_PERCENT) { SetWindowText(hWndText, _T("%")); } else if (wmId == ID_BTN_MULTIPLY) { SetWindowText(hWndText, _T("*")); } else if (wmId == ID_BTN_RECIPROCAL) { SetWindowText(hWndText, _T("1/x")); } else if (wmId == ID_BTN_SUBTRACT) { SetWindowText(hWndText, _T("-")); } else if (wmId == ID_BTN_EQUAL) { SetWindowText(hWndText, _T("=")); } else if (wmId == ID_BTN_POINT) { SetWindowText(hWndText, _T(".")); } else if (wmId == ID_BTN_ADD) { SetWindowText(hWndText, _T("+")); } else if (wmId>=ID_BTN_NUM0 && wmId<=ID_BTN_NUM9) { OnShowNum(wmId-ID_BTN_NUM0+48); } // 分析菜单选择: switch (wmId) { case IDM_ABOUT: //DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); ::ShellAbout(hWnd,L"计算器",L"雁子TEST-123456",NULL); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: 在此添加任意绘图代码... EndPaint(hWnd, &ps); break; case WM_DESTROY: UnhookWindowsHookEx(hKeyHook); PostQuitMessage(0); break; case WM_SIZE: { WORD x = LOWORD(lParam); WORD y = HIWORD(lParam); double dx = (double)x/szPreWnd.cx; double dy = (double)y/szPreWnd.cy; for (map::iterator it=mapSubHWndRect.begin(); it!=mapSubHWndRect.end(); ++it) { pair pi = *it; MoveWindow(pi.first, pi.second.left*dx, pi.second.top*dy, (pi.second.right-pi.second.left)*dx, (pi.second.bottom-pi.second.top)*dy, TRUE); } } break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // “关于”框的消息处理程序。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; } HWND CreateStaticForMainWnd(HWND hWnd, LPCTSTR strText, LONG lStyle, int x, int y, int iWidth, int iHeight) { HWND hWndResult = CreateWindow(_T("STATIC"), strText, lStyle, x, y, iWidth, iHeight, hWnd, NULL, hInst, NULL); RECT rect = {x,y,x+iWidth,y+iHeight}; mapSubHWndRect.insert(pair(hWndResult,rect)); return hWndResult; } void CreateButtonForMainWnd(HWND hWnd, int iID, LPCTSTR strText, int x, int y, int iWidth, int iHeight) { HWND hWndTemp= CreateWindow(_T("BUTTON"), strText, WS_CHILD|WS_VISIBLE,x, y, iWidth, iHeight, hWnd, (HMENU)iID, hInst, NULL); RECT rect = {x,y,x+iWidth,y+iHeight}; mapSubHWndRect.insert(pair(hWndTemp,rect)); } LRESULT CALLBACK HookKeyProc(int iCode, WPARAM wParam, LPARAM lParam) { if (iCode == HC_ACTION) { UINT nFlags = HIWORD(lParam); BOOL bKeyDown = 0 == (nFlags & KF_UP); if (bKeyDown) { //数字键的0-9 if (wParam>=VK_NUMPAD0 && wParam<=VK_NUMPAD9) { //转换成主键盘的0-9 wParam -= 0x30; } //主键盘的0-9 if (wParam>=0x30 && wParam<=0x39) { OnShowNum(wParam); } } } return CallNextHookEx(hKeyHook, iCode, wParam, lParam); } void OnShowNum(int iNum) { TCHAR tc[2] = {0}; tc[0] = (TCHAR)iNum; TCHAR tcCur[100] = {0}; GetWindowText(hWndText, tcCur, 100); LPCTSTR str = lstrcat(tcCur, tc); if (lstrlen(str) > 50) { str = _T(""); } SetWindowText(hWndText, str); }