博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Windows下编程--模拟时钟的实现
阅读量:6567 次
发布时间:2019-06-24

本文共 14528 字,大约阅读时间需要 48 分钟。

windows下编程--模拟时钟的实现:

主要可以分为几个步骤:

(1)   编写按键事件处理(启动和停止时钟)

(2)   编写时钟事件处理,调用显示时钟函数

(3)   编写显示时钟函数,要调用显示数字时钟函数、画出钟面函数和画出指针函数

(4)   编写显示数字时钟函数。注意要自己用矩形填充(FillRect)擦除背景。

(5)   编写画出钟面函数

(6)   编写画出指针函数

(7)   增加WM_PAINT消息处理:调用显示时钟函数,防止在停止时钟后从窗口最小化恢复会不显示内容。

 

最后结果类似于这种形式---一个模拟时钟,数字时钟+画面时钟

 

每一步的说明:

(1)编写按键事件处理(启动和停止时钟)

(2)   编写时钟事件处理,调用显示时钟函数

(3)   编写显示时钟函数,要调用显示数字时钟函数、画出钟面函数和画出指针函数

(4)   编写显示数字时钟函数。注意要自己用矩形填充(FillRect)擦除背景。

(5) 编写画出钟面函数

(6)   编写画出指针函数(注意好时针分针秒针的角度关系计算方法就行了)

(7)   增加WM_PAINT消息处理:调用显示时钟函数,防止在停止时钟后从窗口最小化恢复会不显示内容。

 

 

基本上只是考察了基本的windows编程,掌握好时钟事件和按钮的编程。

最后附上长长的代码...

 

