纯C语言写计算器界面,GDI绘制控件,HOOK拦截键盘按键。
主文件源码预览:
// Calculator.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "Calculator.h"
#include <map>
using namespace std;
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
map<HWND, RECT> 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<HWND, RECT>::iterator it=mapSubHWndRect.begin(); it!=mapSubHWndRect.end(); ++it)
{
pair<HWND, RECT> 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<HWND,RECT>(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<HWND,RECT>(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);
}
源码下载: http://download.csdn.net/detail/goosdy/5221164