编写一个基于Win32 API 的时钟程序,显示当前系统日期时间
时间: 2023-06-12 15:03:29 浏览: 141
以下是一个基于Win32 API的时钟程序,可以显示当前系统日期时间:
```c++
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Clock");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName, TEXT("Clock"),
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static BOOL f24Hour;
static HBITMAP hBitmap;
static int cxClient, cyClient;
static int cxBitmap, cyBitmap;
static int xC, yC, cxC, cyC;
static int iRadius, iMarker;
HDC hdc, hdcMem;
PAINTSTRUCT ps;
POINT apt[3];
SYSTEMTIME st;
TCHAR szBuffer[256];
int i, cx, cy, iSec, iMin, iHour, iAngle;
double fAngle;
switch (message)
{
case WM_CREATE:
hdc = GetDC(hwnd);
hBitmap = LoadBitmap(GetModuleHandle(NULL), TEXT("Clock"));
hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem, hBitmap);
GetObject(hBitmap, sizeof(BITMAP), &bm);
cxBitmap = bm.bmWidth;
cyBitmap = bm.bmHeight;
ReleaseDC(hwnd, hdc);
DeleteDC(hdcMem);
SetTimer(hwnd, 1, 1000, NULL);
f24Hour = TRUE;
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
iRadius = min(cxClient, cyClient) / 2.5;
iMarker = iRadius / 5;
xC = cxClient / 2;
yC = cyClient / 2;
cxC = 7 * iMarker / 4;
cyC = iMarker / 2;
return 0;
case WM_TIMER:
InvalidateRect(hwnd, NULL, TRUE);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem, hBitmap);
BitBlt(hdc, xC - cxBitmap / 2, yC - cyBitmap / 2,
cxBitmap, cyBitmap, hdcMem, 0, 0, SRCCOPY);
// Get the current system time.
GetLocalTime(&st);
// Convert the time into hour, minute, and second.
iSec = st.wSecond;
iMin = st.wMinute;
if (f24Hour)
iHour = st.wHour;
else
iHour = st.wHour % 12;
if (iHour == 0)
iHour = 12;
// Draw the hour hand.
iAngle = (iHour * 30) % 360 + iMin / 2;
fAngle = iAngle * 3.14159265358979323846 / 180.0;
apt[0].x = xC;
apt[0].y = yC;
apt[1].x = xC + (int) (0.6 * iRadius * sin(fAngle));
apt[1].y = yC - (int) (0.6 * iRadius * cos(fAngle));
apt[2].x = xC - (int) (0.1 * iRadius * sin(fAngle));
apt[2].y = yC + (int) (0.1 * iRadius * cos(fAngle));
Polygon(hdc, apt, 3);
// Draw the minute hand.
iAngle = iMin * 6;
fAngle = iAngle * 3.14159265358979323846 / 180.0;
apt[0].x = xC;
apt[0].y = yC;
apt[1].x = xC + (int) (0.8 * iRadius * sin(fAngle));
apt[1].y = yC - (int) (0.8 * iRadius * cos(fAngle));
apt[2].x = xC - (int) (0.1 * iRadius * sin(fAngle));
apt[2].y = yC + (int) (0.1 * iRadius * cos(fAngle));
Polygon(hdc, apt, 3);
// Draw the second hand.
iAngle = iSec * 6;
fAngle = iAngle * 3.14159265358979323846 / 180.0;
MoveToEx(hdc, xC, yC, NULL);
LineTo(hdc, xC + (int) (0.8 * iRadius * sin(fAngle)),
yC - (int) (0.8 * iRadius * cos(fAngle)));
// Draw the tick marks.
for (i = 0; i < 60; i++)
{
if (i % 5 == 0)
{
MoveToEx(hdc,
xC + (int) ((iRadius - iMarker) * sin(i * 6 * 3.14159265358979323846 / 180.0)),
yC - (int) ((iRadius - iMarker) * cos(i * 6 * 3.14159265358979323846 / 180.0)),
NULL);
LineTo(hdc,
xC + (int) (iRadius * sin(i * 6 * 3.14159265358979323846 / 180.0)),
yC - (int) (iRadius * cos(i * 6 * 3.14159265358979323846 / 180.0)));
}
else
{
MoveToEx(hdc,
xC + (int) ((iRadius - iMarker / 2) * sin(i * 6 * 3.14159265358979323846 / 180.0)),
yC - (int) ((iRadius - iMarker / 2) * cos(i * 6 * 3.14159265358979323846 / 180.0)),
NULL);
LineTo(hdc,
xC + (int) (iRadius * sin(i * 6 * 3.14159265358979323846 / 180.0)),
yC - (int) (iRadius * cos(i * 6 * 3.14159265358979323846 / 180.0)));
}
}
// Draw the center ellipse.
Ellipse(hdc, xC - cxC, yC - cyC, xC + cxC, yC + cyC);
// Draw the date and time.
wsprintf(szBuffer, TEXT("%02d:%02d:%02d %s"), f24Hour ? iHour : iHour % 12, iMin, iSec, f24Hour ? TEXT("") : (iHour < 12 ? TEXT("AM") : TEXT("PM")));
cx = GetSystemMetrics(SM_CXSCREEN);
cy = GetSystemMetrics(SM_CYSCREEN);
SetTextColor(hdc, RGB(255, 0, 0));
SetBkMode(hdc, TRANSPARENT);
TextOut(hdc, cx - 5 * cxBitmap / 4, cy - cyBitmap, szBuffer, lstrlen(szBuffer));
// Clean up.
DeleteDC(hdcMem);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
KillTimer(hwnd, 1);
DeleteObject(hBitmap);
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
switch (wParam)
{
case 'F':
case 'f':
f24Hour = !f24Hour;
InvalidateRect(hwnd, NULL, TRUE);
return 0;
case VK_ESCAPE:
DestroyWindow(hwnd);
return 0;
}
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
```
程序中使用了双缓冲技术,可以避免闪烁问题。同时,程序还支持按下“F”键可以在12小时制和24小时制之间切换。
阅读全文