Create a system timer using AddressOf and a callback function

Create a system timer using AddressOf and a callback function

The Timer control is great when you want to periodically execute a piece of code while the program is doing something else. However, it also has a couple of shortcomings: (1) it requires a parent form, so you can’t use it directly inside a BAS module, and (2) it’s Interval property can’t be higher than 65,535, therefore you can’t specify a timeout longer than about 65 seconds.

You can work around both the above limitations if you directly create a system timer using the SetTimer function. When you create a timer in this way you provide the address of a callback function, a function in a BAS module that Windows will call periodically. You need the following API declares to create and then distroy a system timer:

Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, _    ByVal nIDEvent    As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) _    As LongDeclare Function KillTimer Lib "user32" (ByVal hWnd As Long, _    ByVal nIDEvent As Long) As Long

This code creates a timer that is invoked every 500 milliseconds:

Dim timerID As Long' the first two arguments must be zerotimerID = SetTimer(0, 0, 500, AddressOf Timer_CBK)

Note that you need a module-level or a global timerID variable to store the ID of the timer you create, because you must absolutely destroy the timer before the application terminates (or when you don’t need it):

' Destroy the timer created previouslyKillTimer 0, timerID

Here is an example of a timer callback routine:

' the fourth argument is the number of milliseconds elapsed ' from Windows start upSub Timer_CBK(ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, _    ByVal SysTime As Long)    ' In this example just display the system time in a label control    Form1.lblTimer = SysTimeEnd Sub

For simplicity’s sake, the above example uses this timer to display the number of milliseconds elapsed since Windows started in a Label control in a form (which is a job for which a regular Timer control is probably a better choice). In a real application you can use this technique for more interesting tasks, such as monitoring data coming from a serial port, checking your email account, watching the contents of a directory, updating program’s statistics, and more.


Share the Post: