GetTickCount()和GetCurrentTime()都只精確到55ms(1個tick就是55ms)。如果要精確到毫秒,應該使用timeGetTime函數或QueryPerformanceCounter函數。具體例子可以參考QA001022 "VC++中使用高精度定時器"、QA001813 "如何在Windows實現准確的定時"和QA004842 "timeGetTime函數延時不准"。
操作系統: Win2000
編程工具: VB6
問題: 我利用timeGetTime函數,做了一個延時函數,如下:
Private Sub DelayTime(ByVal DelayNum As Long)
Dim StartTime As Double, TmpTime As Single
StartTime = timeGetTime
Do
TmpTime = timeGetTime
If TmpTime < StartTime Then StartTime = TmpTime
Loop Until (TmpTime - StartTime) >= DelayNum
End Sub
但是,延時不准!有時候有10幾毫秒的誤差!請問我的程序寫的有問題嗎?如何改正?
水平: 中級(王輝)
雖然timeGetTime返回值的單位是1ms,但實際上它的精度只有10ms左右。
如果想提高精度,可以使用QueryPerformanceCounter和QueryPerformanceFrequency。這兩個函數不是在每個系統中都支持。對於支持它們的系統中,可以獲得低於1ms的精度。Windows 內部有一個精度非常高的定時器, 精度在微秒級, 但不同的系統這個定時器的頻率不同, 這個頻率與硬件和操作系統都可能有關。利用 API 函數 QueryPerformanceFrequency 可以得到這個定時器的頻率。利用 API 函數 QueryPerformanceCounter 可以得到定時器的當前值。根據要延時的時間和定時器的頻率, 可以算出要延時的時間定時器經過的周期數。在循環裡用 QueryPerformanceCounter 不停的讀出定時器值, 一直到經過了指定周期數再結束循環, 就達到了高精度延時的目的。例如:
Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
' DelayNum為延時的毫秒數
Private Sub DelayTime(ByVal DelayNum As Long)
Dim Ctr1, Ctr2, Freq As Currency
Dim Count As Double