(c) 2002 Visual Studio Magazine 
Fawcette Technical Publications

Issue: August 2002
Section: Q&A
Authors: Karl E. Peterson, Juval Lowy

VB5, VB6	Hand Class Instance to Callback
Listing 1	You can effectively pass a class instance through an API callback by declaring lParam As Any. Here, a Windows enumeration is initiated in a BAS module, when a class module passes a reference to itself to the public StartEnum routine. VB hands EnumWindows a pointer to this instance's class interface. EnumWindows returns the pointer through lParam to each callback, into EnumWindowsProc. VB automatically creates a new reference to the existing class instance, and calls that class's EnumWindowsProc method.

Option Explicit

Private Declare Function EnumWindows Lib _
	"user32" (ByVal lpEnumFunc As Long, _
	ByVal lParam As Any) As Long

Public Sub StartEnum(ByVal cls As CEnumWindows)
	' Pass class instance pointer to API as 
	' lParam.
	Call EnumWindows( _
		AddressOf EnumWindowsProc, cls)
End Sub

Private Function EnumWindowsProc( _
	ByVal hWnd As Long, _
	ByVal lParam As CEnumWindows) As Long
	' Pass handle to class for processing,
	' returning continue flag from class.
	EnumWindowsProc = lParam.EnumWindowsProc(hWnd)
End Function

' *** Code in associated class, called by 
' *** routine above.
' Friend Function EnumWindowsProc(_
'			ByVal hWnd As Long) As Boolean
'		' Pass handle to generic handler.
'		EnumWindowsProc = WindowHandler(hWnd)
' End Function


VB5, VB6	Hand Interface to Callback
Listing 2	You can route callbacks to any number of object types by implementing a generic callback interface within your objects. These dispatching routines are different from those in Listing 1 in that they use a secondary interface exposed by the initiating class. The class that calls StartEnum doesn't have to do anything different in this case, as VB "magically" uses the specified interface and doesn't care about the base type at all.

Option Explicit

Private Declare Function EnumWindows Lib _
	"user32" (ByVal lpEnumFunc As Long, _
	ByVal lParam As Any) As Long

Public Sub StartEnum( _
	ByVal cls As IEnumWindowsSink)
	' Pass interface pointer to API as lParam.
	Call EnumWindows( _
		AddressOf IEnumWindowsProc, cls)
End Sub

Private Function IEnumWindowsProc( _
	ByVal hWnd As Long, _
	ByVal lParam As IEnumWindowsSink) As Long
	' Pass handle to interface for processing,
	' returning continue flag from class.
	IEnumWindowsProc = _
		lParam.EnumWindowsProc(hWnd)
End Function

' *** Code in associated interface, called by 
' *** routine above.
' Friend Function _
' IEnumWindowsSink_EnumWindowsProc( _
' ByVal hWnd As Long) As Boolean
'		' Pass handle to generic handler.
'		IEnumWindowsSink_EnumWindowsProc = _
' 			WindowHandler(hWnd)
' End Function
