WinAPI CallBack functions
You need to execute a particular piece of code when a particular criterion is met with. Worst you can do is to continuously loop to check if the criterion is met or not (thus eating up CPU time), or best see if there is a WinAPI function that can enable the system to make a CallBack to a function defined in your application as and when the criterion is met and thus enabling you to execute the code.
Windows provides a number of functions allowing CallBacks, of which, we will discuss here two the SetTimer and KillTimer.
Ever used the Timer Control provided by Visual Basic? It’s based on these two functions. Let’s take how similar effect can be achieved by using WinAPI functions instead.
The SetTimer function as defined below takes first parameter the handle to the window that’s associated with the timer to be created. The second parameter is an Identifier for the timer, passing which allows you to create more than one timer for a window and should be unique for each timer. These two parameters, however, can be by-passed by passing Null for each of them, doing which requires you to get the identifier as returned by the function otherwise you would not be able to stop the timer.
The third parameter is the time interval, in milliseconds, for which the system needs to wait before making a callback.
The fourth parameter is the pointer to the function, defined in application, which is to be called when the specified time has elapsed. You can get pointer to the function by using the VB AddressOf operator. This function should be able to receive four parameter of type long, which return handle to window associated with timer, WM_TIMER message, timer identifier and time elapsed resp, though we will not be required here to use them. The function should be necessarily Public and hence should be defined in a module.
Public Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, _
ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
The KillTimer function stops a timer created with the system. This function requires to pass two parameters the handle to the window and the Timer Identifier. If the timer was created by passing the first two parameters of SetTimer as Null then the first parameter to the KillTiemr function is to be passed Null. The second parameter, in that case, should be the identifier as returned by the system while creating the Timer.
Public Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, _
ByVal nIDEvent As Long) As Long
Create a new project and add a module to it. Add the code below to the module.
Public Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, _
ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Public Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, _
ByVal nIDEvent As Long) As Long
Public lngIden As Long
Public Function StartTimer()
lngIden = SetTimer(0, 0, 5000, AddressOf TimerCallback)
End Function
Public Function CloseTimer()
KillTimer 0, lngIden
End Function
Public Function TimerCallback(ByVal hwnd As Long, ByVal uMsg As Long, ByVal idEvent _
As Long, ByVal dwTime As Long) As Long
Dim lngRetVal As Long
lngRetVal = MsgBox("Hi its' me making a callback! Wan't me to prompt again?", _
vbExclamation + vbYesNo, "CallBack Functions")
If lngRetVal = vbNo Then
Call CloseTimer
End If
End Function
The variable lngIden in the code above is defined to enable storing the identifier that was returned by the Windows when timer was created.
The StartTimer function here creates a timer by passing first two parameters zeroes, time to be elapsed as 5000 milliseconds (5 seconds) and the pointer to the function TimerCallback which we will use to execute the code every 5 seconds.
The CloseTimer function stops the timer giving the identifier that was returned by SetTimer function.
The TimerCallback function issues a MsgBox function asking if timer needs to be continued or not. If No button is pressed the CloseTimer function is called.
The code above are just to handle the timer, however note that StartTimer function has not been called anywhere. Let’s do it in the form. Add the code below to start the timer when form loads and stop it when it unloads.
Private Sub Form_Load()
Call StartTimer
End Sub
Private Sub Form_Unload(Cancel As Integer)
Call CloseTimer
End Sub
Execute the code and see how you have enabled timer function without using a Timer control.



[...] WinAPI CallBack functions [...]
WinAPI functions consolidated « Jalaj P. Jha
December 11, 2008 at 1:10 am
Nice work, Explained very well and was very helpful for my project and I posted it to my blog too. Thanks.
Prateek
June 29, 2008 at 11:30 pm
[...] that instruct operating system to callback based on some condition. Learn about this and other WinAPI CallBack functions, Where’s TimerProc Function?, More WinAPI functions for [...]
The Blog Revisited - 5 « Jalaj
October 30, 2007 at 12:36 pm
[...] under: Visual Basic, WinAPI — Jalaj @ 4:15 am Marching ahead from the last post WinAPI CallBack functions, we will discuss here four other WinAPI functions that enables CallBacks, the EnumWindows, [...]
More WinAPI functions for CallBack « Jalaj
February 19, 2007 at 10:25 am
[...] Filed under: Visual Basic, WinAPI — Jalaj @ 7:40 am Read my last post WinAPI CallBack functions, and found no reference of TimerProc function mentioned in Microsoft’s documentation for SetTimer [...]
Where’s TimerProc Function? « Jalaj
February 19, 2007 at 9:16 am