1 /*------------------------------------------------------------  2    HELLOWIN.C -- Displays "Hello, Windows 98!" in client area  3                  (c) Charles Petzold, 1998  4   ------------------------------------------------------------*/  5   6 #include 
7 #include
8 #include
9 10 #define PI 3.14159265358979323846 11 #define TIMER_SEC 1 12 #define TIMER_MIN 2 13 #define BUTTON1 3 14 #define BUTTON2 4 15 16 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 17 18 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 19 PSTR szCmdLine, int iCmdShow) 20 { 21 static TCHAR szAppName[] = TEXT ("HelloWin") ; 22 HWND hwnd,hwndButton1,hwndButton2; 23 MSG msg ; 24 WNDCLASS wndclass ; 25 26 wndclass.style = CS_HREDRAW | CS_VREDRAW ; 27 wndclass.lpfnWndProc = WndProc ; 28 wndclass.cbClsExtra = 0 ; 29 wndclass.cbWndExtra = 0 ; 30 wndclass.hInstance = hInstance ; 31 wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; 32 wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; 33 wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 34 wndclass.lpszMenuName = NULL ; 35 wndclass.lpszClassName = szAppName ; 36 37 if (!RegisterClass (&wndclass)) 38 { 39 MessageBox (NULL, TEXT ("This program requires Windows NT!"), 40 szAppName, MB_ICONERROR) ; 41 return 0 ; 42 } 43 44 hwnd = CreateWindow (szAppName, // window class name 45 TEXT ("Analog Clock"), // window caption 46 WS_OVERLAPPEDWINDOW, // window style 47 CW_USEDEFAULT, // initial x position 48 CW_USEDEFAULT, // initial y position 49 560, // initial x size 50 360, // initial y size 51 NULL, // parent window handle 52 NULL, // window menu handle 53 hInstance, // program instance handle 54 NULL) ; // creation parameters 55 56 ShowWindow (hwnd, iCmdShow) ; 57 UpdateWindow (hwnd) ; 58 59 hwndButton1 = CreateWindow(TEXT("button"), // 窗口类名(系统内部定义了该窗口类) 60 TEXT("StartTimer"), // 标题 61 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, // 样式 62 100, 250, // 左上角位置x,y 63 120, 40, // 宽度,高度 64 hwnd, // 父窗口句柄 65 (HMENU)BUTTON1, // 控件ID 66 hInstance, // 实例句柄 67 NULL); // 自定义参数 68 69 hwndButton2 = CreateWindow(TEXT("button"), // 窗口类名 70 TEXT("StopTimer"), // 标题 71 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, // 样式 72 300, 250, // 左上角位置x,y 73 120, 40, // 宽度,高度 74 hwnd, // 父窗口句柄 75 (HMENU)BUTTON2, // 控件ID 76 hInstance, // 实例句柄 77 NULL); 78 79 while (GetMessage (&msg, NULL, 0, 0)) 80 { 81 TranslateMessage (&msg) ; 82 DispatchMessage (&msg) ; 83 } 84 return msg.wParam ; 85 } 86 87 // 画出钟面(不包括指针) 88 void DrawClockFace(HDC hdc){ 89 // PAINTSTRUCT ps; 90 RECT rect; 91 HPEN hPen; 92 HPEN oldPen; 93 hPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255)); // 创建画笔(线形,线宽,颜色) 94 oldPen = (HPEN)SelectObject(hdc, hPen); // 选择画笔,并保留原画笔 95 Ellipse(hdc, 180, 20, 340, 180); // 时钟--半径 80 作出时钟原始图像 96 Rectangle(hdc, 220, 205, 295, 230); 97 double xStart1, yStart1, xEnd1, yEnd1; 98 for (int i = 0; i <= 11; i++){ 99 if (i <= 3){100 xEnd1 = 260 + 80 * sin(i* PI / 6);101 xStart1 = 260 + (80 - 10) * sin(i* PI / 6);102 yEnd1 = 100 - 80 * cos(i* PI / 6);103 yStart1 = 100 - (80 - 10) * cos(i* PI / 6);104 }105 if (i > 3 && i <= 6){106 xEnd1 = 260 + 80 * sin(i* PI / 6);107 xStart1 = 260 + (80 - 10) * sin(i* PI / 6);108 yStart1 = 100 + (80 - 10) * cos(PI - i* PI / 6);109 yEnd1 = 100 + 80 * cos(PI - i* PI / 6);110 }111 if (i > 6 && i <= 9)112 {113 xEnd1 = 260 - 80 * cos(1.5*PI - i* PI / 6);114 xStart1 = 260 - (80 - 10) * cos(1.5*PI - i* PI / 6);115 yStart1 = 100 + (80 - 10) * sin(1.5*PI - i* PI / 6);116 yEnd1 = 100 + 80 * sin(1.5*PI - i* PI / 6);117 }118 if (i > 9){119 xEnd1 = 260 - 80 * sin(2 * PI - i* PI / 6);120 xStart1 = 260 - (80 - 10) * sin(2 * PI - i* PI / 6);121 yEnd1 = 100 - 80 * cos(2 * PI - i* PI / 6);122 yStart1 = 100 - (80 - 10) * cos(2 * PI - i* PI / 6);123 }124 MoveToEx(hdc, xStart1, yStart1, NULL);125 LineTo(hdc, xEnd1, yEnd1);126 }127 DeleteObject(hPen);128 // 钟面相应数字 --- 12129 rect.left = 250;130 rect.top = 5;131 rect.right = 270;132 rect.bottom = 18;133 DrawText(hdc, TEXT("12"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);134 // 钟面相应数字 --- 11135 rect.left = 210;136 rect.top = 15;137 rect.right = 220;138 rect.bottom = 30;139 DrawText(hdc, TEXT("11"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);140 // 钟面相应数字 --- 10141 rect.left = 175;142 rect.top = 50;143 rect.right = 190;144 rect.bottom = 60;145 DrawText(hdc, TEXT("10"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);146 // 钟面相应数字 --- 9147 rect.left = 165;148 rect.top = 95;149 rect.right = 175;150 rect.bottom = 105;151 DrawText(hdc, TEXT("9"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);152 // 钟面相应数字 --- 8153 rect.left = 175;154 rect.top = 135;155 rect.right = 190;156 rect.bottom = 145;157 DrawText(hdc, TEXT("8"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);158 // 钟面相应数字 --- 7159 rect.left = 208;160 rect.top = 167;161 rect.right = 215;162 rect.bottom = 185;163 DrawText(hdc, TEXT("7"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);164 // 钟面相应数字 --- 6165 rect.left = 250;166 rect.top = 182;167 rect.right = 270;168 rect.bottom = 192;169 DrawText(hdc, TEXT("6"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);170 // 钟面相应数字 --- 5171 rect.left = 295;172 rect.top = 170;173 rect.right = 310;174 rect.bottom = 180;175 DrawText(hdc, TEXT("5"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);176 // 钟面相应数字 --- 4177 rect.left = 335;178 rect.top = 135;179 rect.right = 345;180 rect.bottom = 145;181 DrawText(hdc, TEXT("4"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);182 // 钟面相应数字 --- 3183 rect.left = 345;184 rect.top = 95;185 rect.right = 355;186 rect.bottom = 105;187 DrawText(hdc, TEXT("3"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);188 // 钟面相应数字 --- 2189 rect.left = 335;190 rect.top = 48;191 rect.right = 345;192 rect.bottom = 60;193 DrawText(hdc, TEXT("2"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);194 // 钟面相应数字 --- 1195 rect.left = 300;196 rect.top = 20;197 rect.right = 310;198 rect.bottom = 30;199 DrawText(hdc, TEXT("1"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);200 return;201 }202 203 // 画出时钟指针204 void DrawClockHands(HDC hdc,int hour,int min,int sec){205 PAINTSTRUCT ps;206 RECT rect;207 HPEN hPen;208 HPEN oldPen;209 double xStart1, yStart1, xEnd1, yEnd1;210 hour = (hour >= 12 ? hour - 12 : hour);211 hPen = CreatePen(PS_SOLID, 5, RGB(255, 0, 0)); // 创建画笔(线形,线宽,颜色)212 oldPen = (HPEN)SelectObject(hdc, hPen); // 选择画笔,并保留原画笔213 // 显示时针214 xStart1 = 260;215 yStart1 = 100;216 xEnd1 = 260 + (80 - 50) * sin(hour*PI / 6 + ((min * 60 + sec) * PI / (1800*12)));217 yEnd1 = 100 - (80 - 50) * cos(hour*PI / 6 + ((min * 60 + sec) * PI / (1800*12)));218 MoveToEx(hdc, xStart1, yStart1, NULL);219 LineTo(hdc, xEnd1, yEnd1);220 DeleteObject(hPen);221 222 hPen = CreatePen(PS_SOLID, 3, RGB(0, 255, 0)); // 创建画笔(线形,线宽,颜色)223 oldPen = (HPEN)SelectObject(hdc, hPen); // 选择画笔,并保留原画笔224 // 显示分针225 xStart1 = 260;226 yStart1 = 100;227 xEnd1 = 260 + (80 - 35) * sin(min*PI / 30 + (sec * PI / 1800));228 yEnd1 = 100 - (80 - 35) * cos(min*PI / 30 + (sec * PI / 1800));229 MoveToEx(hdc, xStart1, yStart1, NULL);230 LineTo(hdc, xEnd1, yEnd1);231 DeleteObject(hPen);232 233 hPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); // 创建画笔(线形,线宽,颜色)234 oldPen = (HPEN)SelectObject(hdc, hPen); // 选择画笔,并保留原画笔235 // 显示秒针236 xStart1 = 260;237 yStart1 = 100;238 xEnd1 = 260 + (80 - 15) * sin(sec * PI / 30);239 yEnd1 = 100 - (80 - 15) * cos(sec * PI / 30);240 MoveToEx(hdc, xStart1, yStart1, NULL);241 LineTo(hdc, xEnd1, yEnd1);242 DeleteObject(hPen);243 244 return;245 }246 /*247 void ShowTime1(HDC hdc){ // use for debug248 HPEN hPen, oldPen;249 hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); // 创建画笔(线形,线宽,颜色)250 oldPen = (HPEN)SelectObject(hdc, hPen); // 选择画笔,并保留原画笔251 MoveToEx(hdc, 5, 5, NULL);252 LineTo(hdc, 10, 10);253 }254 *////255 256 // 显示数字时钟,注意用函数FillRect擦除背景257 void ShowTime(HDC hdc,int hour,int min,int sec){258 PAINTSTRUCT ps;259 RECT rect;260 LOGBRUSH logbrush;261 HBRUSH hBrush, oldBrush;262 HRGN hRgn; // 区域用于区域填充、剪切、合并、反转、画边框或设无效区 263 264 HDC hdc1;265 HPEN hPen, oldPen;266 hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); // 创建画笔(线形,线宽,颜色)267 oldPen = (HPEN)SelectObject(hdc1, hPen); // 选择画笔,并保留原画笔268 MoveToEx(hdc1, 5, 5, NULL);269 LineTo(hdc1, 10, 10);270 271 // logbrush.lbColor = RGB(255, 255, 255);272 // logbrush.lbHatch = HS_BDIAGONAL; // 阴影样式:HS_BDIAGONAL 对角线,HS_DIAGCROSS 对角交叉线273 // logbrush.lbStyle = BS_HATCHED; // 画刷样式:BS_SOLID 实心,BS_HATCHED 阴影274 // hBrush = (HBRUSH)CreateBrushIndirect(&logbrush);275 hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);276 oldBrush = (HBRUSH)SelectObject(hdc, hBrush); // 选择画刷,并保留原画刷277 SelectObject(hdc, hBrush);278 hRgn = CreateEllipticRgn(195, 35, 325, 165); // 定义区域 279 FillRgn(hdc, hRgn, hBrush); // 填充区域280 DeleteObject(hBrush); // 删除画刷281 SelectObject(hdc, oldBrush); // 恢复原画刷282 283 DrawClockHands(hdc, hour, min, sec);284 return;285 }286 287 // 显示时钟函数,288 void ShowClock(HWND hwnd){289 int x,y,r;290 HDC hdc = GetDC(hwnd);291 RECT rect;292 TCHAR buf[100];293 SYSTEMTIME st;294 295 //GetClientRect(hwnd,&rect);296 rect.left = 230;297 rect.top = 210;298 rect.right = rect.left + 100;299 rect.bottom = rect.top + 30;300 GetLocalTime(&st);301 wsprintf(buf, TEXT("%d:%d:%d\0"), st.wHour, st.wMinute, st.wSecond);302 DrawText(hdc, buf, -1, &rect,303 DT_SINGLELINE | DT_LEFT | DT_TOP);304 305 ReleaseDC(hwnd, hdc);306 return;307 }308 309 LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)310 {311 HDC hdc ;312 PAINTSTRUCT ps ;313 HPEN hPen;314 HPEN oldPen;315 SYSTEMTIME st;316 switch (message)317 {318 case WM_CREATE:319 PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;320 return 0 ;321 322 case WM_PAINT:323 hdc = BeginPaint (hwnd, &ps) ;324 DrawClockFace(hdc); // 画钟325 GetLocalTime(&st); //画时针分针秒针326 DrawClockHands(hdc ,st.wHour, st.wMinute, st.wSecond);327 ShowClock(hwnd);// 当窗口重刷时显示时间,否则停止时钟时可能空白328 // EndPaint(hwnd, &ps) ;329 return 0 ;330 331 case WM_COMMAND:332 // LOWORD (wParam) 子窗口ID, HIWORD (wParam) 按钮通知码, lParam 子窗口句柄333 334 switch (LOWORD(wParam)) //子窗口ID335 {336 case BUTTON1:337 SetTimer(hwnd, TIMER_SEC, 1000, NULL); // 启动定时器(1000毫秒一次),TIMER_SEC为自定义索引号338 break;339 case BUTTON2:340 KillTimer(hwnd, TIMER_SEC); // 删除定时器341 break;342 }343 return 0;344 345 case WM_TIMER:346 switch (wParam)347 {348 case TIMER_SEC:349 ShowClock(hwnd);//每秒一次的处理350 InvalidateRgn(hwnd, NULL, 1); // 使区域无效351 // ShowTime1(hdc);352 ShowTime(hdc, st.wHour, st.wMinute, st.wSecond);353 354 break;355 case TIMER_MIN: //每分钟一次的处理356 break;357 }358 return 0;359 case WM_DESTROY:360 PostQuitMessage (0) ;361 return 0 ;362 }363 return DefWindowProc (hwnd, message, wParam, lParam) ;364 }
View Code

 

转载于:https://www.cnblogs.com/imwtr/p/4105236.html

你可能感兴趣的文章
C#面试宝典
查看>>
基金项目的英文
查看>>
《软件性能测试与LoadRunner实战教程》喜马拉雅有声图书上线
查看>>
ios 字典转模型
查看>>
Java类集
查看>>
类的生命周期
查看>>
php apache用户写文件夹权限设置
查看>>
浅析rune数据类型
查看>>
普通用户开启AUTOTRACE 功能
查看>>
游侠原创:推荐一款免费的Syslog转发工具
查看>>
onAttachedToWindow和onDetachedFromWindow调用时机源码解析
查看>>
根据Servlet的Filter自定义实现字符编码过滤器
查看>>
oh-my-zsh安装与配置
查看>>
1.7 文件目录管理及相关的命令使用方法
查看>>
类成员与类的实例成员
查看>>
Spark源码编译并在YARN上运行WordCount实例
查看>>
Spring AOP + AspectJ annotation example
查看>>
Spring VS EJB 3 的若干认识误区(转)
查看>>
React.js初探(一)
查看>>
json_encode后的中文不编码成unicode
查看>>