Public Sub MySleep(Delaytm&)
Dim Starttm as long
Starttm = Left(Right(Format(Now, "MMDDHHMMSS"), 4), 2) * 3600+ Left(Right(Format(Now, "MMDDHHMMSS"), 4), 2) * 60 + Right(Format(Now, "MMDDHHMMSS"), 2)
Do
DoEvents
Loop Until (Left(Right(Format(Now, "MMDDHHMMSS"), 4), 2) * 3600+ Left(Right(Format(Now, "MMDDHHMMSS"), 4), 2) * 60 + Right(Format(Now, "MMDDHHMMSS"), 2)- Starttm) > Delaytm
End Sub
虽然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
If QueryPerformanceFrequency(Freq) Then
QueryPerformanceCounter Ctr1
Do
QueryPerformanceCounter Ctr2
Loop While (Ctr2 - Ctr1) / Freq * 1000 < DelayNum
Else
MsgBox "不支持高精度计数器!"
End If
End Sub
Private Declare Function GetTickCount& Lib "kernel32" ()
Private WithEvents Timer1 As Timer
Dim Starttm&, Settime&
Private Sub Form_Load()
Set Timer1 = Controls.Add("VB.Timer", "Timer1")
Timer1.Interval = 100
Timer1.Enabled = False
End Sub
Private Sub Command1_Click()
Starttm = GetTickCount
Settime = 5
Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
Me.Caption = CStr(Int((GetTickCount - Starttm) \ 1000)) & " 秒"
If Val(Me.Caption) >= Settime Then MsgBox "计时终止!": Timer1.Enabled = False
End Sub