现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

Win32 关键点总结(6):计时器

2012-09-11 12:28 工业·编程 ⁄ 共 2812字 ⁄ 字号 评论 1 条

69 计时器基础

计时器是一种输入设备,它周期性地每经过一个指定的时间间隔就用WM_TIMER消息通知应用程序一次。

可以通过调用SetTimer函数为Windows应用程序分配一个计时器。SetTimer有一个时间间隔范围为1~4294967295毫秒的整型参数,这个值指示Windows每隔多长时间给程序发送WM_TIMER消息。

当程序用完计时器时,就调用KillTimer函数停止计时器消息。

KillTimer调用清除消息队列中尚未被处理的WM_TIMER消息,从而使程序在调用KillTimer之后就不会再受到WM_TIMER消息。

》》》Win32 关键点总结(5):鼠标

70 系统和计时器

Windows计时器是PC的硬件和ROM BIOS构造的计时器逻辑的一种相对简单的扩展。

BIOS的“计时器滴答”中断约每54.915毫秒或者大约每秒18.2次。

在Microsoft Windows NT中,计时器的分辨率为10毫秒。

Windows应用程序不能以高于这个分辨率的速率接收WM_TIMER消息。在SetTimer调用中指定的时间间隔总是截尾为时钟滴答的整数倍。例如,1000毫秒的间隔除以54.925毫秒≈18.207个时钟滴答,截尾后为18个时钟滴答,它实际上是989毫秒。对每个小于55毫秒的间隔,每个时钟滴答都产生一个WM_TIMER消息。

71 计时器消息不是异步的

计时器是基于硬件计时器中断。但WM_TIMER消息却不是异步的。

WM_TIMER消息放在正常的消息队列之中,和其他消息一起参加排序,因此,如果在SetTimer调用中指定间隔为1000毫秒,那么不能保持程序每1000毫秒就会收到一个WM_TIMER消息。如果其他程序的运行事件超过一秒,在此期间,程序将不会收到任何WM_TIMER消息。

Windows不能持续向消息队列放入多个WM_TIMER消息,而是将多余的WM_TIMER消息合并成一个消息。

72 计时器的使用(方法一)

如果需要在整个程序期间使用计时器,那么可以在处理WM_CREATE消息时调用SetTimer,并在处理WM_DESTROY消息时调用KillTimer。

SetTimer函数如下所示:

SetTimer(hwnd, 1, uiMsecInterval, NULL);

第一个参数是其窗口过程将接收WM_TIMER消息的窗口的句柄;

第二个参数是计时器ID,只要是非0的整数就可以,如果设置多个计时器,那么各个计时器的ID应该不同。

第三个参数是一个32位无符号整数,以毫秒为单位指定一个时间间隔。

第四个参数是回调函数的地址,如果处理WM_TIMER消息不是回调函数,那么设置为NULL。

KillTimer函数调用如下:

KillTimer(hwnd, 1);

第一个参数是其窗口过程将接收WM_TIMER消息的窗口的句柄;

第二个参数是计时器ID。

KillTimer用于在任何时刻停止WM_TIMER消息。

当窗口过程收到一个WM_TIMER消息时,wParam参数等于计时器的ID值,lParam参数为0.如果需要设置多个计时器,那么对每个计时器都使用不同的计时器ID。wParam的值将随传递到窗口过程的WM_TIMER消息的不同而不同。

73 计时器的使用(方法二)

第一种方法是把WM_TIMER消息发送到通常的窗口过程。

第二种方法是让Windows直接将计时器消息发送给程序的另一个函数。

接收这些计时器消息的函数称为“回调函数”,这是一个在程序之中,但是由Windows而不是程序本身调用的函数。先告诉Windows这个函数的地址,然后Windows调用此函数。

窗口过程其实就是一种回调函数。

回调函数必须定义为CALLBACK,因为它是由Windows从程序的代码段调用的。回调函数的参数和回调函数的返回值依赖于回调函数的目的。同计时器相关的回调函数中,输入参数同窗口过程的输入参数一样。计时器回调函数不向Windows返回值,可以设置为VOID。

假设计时器回调函数称为TimerProc,那么可以定义如下:

VOID CALLBACK TimerProc(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)

{

    WM_TIMER消息的处理过程;

}

TimerProc的参数hwnd是在调用SetTimer时指定的窗口句柄。Windows只把WM_TIMER消息消息送过TimerProc,因此消息参数总是等于WM_TIMER。iTimerID值是计时器ID,dwTimer值是与从GetTickCount函数的返回值兼容的值,是反映Windows启动后所经过的毫秒数。

在使用回调函数处理WM_TIMER消息时,窗口过程中设置SetTimer的第4个参数由回调函数的地址取代,如下所示:

SetTimer(hwnd, iTimerID, iMsecInterval, TimerProc);

回调函数必须和窗口过程函数一样,一起被声明在程序的开始处,像TimerProc的函数声明如下:

VOID CALLBACK TimerProc(HWND, UINT, UINT, DWORD);

74计时器的使用(方法三)(少用)

设置计时器的第三种方法类似于第二种方法,只是传递给SetTimer的hwnd参数被设置为NULL,并且第二个参数计时器ID也被忽略,设置为0,最后才函数返回计时器ID。

iTimerID = SetTimer(NULL, 0, iMsecInterval, TimerProc);

如果没有可用的计时器,那么从SetTimer返回的iTimerID值将为NULL。

KillTimer的第一个参数也必须是NULL,计时器ID必须是SetTimer的返回值。

传递给TimerProc计时器函数的hwnd参数也必须是NULL。

75 获取当前时间

首先介绍下SYSTEMTIME结构,如下所示:

typedef struct _SYSTEMTIME {

    WORD wYear;

    WORD wMonth;

    WORD wDayOfWeek;

    WORD wDay;

    WORD wHour;

    WORD wMinute;

    WORD wSecond;

    WORD wMilliseconds;

} SYSTEMTIME, *PSYSTEMTIME;

SYSTEMTIME结构包含日期和时间。月份由1开始递增,星期由0开始递增(星期天是0)。wDay是本月的当前日子,从1开始递增。

SYSTEM主要用于GetLocalTime和GetSystemTime函数。

GetSystemTime函数返回当前的世界时间(格林尼治时间)

GetSystemTime函数返回当地时间。

76 WM_SETTINGCHANGE消息

如果用户改变了任何系统设置,Windows会产生WM_SETTINGCHANGE消息,并传送给所有的应用程序。

目前有 1 条留言    访客:0 条, 博主:0 条 ,引用: 1 条

    外部的引用: 1 条

    • Win32 关键点总结(7):子窗口控制 « 求索阁

    给我留言

    留言无头像?