模拟时钟

    xiaoxiao2021-03-25  176

    以下程序是书上的,只是加了一些自己的注释,方便理解

    # include<windows.h> # include<cmath> # define ID_TIMER 1 # define TWOPI (2*3.14159) LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int iCmdShow ) { TCHAR szAppName[] = TEXT("Clock"); WNDCLASS wndclass; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);//这里用NULL表示使用微软提供的图标 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //同上 wndclass.hInstance = hInstance; wndclass.lpfnWndProc = WndProc; wndclass.lpszClassName = szAppName; wndclass.lpszMenuName = NULL; wndclass.style = CS_HREDRAW | CS_VREDRAW; if (!RegisterClass(&wndclass))//注册窗口类 { MessageBox(NULL, "Program requires windows NT!", szAppName, MB_ICONERROR); return 0; } HWND hwnd; hwnd = CreateWindow(szAppName, TEXT("Analog/*模拟*/ Clock"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL,NULL, hInstance, NULL); ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } //设置笛卡尔坐标系,原点在客户区中央 void SetIsotropic(HDC hdc, int cxClient, int cyClient) { SetMapMode(hdc, MM_ISOTROPIC); SetWindowExtEx(hdc, 1000, 1000, NULL); SetViewportExtEx(hdc, cxClient / 2, -cyClient / 2, NULL); SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL); } //点(x,y)顺时针旋转a角度后,新坐标为(x*cosa+y*sina,y*cona-x*sina) //可用极坐标求 //将Num个点都顺时针旋转iAngle角度 void RotatePoint(POINT pt[], int iNum, int iAngle)//rotate旋转,循环 { int i; POINT ptTemp; for (i = 0; i < iNum; i++) { ptTemp.x = (int)(pt[i].x*cos(TWOPI*iAngle / 360) + pt[i].y*sin(TWOPI*iAngle / 360)); ptTemp.y = (int)(pt[i].y*cos(TWOPI*iAngle / 360) - pt[i].x*sin(TWOPI*iAngle / 360)); pt[i] = ptTemp; } } //画时钟的60个圆,其中整点的圆直径大些 void DrawClock(HDC hdc) { int iAngle; POINT pt[3]; for (iAngle = 0; iAngle < 360; iAngle += 6)//360/6=12*5 //每次角度+6,这样就将所有的圆都画出来了 { pt[0].x = 0; pt[0].y = 900; //12:00的坐标 RotatePoint(pt, 1, iAngle);// pt[2].x = pt[2].y = iAngle % 5 ? 33 : 100;//保存圆的直径 pt[0].x -= pt[2].x / 2;//中心坐标减去半径(左) pt[0].y -= pt[2].y / 2;//上 pt[1].x = pt[0].x + pt[2].x;//右 pt[1].y = pt[0].y + pt[2].y;//下 SelectObject(hdc, GetStockObject(BLACK_BRUSH)); Ellipse(hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y); } } void DrawHands(HDC hdc, SYSTEMTIME *pst, BOOL fChange) { static POINT pt[3][5] = { 0, -150, 100, 0, 0, 600, -100, 0, 0, -150,//时针 0, -200, 50, 0, 0, 800, -50, 0, 0, -200,//分针 0, 0, 0, 0, 0, 0, 0, 0, 0, 800//秒针 }; //此时三个指针的坐标都是12::00时的 int i, iAngle[3]; POINT ptTemp[3][5]; iAngle[0] = (pst->wHour * 30) % 360 + pst->wMinute / 2;//每经过一小时,时针转动 (时数*6*5),但是并非只是每经过 //一小时时针才转动,当分针转动时(经过12分钟),时针转动2度(即每经过2分钟,时针转动1度),所以还要加上当前的分时/2 iAngle[1] = pst->wMinute * 6;//每经过一分钟,分针转动 (分数*6) 度 iAngle[2] = pst->wSecond * 6;//每经过一秒,秒针转动 (秒数*6) 度 memcpy(ptTemp,pt, sizeof(pt)); //时针只有当时或分改变才旋转所有的,否则只用旋转秒针 for (i = fChange ? 0 : 2; i < 3; i++) { RotatePoint(ptTemp[i], 5, iAngle[i]); Polyline(hdc, ptTemp[i], 5); } } LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { static int cxClient, cyClient; static SYSTEMTIME stPrevious; BOOL fChange; HDC hdc; PAINTSTRUCT ps; SYSTEMTIME st; switch (uMsg) { case WM_CREATE: SetTimer(hwnd, ID_TIMER, 1000,NULL);//每1000毫秒即1秒 GetLocalTime(&st); stPrevious = st;//保存前一秒的时间 return 0; case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); return 0; case WM_TIMER: GetLocalTime(&st); fChange = st.wHour != stPrevious.wHour || st.wMinute != stPrevious.wMinute; hdc = GetDC(hwnd); SetIsotropic(hdc, cxClient, cyClient); SelectObject(hdc, GetStockObject(WHITE_PEN)); DrawHands(hdc, &stPrevious, fChange);//前一秒的指针用白刷画,就像是指针"动"了一样 SelectObject(hdc, GetStockObject(BLACK_PEN)); DrawHands(hdc, &st, TRUE); ReleaseDC(hwnd, hdc); stPrevious = st; return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); SetIsotropic(hdc, cxClient, cyClient); DrawClock(hdc); DrawHands(hdc, &stPrevious, TRUE); EndPaint(hwnd, &ps); return 0; case WM_CLOSE: KillTimer(hwnd, ID_TIMER); PostQuitMessage(0); //DestroyWindow(hwnd); return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam); }

    转载请注明原文地址: https://ju.6miu.com/read-2795.html

    最新回复(0)