Library code snippets
A timer without a timer control
One of the most powerful and yet one of the least understood new features introduced in Visual basic version 5 was the AddressOf keyword. What this keyword does is return the loaded memory address of a function which can then be passed to any API call which requires a pointer to a function as it's parameter call.
In itself this isn't very exciting, but it does allow the Visual Basic
programmer to use one of the most powerful features in Win32 programming - the
callback.
The following example introduces this and shows one of the most simple
implementations: a timer without using the Visual basic timer control. The API
calls used in this example are:
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
The last parameter to SetTimer is defined in the API documentation as
"pointer to a TIMER PROC". This means that you need to use AddressOf
to pass the pointer and the procedure argument that this takes must be
compatible with a TIMERPROC. The C++ declaration of this is:
typedef VOID (CALLBACK* TIMERPROC)(HWND, UINT, UINT, DWORD);
Where hWnd is a LONG which uniquely identifies the window with which the timer
proc is associated. You will notice that the other parameters are defined as
UINT and DWORD - niether of which exist in Visual Basic. This is not a problem,
however, as they are the same size as the Visual Basic LONG data type.Public Sub VB_TIMERPROC(ByVal hwnd As Long, ByVal uint1 As Long, ByVal nEventId
As Long, ByVal dwParam As Long)
Because the return from this procedure is defined as a VOID, it is implemented
in visual basic as a subroutine. A word of warning - this procedure must return
to the calling program even if an error occurs. For this reason, the first line
of code is:
On Error Resume Next
I would not recommend this for any procedure which is not used in a callback,
however.
In order to start the timer running, you need to call the SetTimer API call:Dim lRet As Long
lret = SetTimer(Me.hwnd, 1, 100, AddressOf VB_TIMERPROC)
Typically I would do this in the Form_Load() code. The event id (1) uniquely
identifies this timer, and the elapse (100) is the timer interval in
milliseconds.
Before the form is unloaded, you need to unset the timer. This is done with the
KillTimer call.lret = KillTimer(Me.hwnd, 1)
And there you have it - a timer without using the timer control and a gentle
introduction to callbacks.
Related articles
Related discussion
-
Run-time error '91'
by converter2009 (1 replies)
-
VB6 Runtime error 381 subsript out of range Error
by Uncle (2 replies)
-
passing and reading parameters from using Shell
by jigartoliya (0 replies)
-
Convert C++ code to VB6
by mawcot (4 replies)
-
listbox scrollbar
by Dennijr (10 replies)
Related podcasts
-
Christian Beauclair
14 mai 2008 (�mission #0074) ::.Christian Beauclair: Stratégies de migration VB6 vers .NET Nous discutons avec Christian Beauclair des stratégies de migration VB6 vers .NET. Entre autres, nous discutons comment utiliser le "VB 6 Code Advisor" et le "Interop Forms Toolkit" pour ajouter la puiss...
Well this works great. For some reason though the kill timer routine doesnt kill the timer. Maybe I missed something. Anyone else?
This thread is for discussions of A timer without a timer control.