其他语言

位置:IT落伍者 >> 其他语言 >> 浏览文章

利用Delphi建立精确计数器[1]


发布日期:2023年10月17日
 
利用Delphi建立精确计数器[1]

在Windows中的很多场合下编程(例如工业控制游戏)中需要比较精确的记时器本文讨论的是在Delphi下实现记时器的若干方法以及它们的精度控制问题

在Delphi中最常用的是Timer控件它的设置和使用都非常方便理论上它的记时精度可以达到ms(毫秒)但是众所周知的实际上Timer在记时间隔小于ms之下是精度是十分差的它只适用于对于精度要求不太高的场合

这里作者要介绍的是两种利用Windows API函数实现精确记时的方法第一中方法是利用高性能频率记数(作者本人的称呼)法利用这种方法要使用两个API函数QueryPerformanceFrequency和QueryPerformanceCounterQueryPerformanceFrequency函数获得高性能频率记数器的震蕩频率

调用该函数后函数会将系统频率记数器的震蕩频率(每毫秒)保存到一个LargeInteger中不过利用该函数在几台机器上做过试验结果都是读者朋友可以在自己的机器上试一下

QueryPerformanceCounter函数获得系统频率记数器的震蕩次数结果也保存到一个Largenteger中

很显然如果在计时中首先使用QueryPerformanceFrequency获得高性能频率记数器每毫秒的震蕩次数然后在计时开始时使用QueryPerformanceCounter函数获得当前系统频率记数器的震蕩次数在计时结束时再调用QueryPerformanceCounter函数获得系统频率记数器的震蕩次数将两者相减再将结果除以频率记数器每毫秒的震蕩次数就可以获得某一事件经过的准确时间(次数除以频率等于时间)

另外的一种精确记时器的功能是利用多媒体记时器函数(这也是作者的定义因为这个系列的函数是在Winmmdll中定义并且是为媒体播放服务的)

实现多媒体记时器首先要使用timeSetEvent函数建立计时事件该函数在Delphi中的mmsystempas中有定义定义如下

function timeSetEvent(uDelay uResolution: UINT;

lpFunction: TFNTimeCallBack; dwUser: DWORD; uFlags: UINT): MMRESULT; stdcall

函数定义中参数uDelay定义延迟时间以毫秒为单位该参数相当于Timer控件的Interval属性参数uResolution定义记时精度如果要求尽可能高的精度要将该参数设置为参数lpFunction定义了timeSetEvent函数的回调函数该函数相当于一个定时中断处理函数每当经过一个uDelay长度的时间间隔该函数就会被调用编程者可以在该函数中加入相应的处理语句参数dwUser定义用户自定义的回调值该值将传递给回调函数参数uFlags定义定时类型如果要不间断的记时该值应设置为

如果函数调用成功在系统中建立了一个多媒体记时器对象每当经过一个uDelay时间后lpFunction指定的函数都会被调用同时函数返回一个对象标识如果不再需要记时器则必须要使用timeKillEvent函数删除记时器对象

由于Windows是一个多任务的操作系统因此基于API调用的记时器的精度都会受到其它很多因素的干扰到底这两中记时器的精度如何我们来使用以下的程序进行验证

设置三种记时器(Timer控件高性能频率记数多媒体记时器)将它们的定时间隔设置为毫秒让它们不停工作直到达到一个比较长的时间(比如秒)这样记时器的误差会被累计下来然后同实际经过的时间相比较就可以得到它们的精度

[] [] [] []

               

上一篇:利用Delphi建立精确计数器[2]

下一篇:用DELPHI开发DirectX游戏