WIN32下的模拟时钟

Posted greenleaf1976

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WIN32下的模拟时钟相关的知识,希望对你有一定的参考价值。

 


#include <Windows.h> #include <math.h> #include <tchar.h> #include "resource.h" #define PI 3.1415926 BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpcmdLine, int nCmdShow) { MSG msg; if (!InitWindowClass(hInstance,nCmdShow)) { MessageBox(NULL, L"Failed to Create Windows", L"InFo", NULL); return 1; } while (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow) { WNDCLASSEX wcex; HWND hWnd; TCHAR szWindowsClass[] = L"窗口示例"; TCHAR szTitle[] = L"模拟时钟"; wcex.cbClsExtra = 0; wcex.cbSize = sizeof(WNDCLASSEX); wcex.cbWndExtra = 0; wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wcex.hInstance = hInstance; wcex.hIconSm = LoadCursor(wcex.hInstance, MAKEINTRESOURCE(IDI_ICON1)); wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.lpfnWndProc = WndProc; wcex.lpszClassName = szWindowsClass; wcex.lpszMenuName = NULL; wcex.style = CS_HREDRAW | CS_VREDRAW; //注册窗口类 if (!RegisterClassEx(&wcex)) { return FALSE; } //hWnd = CreateWindowEx(0,szWindowsClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); hWnd = CreateWindowEx(0,szWindowsClass, szTitle, WS_OVERLAPPEDWINDOW, 200, 200, 600, 400, NULL, NULL, hInstance, NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hDc; PAINTSTRUCT ps; HBRUSH hBrush; HPEN hPen; RECT clientRect; SYSTEMTIME x; float sita = 0; double rSec, rMin, rHour,temHour,temMin, xOrg, yOrg, rClock, ptLong, xBegin, xEnd, yBegin, yEnd; //消息分发 switch (message) { case WM_CREATE: SetTimer(hWnd, 9999, 1000, NULL); break; case WM_PAINT: hDc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &clientRect);//获取窗口大小 hPen = (HPEN)GetStockObject(BLACK_PEN); hBrush = CreateSolidBrush(RGB(255, 220, 220)); SelectObject(hDc, hPen); SelectObject(hDc, hBrush); //时钟表盘圆点坐标 xOrg = (clientRect.left + clientRect.right) / 2; yOrg = (clientRect.bottom + clientRect.top) / 2; //表盘,秒,分,时针半径 rClock = min(xOrg, yOrg) * 4 / 5; rSec = rClock * 6 / 7; rMin = rClock * 5 / 6; rHour = rClock * 2 / 3; //画圆盘 Ellipse(hDc, int(xOrg - rClock), int(yOrg - rClock), int(xOrg + rClock), int(yOrg + rClock)); //画刻度 for (int i = 0; i < 60; i++) { if (i % 5) { hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0)); ptLong = rClock * 9 / 10; } else { hPen = CreatePen(PS_SOLID, 5, RGB(255, 0, 0)); ptLong = rClock * 7 / 8; } SelectObject(hDc, hPen); //刻度起止点 xBegin = xOrg + rClock * sin(2 * PI*i / 60); yBegin = yOrg + rClock * cos(2 * PI*i / 60); xEnd = xOrg + ptLong * sin(2 * PI*i / 60); yEnd = yOrg + ptLong * cos(2 * PI*i / 60); MoveToEx(hDc, (int)xBegin,(int)yBegin, NULL); LineTo(hDc, (int)xEnd, (int)yEnd); DeleteObject(hPen); } GetLocalTime(&x); //画秒针 hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0)); SelectObject(hDc, hPen); sita = float(2 * PI*x.wSecond / 60); //秒针起止点 xBegin = xOrg + (int)(rSec*sin(sita)); yBegin = yOrg - (int)(rSec*cos(sita)); xEnd = xOrg + (int)(rClock*sin(sita + PI) / 8); yEnd = yOrg - (int)(rClock*cos(sita + PI) / 8); MoveToEx(hDc, (int)xBegin, (int)yBegin, NULL); LineTo(hDc, (int)xEnd, (int)yEnd); //画分针 hPen = CreatePen(PS_SOLID, 5, RGB(0, 0, 0)); SelectObject(hDc, hPen); sita = float(2 * PI*x.wMinute / 60); //分针起止点 xBegin = xOrg + (int)(rMin*sin(sita)); yBegin = yOrg - (int)(rMin*cos(sita)); xEnd = xOrg + (int)(rClock*sin(sita + PI) / 8); yEnd = yOrg - (int)(rClock*cos(sita + PI) / 8); MoveToEx(hDc, (int)xBegin, (int)yBegin, NULL); LineTo(hDc, (int)xEnd, (int)yEnd); //画时针 hPen = CreatePen(PS_SOLID, 10, RGB(0, 0, 0)); SelectObject(hDc, hPen); /*if (x.wMinute >= 12 && x.wMinute<=24) sita = 2 * PI*(x.wHour +(12/60)) / 12; else if(x.wMinute>24 && x.wMinute<=36) { sita = 2 * PI*(x.wHour + (24/60)) / 12; } else if(x.wMinute>36 && x.wMinute<=48) { sita = 2 * PI*(x.wHour + (48/60)) / 12; } else if (x.wMinute > 48 && x.wMinute<=59) { sita = 2 * PI*(x.wHour + (double)(x.wMinute/60)) / 12; } else { sita = 2 * PI*x.wHour / 12; }*/
temMin =(double)(x.wMinute) / 60;//把分转换成小时的十进制,也就是30分钟->0.5小时 temHour = x.wHour + temMin; //把时针换面十进制时间,1:30->1.5小时


//这么设定时针的时间3:30就不是3了,改成3.5了,这么一来时针在表盘上就会在两个小时的刻度的中间
//而不是只指到3的刻度一个小时不变<_>;

sita = float(2 * PI*temHour / 12); //时针起止点 xBegin = xOrg + (double)(rHour*sin(sita)); yBegin = yOrg - (double)(rHour*cos(sita)); xEnd = xOrg + (double)(rClock*sin(sita + PI) / 8); yEnd = yOrg - (double)(rClock*cos(sita + PI) / 8); MoveToEx(hDc, (int)xBegin, (int)yBegin, NULL); LineTo(hDc, (int)xEnd, (int)yEnd); DeleteObject(hPen); DeleteObject(hBrush); EndPaint(hWnd, &ps); break; case WM_TIMER: if (wParam == 9999) InvalidateRect(hWnd, NULL, true); break; case WM_SIZE: InvalidateRect(hWnd, NULL, TRUE); break; case WM_DESTROY: PostQuitMessage(0); break; default: return ::DefWindowProc(hWnd, message, wParam, lParam); } return 0; }

  

在网上抄的,对于刚学的小白来说,只有抄,不过网上这个时针一个小时才跳一下,不好看,我自己改进了下.

主要是画时针时把时间(3:30)换成十进制的3.5表示就OK了,说起来很简单,我也弄了好几个小时.

以上是关于WIN32下的模拟时钟的主要内容,如果未能解决你的问题,请参考以下文章

模拟人生3 Shaders_Win32.precomp

如何自定义模拟时钟[关闭]

stm32 dac 配置过程

请用Python如何模拟键盘操作

基于Lua框架下的合宙ESP32C3+1.5‘’Eink墨水屏天气时钟+OLED开源项目分享

MiniFly Firmware V1.1开源四轴代码分析七:系统时钟