AddressOf procedurename procedurename Use: Required
Passes the address of a procedure to an API function. There are some API functions that require the address of a callback function as a parameter. (A callback function is a routine in your code that is invoked by the routine that your program is calling: it calls back into your code.) These callback functions are passed to the API function as pointers to a memory address. In the past, calling functions that required callbacks posed a unique problem to VB, since, unlike C or C++, it lacks a concept of pointers. However, the AddressOf operator allows you to pass such a pointer in the form of a long integer to the API function, thereby allowing the API function to call back to the procedure.
• The callback function must be stored in a code module; attempting to store it in a class or a form module generates a compile-time error, "Invalid use of AddressOf operator."
• The AddressOf operator must be followed by the name of a user-defined function, procedure, or property.
• The data type of the corresponding argument in the API function's Declare statement must be As Any or As Long.
• The AddressOf operator can't call one VB procedure from another. Example
The following example uses the EnumWindows and GetWindowText API calls to return a list of currently open windows. EnumWindows requires the address of a callback function as its first parameter. A custom function, EnumCallBackProc, is the callback function that populates the lstWindowTitles list box.
When the cmdListWindows command button is clicked, the list box is cleared, and a call to the EnumWindows API function is made, passing the AddressOf the EnumCallBackProc function and a reference to the list box control. EnumWindows then calls back to EnumCallBackProc, passing it the window handle of an open window and the reference to the list box. EnumCallBackProc then uses the GetWindowText API function to return the text in the titlebar of the window, passing it the window handle, a string buffer, and the length of that buffer. EnumCallBackProc is called by the API function as many times as is required, depending upon the number of open windows. The first portion of the example
code must be stored in a code module, while the cmdListWindows_Click event handler can be stored in the form module containing the cmdListWindows button.
Public Declare Function EnumWindows Lib "User32" _
(ByVal lpEnumFunc As Any, _ ByVal lParam As Any) As Long
Public Declare Function GetWindowText Lib "User32" _
Alias "GetWindowTextA" _ (ByVal hWnd As Long, _ ByVal lpString As String, _ ByVal cch As Long) As Long
Function EnumCallBackProc(ByVal hWnd As Long, _
ByVal lParam As ListBox) As Long
On Error Resume Next
Dim sWindowTitle As String Dim lReturn As Long sWindowTitle = String(512, 0)
lReturn = GetWindowText(hWnd, sWindowTitle, 512)
If lReturn > 0 Then lParam.AddItem sWindowTitle End If
EnumCallBackProc = 1 End Function
Private Sub cmdListWindows_Click() Dim lReturn As Long lstWindowTitles.Clear lReturn = EnumWindows(AddressOf EnumCallBackProc, _ lstWindowTitles)
End Sub Programming Tips & Gotchas
• Debugging calls containing AddressOf is at best very difficult and most of the time downright impossible.
• It's possible to pass an AddressOf pointer from one VB procedure to another by creating a wrapper for the callback function. To do this, however, you must declare the pointer as either Long or Any. The following snippet shows how you could add such a wrapper function to the example used above:
122 Chapter 7- The Language Reference
Private Sub cmdListWindows_Click() Dim lReturn As Long lReturn = DoWindowTitles(AddressOf EnumCallBackProc, _
Private Function DoWindowTitles(CallBackAddr As Long, _
lstBox As ListBox) As Long
'other stuff here lstBox.Clear
DoWindowTitles = EnumWindows(CallBackAddr, lstBox) End Function
• Because you can't pass an error back to the calling Windows API function from within your VB callback function, you should use the On Error Resume Next statement at the start of your VB callback function.
Was this article helpful?