Here is the complete code for an accurate timer class using API functions. You can start, stop and reset the timer. It is accurate to about 10 microseconds (depending on processor). You can't use it like a timer control to generate interrupts, but it's far better than using the system tick timer for timing processes.
Once you've used this method for a bit you won't want to go back!
Put this in as a class module and then create as many independent timers as you need.
Private Declare Function QueryPerformanceFrequencyAny Lib "kernel32" Alias _
"QueryPerformanceFrequency" (lpFrequency As Any) As Long
Private Declare Function QueryPerformanceCounterAny Lib "kernel32" Alias _
"QueryPerformanceCounter" (lpPerformanceCount As Any) As Long
Private mStartTime As Currency
Private mEndTime As Currency
Private mTotalTime As Double
Private mFrequency As Currency
Private mRunning As Boolean
Private mDuration As Double
Private Sub Class_Initialize()
' measure the frequency of the counter-timer
' ensure the computer is compatible
If QueryPerformanceFrequencyAny(mFrequency) = 0 Then
Err.Raise 1001, , "Hardware out of date!"
mFrequency = 0
Exit Sub
End If
End Sub
Public Sub StartTimer()
QueryPerformanceCounterAny mStartTime
mRunning = True 'used in Duration property
End Sub
Public Sub StopTimer()
mTotalTime = mDuration 'transfer cumulative time so far to module-level variable
mRunning = False 'no longer running
End Sub
Public Sub ResetTimer()
If mRunning Then
StartTimer
End If
mTotalTime = 0# 'only used when in stopped condition
End Sub
Public Property Get Duration() As Double
Dim Interval As Double
If mFrequency = 0 Then
Err.Raise 1002, , "Accurate timer object not initialised"
Duration = 0
Exit Property
End If
If mRunning Then
QueryPerformanceCounterAny mEndTime 'get a new endtime
Interval = CDbl(mEndTime - mStartTime) / mFrequency
mDuration = mTotalTime + Interval 'the stored total so far plus the new addition
Else
mDuration = mTotalTime 'not running - return cumulative
End If
Duration = mDuration
End Property