#include <windows.h>
#include <tchar.h>
#include <math.h>
#include <stdio.h>
typedef struct Time
{
int hour;
int min;
int sec;
}TimeStructure;
HINSTANCE hInst; //表示当前程序的实例句柄
int flag = 1; //1/0 代表按钮不同状态
const char* weekstr[] = { "天","一","二","三","四","五","六", };
BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void AdjustTime(TimeStructure* x); //根据second 调整hour、minute
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
if (!InitWindowClass(hInstance, nCmdShow))
{
MessageBox(NULL, L"创建窗口失败!", _T("创建窗口"), NULL);
return 1;
}
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
HBRUSH hBrush;
HPEN hPen;
RECT clientRect;
SYSTEMTIME t; //本地时间
static TCHAR szTextBuf[200]; //static 控件文本(缓冲区)
static HWND hStatic; //文本框 控件句柄
static HWND hBtn; //按钮 控件句柄
static TimeStructure x;
int wmId, wmEvent; //控件ID
double sita = 0; //角度
int xOrg, yOrg, rSec, rMin, rHour, rClock, xBegin, xEnd, yBegin, yEnd;
switch (message)
{
case WM_CREATE://创建窗口时,响应的消息
//设置定时器
SetTimer(hWnd, 9999, 1000, NULL);
//设置按钮
hBtn = CreateWindow(
TEXT("button"),
TEXT("暂停"),
WS_CHILD | WS_VISIBLE | WS_BORDER | BS_PUSHBUTTON,
1100/*X坐标*/, 150 /*Y坐标*/, 150 /*宽度*/, 50/*高度*/,
hWnd, (HMENU)2 /*控件唯一标识符*/, hInst, NULL
);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId) {
case 2: //按下按钮
//通过每次点击按钮,来回改变flag的值(0或1),从而控制开始和暂停
if (flag) {
flag = 0;
KillTimer(hWnd, 9999); //清除定时器
SetWindowText(hBtn, TEXT("开始")); //更改按钮内容
}
else {
flag = 1;
SetTimer(hWnd, 9999, 1000, NULL); //设置定时器
SetWindowText(hBtn, TEXT("暂停")); //更改按钮内容
}
break;
default:
//不处理的消息一定要交给 DefWindowProc 处理。
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
GetLocalTime(&t); //本地时间
x.sec = t.wSecond;
x.min = t.wMinute;
x.hour = t.wHour;
AdjustTime(&x); //调用函数 根据s调整h、m
hStatic = CreateWindow(
L"static", //静态文本框的类名
L"时间", //控件的文本(可更改)
WS_CHILD /*子窗口*/ | WS_VISIBLE /*创建时显示*/ | WS_BORDER /*带边框*/ | SS_CENTER /*水平居中*/ | SS_CENTERIMAGE /*垂直居中*/,
950 /*X坐标*/, 20 /*Y坐标*/, 300 /*宽度*/, 100 /*高度*/,
hWnd, //父窗口句柄
(HMENU)1, //为控件指定一个唯一标识符
hInst, //当前程序实例句柄
NULL
);
//设置 static 控件的文本
wsprintf(szTextBuf, TEXT("%d年%d月%d日 %d:%d:%d 星期%S"), t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond, weekstr[t.wDayOfWeek]);
SetWindowText(hStatic, szTextBuf);
//开始绘图
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &clientRect); // 获取用户区的尺寸
hPen = (HPEN)GetStockObject(BLACK_PEN);//设置画笔为系统预定定义的黑色画笔
hBrush = CreateSolidBrush(RGB(224,255,255));
SelectObject(hDC, hPen);//选择画笔
SelectObject(hDC, hBrush);//选择画刷
xOrg = (clientRect.left + clientRect.right) / 2;
yOrg = (clientRect.top + clientRect.bottom) / 2;//计算屏幕中心的坐标,它也是钟表的中心
rClock = min(xOrg, yOrg) - 50;//钟表的半径
rSec = rClock * 6 / 7;//秒针的半径
rMin = rClock * 5 / 6;//分针的半径
rHour = rClock * 2 / 3;//时针的半径
Ellipse(hDC, xOrg - rClock, yOrg - rClock, xOrg + rClock, yOrg + rClock);//绘制表面圆
for (int i = 0; i < 60; i++)//绘制表面的刻度
{
if (i % 5)// 绘制表面的非整点刻度
{
hPen = CreatePen(PS_SOLID, 2, RGB(102, 205, 170));
SelectObject(hDC, hPen);
xBegin = (int)(xOrg + rClock * sin(2 * 3.1415926 * i / 60));
yBegin = (int)(yOrg + rClock * cos(2 * 3.1415926 * i / 60));
MoveToEx(hDC, xBegin, yBegin, NULL);
xEnd = (int)(xOrg + (rClock - 20) * sin(2 * 3.1415926 * i / 60));
yEnd = (int)(yOrg + (rClock - 20) * cos(2 * 3.1415926 * i / 60));
}
else {//绘制表面的整点刻度
hPen = CreatePen(PS_SOLID, 5, RGB(139, 139, 122));
SelectObject(hDC, hPen);
xBegin = (int)(xOrg + rClock * sin(2 * 3.1415926 * i / 60));
yBegin = (int)(yOrg + rClock * cos(2 * 3.1415926 * i / 60));
MoveToEx(hDC, xBegin, yBegin, NULL);
xEnd = (int)(xOrg + (rClock - 25) * sin(2 * 3.1415926 * i / 60));
yEnd = (int)(yOrg + (rClock - 25) * cos(2 * 3.1415926 * i / 60));
}
LineTo(hDC, xEnd, yEnd);
DeleteObject(hPen);
}
//秒针
hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
SelectObject(hDC, hPen);
sita = 2 * 3.1415926 * x.sec / 60;
//下面求秒针的起点坐标,它的位置在秒针的最末端
xBegin = xOrg + (int)(rSec * sin(sita));
yBegin = yOrg - (int)(rSec * cos(sita));
//下面求秒针的终点坐标,它的位置在秒针的反方向的长度为秒针的/8
xEnd = xOrg + (int)(rClock * sin(sita + 3.1415926) / 8);
yEnd = yOrg - (int)(rClock * cos(sita + 3.1415926) / 8);
MoveToEx(hDC, xBegin, yBegin, NULL);
LineTo(hDC, xEnd, yEnd);//绘制
//分针
hPen = CreatePen(PS_SOLID, 5, RGB(255, 193, 193));
SelectObject(hDC, hPen);
sita = 2 * 3.1415926 * x.min / 60;
xBegin = xOrg + (int)(rMin * sin(sita));
yBegin = yOrg - (int)(rMin * cos(sita));//分针的起点
xEnd = xOrg + (int)(rClock * sin(sita + 3.1415926) / 8);
yEnd = yOrg - (int)(rClock * cos(sita + 3.1415926) / 8);// 分针的终点
MoveToEx(hDC, xBegin, yBegin, NULL);
LineTo(hDC, xEnd, yEnd);//绘制
//时针
hPen = CreatePen(PS_SOLID, 10, RGB(238, 180, 34));
SelectObject(hDC, hPen);
sita = 2 * 3.1415926 * x.hour / 12;
xBegin = xOrg + (int)(rHour * sin(sita));
yBegin = yOrg - (int)(rHour * cos(sita));
xEnd = xOrg + (int)(rClock * sin(sita + 3.1415926) / 8);
yEnd = yOrg - (int)(rClock * cos(sita + 3.1415926) / 8);
MoveToEx(hDC, xBegin, yBegin, NULL);
LineTo(hDC, xEnd, yEnd);//绘制
DeleteObject(hPen);
DeleteObject(hBrush);
//结束绘图
EndPaint(hWnd, &ps);
break;
case WM_TIMER://响应定时器发出的定时消息
if (wParam == 9999)//判断是否是设置的定时器发出的消息
InvalidateRect(hWnd, NULL, 1); //刷新屏幕
break;
case WM_SIZE://窗口尺寸改变时,刷新窗口
InvalidateRect(hWnd, NULL, 1);
break;
case WM_DESTROY:
PostQuitMessage(0); // 调用PostQuitMessage发出WM_ QUIT 消息
KillTimer(hWnd, 9999);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
void AdjustTime(TimeStructure* x)
{
if (x->sec == 60)
{
x->sec = 0;
x->min++;
if (x->min == 60)
{
x->min = 0;
x->hour++;
if (x->hour == 12)
x->hour = 0;
}
}
}
BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow)
{
WNDCLASSEX wcex;
HWND hWnd;
TCHAR szWindowClass[] = L"窗口示例";
TCHAR szTit1e[] = L"模拟时钟";
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = 0;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
if (!RegisterClassEx(&wcex))
return FALSE;
hWnd = CreateWindow(szWindowClass,
szTit1e,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}适当修改代码,使时钟刻度显示数字,优化按钮中的字体并填充颜色