Retrieving Error Information Following DLL Function Calls

Run-time errors that occur in DLL functions behave differently from run-time errors in Microsoft® Visual Basic® for Applications (VBA) in that no error message box is displayed. When a run-time error occurs, the DLL function returns some value that indicates an error occurred, but the error does not interrupt VBA code execution.

Some functions in the Microsoft® Windows® API store error information for run-time errors. If you are programming in C or C++, you can use the GetLastError function to retrieve information about the last error that occurred. From VBA, however, GetLastError might return inaccurate results. To get information about a DLL error from VBA, you can use the LastDLLError property of the VBA Err object. The LastDLLError property returns the number of the error that occurred.

Note   To use the LastDLLError property, you must know which error numbers correspond with which errors. This information is not available in the Win32API.txt file, but it is available free of charge in the Microsoft Platform SDK, available on the Microsoft® Developer Network (MSDN®) Web site at https://msdn.microsoft.com/default.asp.

The following example shows how you can use the LastDLLError property after you have called a function in the Windows API. The PrintWindowCoordinates procedure takes a handle to a window and calls the GetWindowRect function. GetWindowRect fills the RECT data structure with the lengths of the sides of the rectangle that make up the window. If you pass an invalid handle, an error occurs, and the error number is available through the LastDLLError property.

Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, _
               lpRect As RECT) As Long

Type RECT
      Left As Long
      Top  As Long
      Right  As Long
      Bottom As Long
End Type

Const ERROR_INVALID_WINDOW_HANDLE   As Long = 1400
Const ERROR_INVALID_WINDOW_HANDLE_DESCR As String = "Invalid window handle."

Sub PrintWindowCoordinates(hwnd As Long)
   ' Prints left, right, top, and bottom positions of a window in pixels.
   
   Dim rectWindow As RECT
   
   ' Pass in window handle and empty the data structure.
   ' If function returns 0, an error occurred.
   If GetWindowRect(hwnd, rectWindow) = 0 Then
      ' Check LastDLLError and display a dialog box if the error 
      ' occurred because an invalid handle was passed.
      If Err.LastDllError = ERROR_INVALID_WINDOW_HANDLE Then
         MsgBox ERROR_INVALID_WINDOW_HANDLE_DESCR, _
            Title:="Error!"
      End If
   Else
      Debug.Print rectWindow.Bottom
      Debug.Print rectWindow.Left
      Debug.Print rectWindow.Right
      Debug.Print rectWindow.Top
   End If
End Sub

To get the coordinates for the active window, you can return the handle of the active window by using the GetActiveWindow function and pass that result to the procedure defined in the previous example. To use GetActiveWindow, include the following Declare statement:

Declare Function GetActiveWindow Lib "user32" () As Long

In the Immediate window, type the following:

? PrintWindowCoordinates(GetActiveWindow)

To generate an error message, call the procedure with a random long integer.

See Also

Calling DLL Functions | Argument Data Types | Returning Strings from DLL Functions | Passing User-Defined Types | Using the Any Data Type