Windows下编程--模拟时钟的实现
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下编程--模拟时钟的实现的更多相关文章
- windows 下编程实现打印日志
下面是在windows下编程实现的日志打印,写的比较简单,可以根据实际情况进行修改使用. 宏WRITELOG在vs2013可以正常使用. 在vs2003和vs2010可能会报错,可以直接使用myLog ...
- VC++SDK编程——模拟时钟
#include <Windows.h> #include <tchar.h> #include <math.h> typedef struct Time { in ...
- 使用IDEA2017在Windows下编程并测试Hadoop2.7+Spark2.2+Azkaban
1. 下载好IDEA HADOOP SPARK 首先,配置IDEA, 在插件管理中使用IDEA在线库安装scala插件, 在在线库直接搜索即可; 其次,配置Maven选项, 将Maven添加到IDEA ...
- Windows下编程2----- C语言常用函数举例
几个小函数 1. //MessageBoxA(0,"网络故障,重新登录","qq error",3); //弹出对话框 2. //ShellExec ...
- windows下LINUX模拟终端Cypwin以及Vim的配置使用
Cypwin的安装 从官网下载相应版本后,直接安装. 官网地址:Cypwin 安装过程中可以选择相应的Packages,我们需要安装的Vim就需要在这一步中选择相应的包. Cypwin的使用 纯命令行 ...
- Windows下Android模拟环境的搭建
- windows下C语言编程获取磁盘(分区)使用情况
windows下编程获取磁盘(分区)使用情况 windows下编程获取磁盘(分区)使用情况 GetLogicalDriveStrings函数 使用示例 获取需要的缓冲区长度示例 获取所有驱动器号示例 ...
- windows下的socket网络编程
windows下的socket网络编程 windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了, ...
- windows下的socket网络编程(入门级)
windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了,这次因为需要做一个跨平台的网络程序,就先 ...
随机推荐
- Docker私有仓库Registry实战
参考: https://www.cnblogs.com/soar1688/p/6828329.html 1. 关于Registry 官方的Docker hub是一个用于管理公共镜像的好地方,我们可以在 ...
- 3.C#WebAPI设置路由和参数2
1.上面已经教大家如何修改全局路由了,那么修改完后我们在post请求的要这样使用,其中model模型我就默认你应该已经建好了,没有创建的话请看上一部分 Post方法的参数,如果提交的请求体需要是pho ...
- C# 加载配置文件
//加载配置文件 var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .Add ...
- C# 中多态和重载的区别
一.多态性意味着有多重形式. 在面向对象编程范式中,多态性往往表现为"一个接口,多个功能". using System; using System.Collections.Gene ...
- django drf CreateModelMixin和Serializer.validate_columun
view demo class ValidateCodeSet(mixins.CreateModelMixin, viewsets.GenericViewSet): serializer_class ...
- C# 连接sqlite数据库
web.config <connectionStrings> <add name="SQLiteDB" connectionString="Data S ...
- python网络编程--粘包解决方案 和 subprocess模块
1.缓冲区:作用:将程序和网络解耦分为输入缓冲区, 输出缓冲区 每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区.write()/send() 并不立即向网络中传输数据,而是先 ...
- 获取BinaryReader中读取的文件名
BinaryReader br; br = null; br = new BinaryReader(new FileStream("E:demo.txt", FileMode.Op ...
- 【ocp-12c】最新Oracle OCP-071考试题库(47题)
47.(10-6)choose two You need to calculate the number of days from 1st January 2007 till date. Dates ...
- enumerate 和 dict.items()
对 list 遍历 a_list = [1,2,3] for index,iterm in enumerate(a_list): print(index,iterm) 对 dict 遍历 dict = ...