SetWaitableTimer函数非凝滞定时

  1 'clsWaitableTimer.cls  中代码
  2 
  3 Option Explicit
  4 Private Type FILETIME
  5     dwLowDateTime As Long
  6     dwHighDateTime As Long
  7 End Type
  8 
  9 Private Const WAIT_ABANDONED& = &H80&
 10 Private Const WAIT_ABANDONED_0& = &H80&
 11 Private Const WAIT_FAILED& = -1&
 12 Private Const WAIT_IO_COMPLETION& = &HC0&
 13 Private Const WAIT_OBJECT_0& = 0
 14 Private Const WAIT_OBJECT_1& = 1
 15 Private Const WAIT_TIMEOUT& = &H102&
 16 Private Const INFINITE = &HFFFF
 17 Private Const ERROR_ALREADY_EXISTS = 183&
 18 Private Const QS_HOTKEY& = &H80
 19 Private Const QS_KEY& = &H1
 20 Private Const QS_MOUSEBUTTON& = &H4
 21 Private Const QS_MOUSEMOVE& = &H2
 22 Private Const QS_PAINT& = &H20
 23 Private Const QS_POSTMESSAGE& = &H8
 24 Private Const QS_SENDMESSAGE& = &H40
 25 Private Const QS_TIMER& = &H10
 26 Private Const QS_MOUSE& = (QS_MOUSEMOVE Or QS_MOUSEBUTTON)
 27 Private Const QS_INPUT& = (QS_MOUSE Or QS_KEY)
 28 Private Const QS_ALLEVENTS& = (QS_INPUT Or QS_POSTMESSAGE Or QS_TIMER Or QS_PAINT Or QS_HOTKEY)
 29 Private Const QS_ALLINPUT& = (QS_SENDMESSAGE Or QS_PAINT Or QS_TIMER Or QS_POSTMESSAGE Or QS_MOUSEBUTTON Or QS_MOUSEMOVE Or QS_HOTKEY Or QS_KEY)
 30 
 31 Private Const UNITS = 4294967296#
 32 Private Const MAX_LONG = -2147483648#
 33 
 34 Private Declare Function CreateWaitableTimer Lib "kernel32" Alias "CreateWaitableTimerA" (ByVal lpSemaphoreAttributes As Long, ByVal bManualReset As Long, ByVal lpName As StringAs Long
 35 Private Declare Function OpenWaitableTimer Lib "kernel32" Alias "OpenWaitableTimerA" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal lpName As StringAs Long
 36 Private Declare Function SetWaitableTimer Lib "kernel32" (ByVal hTimer As Long, lpDueTime As FILETIME, ByVal lPeriod As Long, ByVal pfnCompletionRoutine As Long, ByVal lpArgToCompletionRoutine As Long, ByVal fResume As LongAs Long
 37 Private Declare Function CancelWaitableTimer Lib "kernel32" (ByVal hTimer As Long)
 38 Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As LongAs Long
 39 Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As LongAs Long
 40 Private Declare Function MsgWaitForMultipleObjects Lib "user32" (ByVal nCount As Long, pHandles As Long, ByVal fWaitAll As Long, ByVal dwMilliseconds As Long, ByVal dwWakeMask As LongAs Long
 41 
 42 Private mlTimer As Long
 43 
 44 Private Sub Class_Terminate()
 45     On Error Resume Next
 46     If mlTimer <> 0 Then CloseHandle mlTimer
 47 End Sub
 48 
 49 Public Sub Wait(MilliSeconds As Long)
 50     On Error GoTo ErrHandler
 51     Dim ft As FILETIME
 52     Dim lBusy As Long
 53     Dim lRet As Long
 54     Dim dblDelay As Double
 55     Dim dblDelayLow As Double
 56     
 57     mlTimer = CreateWaitableTimer(0True, App.EXEName & "Timer" & Format$(Now(), "NNSS"))
 58     
 59     If Err.LastDllError <> ERROR_ALREADY_EXISTS Then
 60         ft.dwLowDateTime = -1
 61         ft.dwHighDateTime = -1
 62         lRet = SetWaitableTimer(mlTimer, ft, 0000)
 63     End If
 64     
 65     dblDelay = CDbl(MilliSeconds) * 10000#
 66 
 67     ft.dwHighDateTime = -CLng(dblDelay / UNITS) - 1
 68     dblDelayLow = -UNITS * (dblDelay / UNITS - Fix(CStr(dblDelay / UNITS)))
 69     
 70     If dblDelayLow < MAX_LONG Then dblDelayLow = UNITS + dblDelayLow
 71     
 72     ft.dwLowDateTime = CLng(dblDelayLow)
 73     lRet = SetWaitableTimer(mlTimer, ft, 000False)
 74     
 75     Do
 76         lBusy = MsgWaitForMultipleObjects(1, mlTimer, False, INFINITE, QS_ALLINPUT&)
 77         DoEvents
 78     Loop Until lBusy = WAIT_OBJECT_0
 79     
 80 
 81     CloseHandle mlTimer
 82     mlTimer = 0
 83     Exit Sub
 84     
 85 ErrHandler:
 86     Err.Raise Err.Number, Err.Source, "[clsWaitableTimer.Wait]" & Err.Description
 87 End Sub
 88 
 89 'FORM中代码
 90 
 91 Private Sub cmdWaitTimer_Click()
 92     Dim objTimer As clsWaitableTimer
 93     Set objTimer = New clsWaitableTimer
 94     
 95     cmdWaitTimer.Enabled = False
 96     objTimer.Wait 5000  '5 秒
 97     cmdWaitTimer.Enabled = True
 98     Set objTimer = Nothing
 99 End Sub
100  
101 
原文地址:https://www.cnblogs.com/xxaxx/p/1635315.html