www.applevb.com
在Windows中的很多場合下編程(例如工業控制、游戲)中需要比較精確的記時器,本文討論的是在Delphi下實現記時器的若干方法以及它們的精度控制問題。
在Delphi中最常用的是Timer控件,它的設置和使用都非常方便,理論上它的記時精度可以達到1ms(毫秒)。但是眾所周知的,實際上Timer在記時間隔小於50ms之下是精度是十分差的。它只適用於對於精度要求不太高的場合。
這裡作者要介紹的是兩種利用Windows API函數實現精確記時的方法。第一中方法是利用高性能頻率記數(作者本人的稱呼)法。利用這種方法要使用兩個API函數QueryPerformanceFrequency和QueryPerformanceCounter。QueryPerformanceFrequency函數獲得高性能頻率記數器的震蕩頻率。
調用該函數後,函數會將系統頻率記數器的震蕩頻率(每毫秒)保存到一個LargeInteger中。不過利用該函數在幾台機器上做過試驗,結果都是1193180。讀者朋友可以在自己的機器上試一下
QueryPerformanceCounter函數獲得系統頻率記數器的震蕩次數,結果也保存到一個Largenteger中。
很顯然,如果在計時中首先使用QueryPerformanceFrequency獲得高性能頻率記數器每毫秒的震蕩次數,然後在計時開始時使用QueryPerformanceCounter函數獲得當前系統頻率記數器的震蕩次數。在計時結束時再調用QueryPerformanceCounter函數獲得系統頻率記數器的震蕩次數。將兩者相減,再將結果除以頻率記數器每毫秒的震蕩次數,就可以獲得某一事件經過的准確時間。(次數除以頻率等於時間)
另外的一種精確記時器的功能是利用多媒體記時器函數(這也是作者的定義,因為這個系列的函數是在Winmm.dll中定義並且是為媒體播放服務的)。
實現多媒體記時器首先要使用timeSetEvent函數建立計時事件。該函數在Delphi中的mmsystem.pas中有定義,定義如下:
function timeSetEvent(uDelay, uResolution: UINT;
lpFunction: TFNTimeCallBack; dwUser: DWORD; uFlags: UINT): MMRESULT; stdcall
函數定義中參數uDelay定義延遲時間,以毫秒為單位,該參數相當於Timer控件的Interval屬性。參數uResolution