The New AddressOf Keyword

The AddressOf keyword is a unary operator that evaluates to the address of the procedure it precedes. This feature has been added to Visual Basic® to enable making Windows® API calls and calls to functions in other DLLs that expect to receive a function pointer as a procedure parameter.
       Normally, when a procedure name appears in an argument list, the procedure is evaluated and the address of the procedure's return value is passed. AddressOf permits the address of the procedure, rather than its return value, to be passed to a DLL. The called function can then use the address to call the Visual Basic procedure, a process known as a callback—functions called automatically by Windows in response to certain predefined events. These events include timer messages, window messages, dialog box messages, and font enumeration notifications. This means that you can now write callback functions in Visual Basic.
       Although you can use AddressOf to pass function pointers among Visual Basic procedures, you cannot call a function through such a pointer from within Visual Basic. Therefore, a class written in Visual Basic cannot make a callback to its controller using such a pointer. When using AddressOf to pass a procedure pointer among procedures within Visual Basic, the parameter of the called procedure must be typed As Long. When using AddressOf to pass a procedure pointer to an API function, the procedure address argument must be declared As Any in the Declare statement. The AddressOf operator appears only in the call and not in the Declare statement. Note that AddressOf only works on procedures stored in standard modules.
       Here is some Visual Basic code that uses a callback function. It calls the Win32® API function EnumChildWindows to display a list of all child window handles.


 ' Make Sub Main the startup and put this code in a 
 ' standard module.
 Option Explicit
 
 Declare Function GetActiveWindow Lib "User32" () As Long
 Declare Function EnumChildWindows Lib "User32" _
    (ByVal hWnd As Long, ByVal lpWndProc As Long, 
     _ ByVal lp As Long) As Long
 
 Sub Main()
     Dim hWnd As Long
     Dim x As Long
     hWnd = GetActiveWindow()
     If hWnd Then
         x = EnumChildWindows(hWnd, 
                             AddressOf EnumChildProc, 
                              0)
     End If
 End Sub
 
 Function EnumChildProc(ByVal hWnd As Long, 
                       _ ByVal lp As Long) As Long
     Debug.Print "Window: "; hWnd
     EnumChildProc = 1
 End Function