Visual Basic Concepts
Passing User-Defined Types to a DLL Procedure
Some DLL procedures take user-defined types as arguments. (User-defined types are referred to as "structures" in C and as "records" in Pascal.) As with arrays, you can pass the individual elements of a user-defined type the same way you would pass ordinary numeric or string variables.
You can pass an entire user-defined type as a single argument if you pass it by reference. User-defined types cannot be passed by value. Visual Basic passes the address of the first element, and the rest of the elements of a user-defined type are stored in memory following the first element. Depending on the operating system, there may also be some padding.
For example, several procedures in the operating environment DLLs accept a user-defined type for a rectangle, which has the following structure:
Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type
Two of the procedures that accept a rectangle are DrawFocusRect, which draws a dotted outline around the specified rectangle, and InvertRect, which inverts the colors of the specified rectangle. To use the procedures, place these declarations in the Declarations section of a standard module:
Declare Function DrawFocusRect Lib "User32" Alias _ "DrawFocusRect" (ByVal hdc As Long, _ lpRect As RECT) As Long Declare Function InvertRect Lib "User32" Alias _ "InvertRect" (ByVal hdc As Long, _ lpRect As RECT) As Long Dim MouseRect As RECT
Now you can use the following Sub procedures to call the DLLs:
Private Sub Form_MouseDown (Button As Integer, _ Shift As Integer, X As Single, Y As Single) ScaleMode = 3 If Button And 1 Then MouseRect.Left = X MouseRect.Top = Y MouseRect.Right = X MouseRect.Bottom = Y End If End Sub Private Sub Form_MouseUp (Button As Integer, _ Shift As Integer, X As Single, Y As Single) ScaleMode = 3 If Not (Button And 1) Then MouseRect.Right = X MouseRect.Bottom = Y InvertRect hDC, MouseRect End If End Sub Private Sub Form_MouseMove (Button As Integer, _ Shift As Integer, X As Single, Y As Single) ScaleMode = 3 If Button And 1 Then DrawFocusRect hDC, MouseRect MouseRect.Right = X MouseRect.Bottom = Y DrawFocusRect hDC, MouseRect End If End Sub
User-defined types can contain objects, arrays, and BSTR strings, although most DLL procedures that accept user-defined types do not expect them to contain string data. If the string elements are fixed-length strings, they look like null-terminated strings to the DLL and are stored in memory like any other value. Variable-length strings are incorporated in a user-defined type as pointers to string data. Four bytes are required for each variable-length string element.
*Note* When passing a user-defined type that contains binary data to a DLL procedure, store the binary data in a variable of an array of the Byte data type, instead of a String variable. Strings are assumed to contain characters, and binary data may not be properly read in external procedures if passed as a String variable.