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 http://msdn.microsoft.com.
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:
To generate an error message, call the procedure with a random long integer.