Passing User-Defined Types

Many DLL functions require you to pass in a data structure by using a predefined format. When calling a DLL function from VBA, you pass a user-defined type that you have defined according to the function's requirements.

You can figure out when you must pass a user-defined type and which type definition you must include in your code by looking at the Declare statement for the function. An argument requiring a data structure always is declared as a long pointer: a 32-bit numeric value that points to the data structure in memory. The conventional prefix for a long pointer argument is "lp". In addition, the data type for the argument is the name of the data structure.

For example, take a look at the Declare statements for the GetLocalTime and SetLocalTime functions:

Private Declare Sub GetLocalTime Lib "kernel32" (lpSystem As SYSTEMTIME)
Private Declare Function SetLocalTime Lib "kernel32" (lpSystem As SYSTEMTIME) As Long

Both functions take an argument of type SYSTEMTIME, a data structure that contains date and time information. Here is the definition for the SYSTEMTIME type:

Private Type SYSTEMTIME
      wYear          As Integer
      wMonth         As Integer
      wDayOfWeek     As Integer
      wDay           As Integer
      wHour          As Integer
      wMinute        As Integer
      wSecond        As Integer
      wMilliseconds  As Integer
End Type

To pass the data structure to a function, you must declare a variable of type SYSTEMTIME, as in the following example:

Private sysLocalTime As SYSTEMTIME

When calling GetLocalTime, you pass a variable of type SYSTEMTIME to the function, and it fills the data structure with numeric values indicating the current local year, month, day, day of week, hour, minute, second, and millisecond. For example, the following Property Get procedure calls GetLocalTime to return a value indicating the current hour:

Public Property Get Hour() As Integer
   ' Retrieve current time, then return hour.

   GetLocalTime sysLocalTime
   Hour = sysLocalTime.wHour
End Property

When calling SetLocalTime, you also pass a variable of type SYSTEMTIME, but you first provide values for one or more of the elements of the data structure. For example, the following Property Let procedure sets the hour value for the local system time. First, it calls GetLocalTime to retrieve the most current values for the local time into the data structure, sysSystem. Then, it updates the value of the sysLocalTime.wHour element of the data structure with the value of the argument passed to the property procedure. Finally, it calls SetLocalTime, passing in the same data structure, which contains the values retrieved by GetLocalTime plus the new hour value.

Public Property Let Hour(intHour As Integer)
   ' Retrieve current time, so all values will be current,
   ' then set hour portion of local time.
   
   GetLocalTime sysLocalTime
   sysLocalTime.wHour = intHour
   SetLocalTime sysLocalTime
End Property

Note   The GetLocalTime and SetLocalTime functions are similar to the GetSystemTime and SetSystemTime functions. The primary difference is that the GetSystemTime and SetSystemTime functions express time as Greenwich Mean Time. For example, if your local time is 12:00 midnight and you live on the West Coast, Greenwich Mean Time is 8:00 A.M., an eight-hour difference. The GetSystemTime function returns the current time as 8:00 A.M., while GetLocalTime returns 12:00 midnight.

See Also

Calling DLL Functions | Argument Data Types | Returning Strings from DLL Functions | Using the Any Data Type | Retrieving Error Information Following DLL Function Calls