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

主要可以分为几个步骤:

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

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

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

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

(5)   编写画出钟面函数

(6)   编写画出指针函数

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

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

每一步的说明:

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

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

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

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

(5) 编写画出钟面函数

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

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

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

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

 /*------------------------------------------------------------
HELLOWIN.C -- Displays "Hello, Windows 98!" in client area
(c) Charles Petzold, 1998
------------------------------------------------------------*/ #include <windows.h>
#include <stdio.h>
#include <math.h> #define PI 3.14159265358979323846
#define TIMER_SEC 1
#define TIMER_MIN 2
#define BUTTON1 3
#define BUTTON2 4 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HelloWin") ;
HWND hwnd,hwndButton1,hwndButton2;
MSG msg ;
WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = ;
wndclass.cbWndExtra = ;
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 ;
} hwnd = CreateWindow (szAppName, // window class name
TEXT ("Analog Clock"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
, // initial x size
, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ; hwndButton1 = CreateWindow(TEXT("button"), // 窗口类名(系统内部定义了该窗口类)
TEXT("StartTimer"), // 标题
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, // 样式
, , // 左上角位置x,y
, , // 宽度,高度
hwnd, // 父窗口句柄
(HMENU)BUTTON1, // 控件ID
hInstance, // 实例句柄
NULL); // 自定义参数 hwndButton2 = CreateWindow(TEXT("button"), // 窗口类名
TEXT("StopTimer"), // 标题
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, // 样式
, , // 左上角位置x,y
, , // 宽度,高度
hwnd, // 父窗口句柄
(HMENU)BUTTON2, // 控件ID
hInstance, // 实例句柄
NULL); while (GetMessage (&msg, NULL, , ))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
} // 画出钟面(不包括指针)
void DrawClockFace(HDC hdc){
// PAINTSTRUCT ps;
RECT rect;
HPEN hPen;
HPEN oldPen;
hPen = CreatePen(PS_SOLID, , RGB(, , )); // 创建画笔(线形,线宽,颜色)
oldPen = (HPEN)SelectObject(hdc, hPen); // 选择画笔,并保留原画笔
Ellipse(hdc, , , , ); // 时钟--半径 80 作出时钟原始图像
Rectangle(hdc, , , , );
double xStart1, yStart1, xEnd1, yEnd1;
for (int i = ; i <= ; i++){
if (i <= ){
xEnd1 = + * sin(i* PI / );
xStart1 = + ( - ) * sin(i* PI / );
yEnd1 = - * cos(i* PI / );
yStart1 = - ( - ) * cos(i* PI / );
}
if (i > && i <= ){
xEnd1 = + * sin(i* PI / );
xStart1 = + ( - ) * sin(i* PI / );
yStart1 = + ( - ) * cos(PI - i* PI / );
yEnd1 = + * cos(PI - i* PI / );
}
if (i > && i <= )
{
xEnd1 = - * cos(1.5*PI - i* PI / );
xStart1 = - ( - ) * cos(1.5*PI - i* PI / );
yStart1 = + ( - ) * sin(1.5*PI - i* PI / );
yEnd1 = + * sin(1.5*PI - i* PI / );
}
if (i > ){
xEnd1 = - * sin( * PI - i* PI / );
xStart1 = - ( - ) * sin( * PI - i* PI / );
yEnd1 = - * cos( * PI - i* PI / );
yStart1 = - ( - ) * cos( * PI - i* PI / );
}
MoveToEx(hdc, xStart1, yStart1, NULL);
LineTo(hdc, xEnd1, yEnd1);
}
DeleteObject(hPen);
// 钟面相应数字 --- 12
rect.left = ;
rect.top = ;
rect.right = ;
rect.bottom = ;
DrawText(hdc, TEXT(""), -, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
// 钟面相应数字 --- 11
rect.left = ;
rect.top = ;
rect.right = ;
rect.bottom = ;
DrawText(hdc, TEXT(""), -, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
// 钟面相应数字 --- 10
rect.left = ;
rect.top = ;
rect.right = ;
rect.bottom = ;
DrawText(hdc, TEXT(""), -, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
// 钟面相应数字 --- 9
rect.left = ;
rect.top = ;
rect.right = ;
rect.bottom = ;
DrawText(hdc, TEXT(""), -, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
// 钟面相应数字 --- 8
rect.left = ;
rect.top = ;
rect.right = ;
rect.bottom = ;
DrawText(hdc, TEXT(""), -, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
// 钟面相应数字 --- 7
rect.left = ;
rect.top = ;
rect.right = ;
rect.bottom = ;
DrawText(hdc, TEXT(""), -, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
// 钟面相应数字 --- 6
rect.left = ;
rect.top = ;
rect.right = ;
rect.bottom = ;
DrawText(hdc, TEXT(""), -, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
// 钟面相应数字 --- 5
rect.left = ;
rect.top = ;
rect.right = ;
rect.bottom = ;
DrawText(hdc, TEXT(""), -, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
// 钟面相应数字 --- 4
rect.left = ;
rect.top = ;
rect.right = ;
rect.bottom = ;
DrawText(hdc, TEXT(""), -, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
// 钟面相应数字 --- 3
rect.left = ;
rect.top = ;
rect.right = ;
rect.bottom = ;
DrawText(hdc, TEXT(""), -, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
// 钟面相应数字 --- 2
rect.left = ;
rect.top = ;
rect.right = ;
rect.bottom = ;
DrawText(hdc, TEXT(""), -, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
// 钟面相应数字 --- 1
rect.left = ;
rect.top = ;
rect.right = ;
rect.bottom = ;
DrawText(hdc, TEXT(""), -, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
return;
} // 画出时钟指针
void DrawClockHands(HDC hdc,int hour,int min,int sec){
PAINTSTRUCT ps;
RECT rect;
HPEN hPen;
HPEN oldPen;
double xStart1, yStart1, xEnd1, yEnd1;
hour = (hour >= ? hour - : hour);
hPen = CreatePen(PS_SOLID, , RGB(, , )); // 创建画笔(线形,线宽,颜色)
oldPen = (HPEN)SelectObject(hdc, hPen); // 选择画笔,并保留原画笔
// 显示时针
xStart1 = ;
yStart1 = ;
xEnd1 = + ( - ) * sin(hour*PI / + ((min * + sec) * PI / (*)));
yEnd1 = - ( - ) * cos(hour*PI / + ((min * + sec) * PI / (*)));
MoveToEx(hdc, xStart1, yStart1, NULL);
LineTo(hdc, xEnd1, yEnd1);
DeleteObject(hPen); hPen = CreatePen(PS_SOLID, , RGB(, , )); // 创建画笔(线形,线宽,颜色)
oldPen = (HPEN)SelectObject(hdc, hPen); // 选择画笔,并保留原画笔
// 显示分针
xStart1 = ;
yStart1 = ;
xEnd1 = + ( - ) * sin(min*PI / + (sec * PI / ));
yEnd1 = - ( - ) * cos(min*PI / + (sec * PI / ));
MoveToEx(hdc, xStart1, yStart1, NULL);
LineTo(hdc, xEnd1, yEnd1);
DeleteObject(hPen); hPen = CreatePen(PS_SOLID, , RGB(, , )); // 创建画笔(线形,线宽,颜色)
oldPen = (HPEN)SelectObject(hdc, hPen); // 选择画笔,并保留原画笔
// 显示秒针
xStart1 = ;
yStart1 = ;
xEnd1 = + ( - ) * sin(sec * PI / );
yEnd1 = - ( - ) * cos(sec * PI / );
MoveToEx(hdc, xStart1, yStart1, NULL);
LineTo(hdc, xEnd1, yEnd1);
DeleteObject(hPen); return;
}
/*////////////////////////////////////////////////////
void ShowTime1(HDC hdc){ // use for debug
HPEN hPen, oldPen;
hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); // 创建画笔(线形,线宽,颜色)
oldPen = (HPEN)SelectObject(hdc, hPen); // 选择画笔,并保留原画笔
MoveToEx(hdc, 5, 5, NULL);
LineTo(hdc, 10, 10);
}
*//////////////////////////////////////////////////// // 显示数字时钟,注意用函数FillRect擦除背景
void ShowTime(HDC hdc,int hour,int min,int sec){
PAINTSTRUCT ps;
RECT rect;
LOGBRUSH logbrush;
HBRUSH hBrush, oldBrush;
HRGN hRgn; // 区域用于区域填充、剪切、合并、反转、画边框或设无效区 HDC hdc1;
HPEN hPen, oldPen;
hPen = CreatePen(PS_SOLID, , RGB(, , )); // 创建画笔(线形,线宽,颜色)
oldPen = (HPEN)SelectObject(hdc1, hPen); // 选择画笔,并保留原画笔
MoveToEx(hdc1, , , NULL);
LineTo(hdc1, , ); // logbrush.lbColor = RGB(255, 255, 255);
// logbrush.lbHatch = HS_BDIAGONAL; // 阴影样式:HS_BDIAGONAL 对角线,HS_DIAGCROSS 对角交叉线
// logbrush.lbStyle = BS_HATCHED; // 画刷样式:BS_SOLID 实心,BS_HATCHED 阴影
// hBrush = (HBRUSH)CreateBrushIndirect(&logbrush);
hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
oldBrush = (HBRUSH)SelectObject(hdc, hBrush); // 选择画刷,并保留原画刷
SelectObject(hdc, hBrush);
hRgn = CreateEllipticRgn(, , , ); // 定义区域
FillRgn(hdc, hRgn, hBrush); // 填充区域
DeleteObject(hBrush); // 删除画刷
SelectObject(hdc, oldBrush); // 恢复原画刷 DrawClockHands(hdc, hour, min, sec);
return;
} // 显示时钟函数,
void ShowClock(HWND hwnd){
int x,y,r;
HDC hdc = GetDC(hwnd);
RECT rect;
TCHAR buf[];
SYSTEMTIME st; //GetClientRect(hwnd,&rect);
rect.left = ;
rect.top = ;
rect.right = rect.left + ;
rect.bottom = rect.top + ;
GetLocalTime(&st);
wsprintf(buf, TEXT("%d:%d:%d\0"), st.wHour, st.wMinute, st.wSecond);
DrawText(hdc, buf, -, &rect,
DT_SINGLELINE | DT_LEFT | DT_TOP); ReleaseDC(hwnd, hdc);
return;
} LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
HPEN hPen;
HPEN oldPen;
SYSTEMTIME st;
switch (message)
{
case WM_CREATE:
PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
return ; case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
DrawClockFace(hdc); // 画钟
GetLocalTime(&st); //画时针分针秒针
DrawClockHands(hdc ,st.wHour, st.wMinute, st.wSecond);
ShowClock(hwnd);// 当窗口重刷时显示时间,否则停止时钟时可能空白
// EndPaint(hwnd, &ps) ;
return ; case WM_COMMAND:
// LOWORD (wParam) 子窗口ID, HIWORD (wParam) 按钮通知码, lParam 子窗口句柄 switch (LOWORD(wParam)) //子窗口ID
{
case BUTTON1:
SetTimer(hwnd, TIMER_SEC, , NULL); // 启动定时器(1000毫秒一次),TIMER_SEC为自定义索引号
break;
case BUTTON2:
KillTimer(hwnd, TIMER_SEC); // 删除定时器
break;
}
return ; case WM_TIMER:
switch (wParam)
{
case TIMER_SEC:
ShowClock(hwnd);//每秒一次的处理
InvalidateRgn(hwnd, NULL, ); // 使区域无效
// ShowTime1(hdc);
ShowTime(hdc, st.wHour, st.wMinute, st.wSecond); break;
case TIMER_MIN: //每分钟一次的处理
break;
}
return ;
case WM_DESTROY:
PostQuitMessage () ;
return ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}

Windows下编程--模拟时钟的实现的更多相关文章

  1. windows 下编程实现打印日志

    下面是在windows下编程实现的日志打印,写的比较简单,可以根据实际情况进行修改使用. 宏WRITELOG在vs2013可以正常使用. 在vs2003和vs2010可能会报错,可以直接使用myLog ...

  2. VC++SDK编程——模拟时钟

    #include <Windows.h> #include <tchar.h> #include <math.h> typedef struct Time { in ...

  3. 使用IDEA2017在Windows下编程并测试Hadoop2.7+Spark2.2+Azkaban

    1. 下载好IDEA HADOOP SPARK 首先,配置IDEA, 在插件管理中使用IDEA在线库安装scala插件, 在在线库直接搜索即可; 其次,配置Maven选项, 将Maven添加到IDEA ...

  4. Windows下编程2----- C语言常用函数举例

    几个小函数 1.    //MessageBoxA(0,"网络故障,重新登录","qq error",3); //弹出对话框 2.    //ShellExec ...

  5. windows下LINUX模拟终端Cypwin以及Vim的配置使用

    Cypwin的安装 从官网下载相应版本后,直接安装. 官网地址:Cypwin 安装过程中可以选择相应的Packages,我们需要安装的Vim就需要在这一步中选择相应的包. Cypwin的使用 纯命令行 ...

  6. Windows下Android模拟环境的搭建

  7. windows下C语言编程获取磁盘(分区)使用情况

    windows下编程获取磁盘(分区)使用情况 windows下编程获取磁盘(分区)使用情况 GetLogicalDriveStrings函数 使用示例 获取需要的缓冲区长度示例 获取所有驱动器号示例 ...

  8. windows下的socket网络编程

    windows下的socket网络编程 windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了, ...

  9. windows下的socket网络编程(入门级)

    windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了,这次因为需要做一个跨平台的网络程序,就先 ...

随机推荐

  1. java学习笔记—第三方操作数据库包专门接收DataSource-dbutils (30)

    Dbutils 操作数据第三方包.依赖数据源DataSource(DBCP|C3p0). QueryRunner – 接收DataSource|Connection,查询数据删除修改操作.返回结果. ...

  2. “全栈2019”Java第一百一十二章:什么是闭包?

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  3. JAVA日期——java.util.date类的操作

    package com.hxzy.time; import java.text.SimpleDateFormat;import java.util.Date; public class DateDem ...

  4. 0基础浅谈反射型xss(2)

    0x1:回顾前文疑惑“先闭合,在构造” 上一篇,我们说到了xss的一个触发精髓,“先闭合,在构造”,对于前面的先闭合,我们来简单的解释一下:   首先说,为什么要闭合? 因为HTML标签都是成对出现的 ...

  5. jquery input 实时监听输入

    $('input').bind('input propertychange', function() { alert('hello world') });

  6. 在linux云服务器上运行Jar文件

    在linux服务器上运行Jar文件时通常的方法是: $ java -jar test.jar 这种方式特点是ssh窗口关闭时,程序中止运行.或者是运行时没法切出去执行其他任务,有没有办法让Jar在后台 ...

  7. 安装配置python、beautifulsoup4、pip的心酸总结

    1.python下载安装不纠结,但如果要加入到eclipse里面就要注意一下版本,版本不匹配会造成,要不python降级,要不eclipse升级的情况 2.在稍新版本的python立面就附带下载在了p ...

  8. Java NIO学习与记录(八): Reactor两种多线程模型的实现

    Reactor两种多线程模型的实现 注:本篇文章例子基于上一篇进行:Java NIO学习与记录(七): Reactor单线程模型的实现 紧接着上篇Reactor单线程模型的例子来,假设Handler的 ...

  9. noip rp++

    from JOKER-Y

  10. LCS and LIS

    LCS #include<bits/stdc++.h> using namespace std; typedef long long ll; int n,m; char s[1005],t ...