My app's external processes each poll a boolean to see if there is work to do. I now want to check that variable in a Timer
event to cut down the 'not responding' messages.
A Timer object has to be placed on a form, which seems to cause some limitations.
Launching the event from a form with Me.Show
(vbModal
) works great. Only I don't want to actually show that form, I just want to use the timer. Trying to hide the form using Me.Hide
then loses the Modal behavior which I need, so that's not a good workaround.
I tried launching the event from a class but it exhibits the same unwanted behavior as Me.Hide
: Processing returns to the caller rather than staying in the timer event sub waiting for work.
Is there any way to implement an event based on Timer
which doesn't require showing a form and does not immediately return to the caller? The external processes have no screen IO and none is desired.
You can look into using the SetTimer function from the Windows API. Add the following code in a Module and user TimerStart
with an interval in milliseconds:
Private Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Public Function TimerStart(ByVal p_lngInterval As Long) As Long
' Start timer
TimerStart = SetTimer(0, 0, p_lngInterval, AddressOf TimerCallBack)
End Function
Public Sub TimerCallBack(ByVal hwnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal dwTime As Long)
' Handle your polling here
End Sub
You do not need a Form so this should suit your needs.
You can also use Sleep from the Windows API in conjuction with Timer to keep your EXE running:
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Sub Main()
TimerStart 2000
Do While True
DoEvents
Sleep 1000
Loop
End Sub
See these other answers for more details: