Jalaj P. Jha Technical & Miscellaneous Ramblings

9Feb/071

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.

Comments (1) Trackbacks (4)
  1. Nice work, Explained very well and was very helpful for my project and I posted it to my blog too. Thanks.


Leave a comment

(required)

  • Twitter
  • Buzz
  • Facebook
  • Orkut
  • Picasa
  • YouTube