MFC定时器的应用


在计算机程序设计领域,有很多功能是周期性执行的,
      如:数据采集程序,系统时间的显示等。
数据采集:周期性地获得现场的物理量信息
系统时间的显示:周期性地获得系统时间,并显示出来。
完成上述这些功能的代码都是按照一定的时间间隔周期性地执行的,这是就需要用到一个新的组件——定时器(TIMER)。  
    定时器是Windows系统的资源, Visual C++提供了定时器消息和一些与定时相关的函数。使用这些函数可以完成程序代码的周期性执行。
Viusal C++提供了三种完成周期性操作的方法:
1、Sleep函数(延时函数)。
2、WM_TIMER消息(Windows窗口消息)。
3、多媒体定时器。
3.2.1 Sleep函数
while(1)  
{  
i=i+1; //此处添加需要周期性执行的代码。 
Sleep(1000);
}
Sleep函数:延时函数
参数:延时的时间(单位ms)
缺点:
(1)CPU占用率高,一般适用于单任务的程序(如DOS操作系统的程序)
(2)程序能够完成的功能比较简单。
(3)定时精度低,(据资料)最小误差为54.915 ms,每秒18.2次
3.2.2 WM_TIMER
众所周知,Windows系统是一个多任务的操作系统。即可以有多个任务并行,这时,周期性(定时)执行的任务在执行完毕后,应该将控制权交给系统,这样程序的其它功能才能得以执行。
Windows系统提供了WM_TIMER消息来实现多任务系统的定时操作。
    WM_TIMER是一个Windosws的窗口消息
1、WM_TIMER的功能:
    (1)可以完成定时操作。
    (2)定时任务执行完毕后,将控制权交回给程序。程序可以进行其它的操作。
 
2、使用WM_TIMER消息需要用到的函数
1) SetTimer()
功能:设置定时间隔并启动定时器。
函数原型:UINT SetTimer(UINT nIDEvent,UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD));
参数说明:
nIDEvent:非0值标识Timer的id 。
nElapse:以毫秒为单位的定时间隔时间
lpfnTimer 指向定时事件到达时调用的函数的指针,如果为NULL,那么调用OnTimer()
例:SetTimer(1,200,NULL)设置并启动一个时间间隔为200ms的定时器。消息响应函数为OnTimer()
例:SetTimer(2,1000, TimerProc );设置并启动一个实间间隔为1s的定时器,该定时器的响应函数为TimerProc。
2)KillTimer(1)
功能:取消定时器,此函数调用后,相应的定时器将被关闭不再起作用。
参数:用SetTimer()函数创建的定时器标识。
定时器使用总结:
1、在WM_CREATE消息中启动定时器(SetTimer)
2、在WM_TIMER消息中编写定时函数(即需要周期性完成的工作)
3、在定时工作完成之后关闭/停止定时器。(可选)
WM_TIMER的缺点:
1、精度低,最小计时精度大约为55ms(Win95),或10ms左右(Win2000/xp)
2、定时器消息在多任务操作系统中的优先级较低,有时不能得到及时响应。(一旦计算机的CPU被某个进程占用,或系统资源紧张时,发送到消息队列中的消息就暂时被挂起,WM_TIMER消息得不到及时处理。)
3.2.3 多媒体定时器
1、 针对前两种定时器的缺点,MicroSoft公司提供了一种精度更高的定时器——多媒体定时器。
优点:
(1)精度较高:多媒体定时器最小误差为1毫秒。
(2)优先级较高,可以减轻资源紧张对定时器运行的影响。
2、多媒体定时器的使用
timeSetEvent 函数
功能:设置并启动一个多媒体定时器。
函数原型:
MMRESULT timeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, WORD dwUser, UINT fuEvent )
函数头文件:#include "mmsystem.h"
MMRESULT timeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, WORD dwUser, UINT fuEvent )
参数说明:
uDelay:以毫秒指定时的周期
Uresolution:以毫秒指定延时的精度,数值越小定时器事件分辨率越高。缺省值为1ms。
LpTimeProc:指向一个回调函数,该回调函数包含需要定时执行的代码。
DwUser:存放用户提供的回调数据。
FuEvent:指定定时器事件类型:
    TIME_ONESHOT:uDelay毫秒后只产生一次事件。
    TIME_PERIODIC :每隔uDelay毫秒周期性地产生事件。
3.3 其它定时方法
1、使用GetTickCount函数
2、使用QueryPerformanceFrequency()和QueryPerformanceCounter()函数。
在精度要求较高的情况下,如要求定时误差不大于1ms时,还可以利用GetTickCount()函数返回自计算机启动后的时间,该函数的返回值是DWORD型,表示以ms为单位的计算机启动后经历的时间间隔。通过两次调用GetTickCount()函数,然后控制它们的差值来取得定时效果。.下列的代码可以实现50ms的精确定时,其误差是毫秒级的。
3、使用QueryPerformanceFrequency()和QueryPerformanceCounter()函数
    对于更精确的定时操作,使用QueryPerformanceFrequency()和QueryPerformanceCounter()函数。这两个函数是Visual C++提供并且仅供Windows 95及其后续版本使用,其精度与CPU的时钟频率有关,它们要求计算机从硬件上支持精确定时器。QueryPerformanceFrequency()函数和QueryPerformanceCounter()函数的原型如下:
BOOL QueryPerformanceFrequency (LARGE_INTEGER *lpFrequency);
BOOL QueryPerformanceCounter (LARGE_INTEGER *lpCount);
使用QueryPerformanceFrequency()和QueryPerformanceCounter()函数进行精确定时的步骤如下:
  1、首先调用QueryPerformanceFrequency()函数取得高精度运行计数器的频率f,单位是每秒多少次(n/s),此数一般很大;
  2、在需要定时的代码的两端分别调用QueryPerformanceCounter()以取得高精度运行计数器的数值n1、n2,两次数值的差值通过f换算成时间间隔,t=(n2-n1)/f,当t大于或等于定时时间长度时,启动定时器;

你可能感兴趣的:(C++,Code,mfc,timer,windows,任务,integer,microsoft)