Interpreting CStyle Declarations

The MSDN library is the best source for information about the functions in the Windows API, but it's primarily targeted toward C and C++ programmers and displays the function declarations using C notation. The API viewer mentioned in the previous section contains many of the declarations for the core Windows functions in VBA notation, but if you encounter a function that it does not include, it is usually possible to convert the C notation to a VBA Declare statement, using the following method.

The declaration shown in MSDN for the GetTempPath function (at

http://msdn.microsoft.com/library/en-us/fileio/fs/gettemppath.asp) is:

DWORD GetTempPath(

DWORD nBufferLength, LPTSTR lpBuffer

This should be read as:

<Return data type> <Function name>(

<Parameter data type> <Parameter name>, <Parameter data type> <Parameter name>

Rearranging the C-style declaration to a VBA Declare statement gives the following (where the C-style DWORD and LPSTR are converted to VBA data types later):

Declare Function <Our Name> Lib "???" Alias "GetTempPath"

( _

nBufferLength As DWORD, _

lpBuffer As LPTSTR _

) As DWORD

On the Windows platform, there are two types of character sets. The ANSI character set has been the standard for many years and uses one byte to represent one character, which only gives 255 characters available at any time. To provide simultaneous access to a much wider range of characters (such as Far Eastern alphabets), the Unicode character set was introduced. This allocates two bytes for each character, allowing for 65,535 characters.

To provide the same functionality for both character sets, the Windows API includes two versions of all the functions that involve strings, denoted by the A suffix for the ANSI version and W for the Unicode (or Wide) version. VBA always uses ANSI strings, so you will always use the A version of the functions—in this case GetTempPathA. The C-style declarations also use different names for their data types, which you need to convert. Though not an exhaustive list, the following table shows the most common data types.

C Data Type

VBA Declaration

BOOL

ByVal <Name> As Long

BYTE

ByVal <Name> As Byte

BYTE *

ByRef <Name> As Byte

Char

ByVal <Name> As Byte

char huge *

ByVal <Name> As String

char FAR *

ByVal <Name> As String

char NEAR *

ByVal <Name> As String

DWORD

ByVal <Name> As Long

HANDLE

ByVal <Name> As Long

HBITMAP

ByVal <Name> As Long

HBRUSH

ByVal <Name> As Long

HCURSOR

ByVal <Name> As Long

HDC

ByVal <Name> As Long

HFONT

ByVal <Name> As Long

HICON

ByVal <Name> As Long

HINSTANCE

ByVal <Name> As Long

HLOCAL

ByVal <Name> As Long

HMENU

ByVal <Name> As Long

HMETAFILE

ByVal <Name> As Long

HMODULE

ByVal <Name> As Long

HPALETTE

ByVal <Name> As Long

HPEN

ByVal <Name> As Long

HRGN

ByVal <Name> As Long

HTASK

ByVal <Name> As Long

C Data Type

VBA Declaration

HWND

ByVal <Name> As Long

Int

ByVal <Name> As Long

int FAR *

ByVal <Name> As Long

LARGE INTEGER

ByVal <Name> As Currency

LONG

ByVal <Name> As Long

LPARAM

ByVal <Name> As Long

LPCSTR

ByVal <Name> As String

LPCTSTR

ByVal <Name> As String

LPSTR

ByVal <Name> As String

LPTSTR

ByVal <Name> As String

LPVOID

ByRef <Name> As Any

LRESULT

ByVal <Name> As Long

UINT

ByVal <Name> As Integer

UINT FAR *

ByVal <Name> As Integer

WORD

ByVal <Name> As Integer

WPARAM

ByVal <Name> As Integer

Other

Probably a user-defined type, which you need to define.

Some API definitions on the MSDN also include the IN and OUT identifiers. If the VBA type is shown in the table as ByVal <Name> As Long, it should be changed to ByRef... for the OUT parameters.

Strings are always passed ByVal (by value) to API functions. This is because VBA uses its own storage mechanism for strings, which the C DLLs do not understand. By passing the string ByVal, VBA converts its own storage structure into one that the DLLs can use.

Putting these into the declaration gives:

Declare Function GetTempPath Lib "???" _ Alias "GetTempPathA" ( _ ByVal nBufferLength As Long, _ ByVal lpBuffer As String _ ) As Long

The only thing that the declaration doesn't tell you is the DLL that contains the function. Looking at the bottom of the MSDN page, the Requirements section includes the lines:

DLL: Requires kernel32.dll

This tells you that the function is in the file kernel32.dll, giving the final declaration of:

Declare Function GetTempPath Lib "kernel32.dll" _ Alias "GetTempPathA" ( _ ByVal nBufferLength As Long, _ ByVal lpBuffer As String _ ) As Long

This is the same as that shown in the API viewer, which should be your first reference point for all API function definitions. Note that the Alias clause is not required when the function name is the same as the alias (typically when there are no String parameters), and is automatically removed when the function is copied into a code module.

Warning: Using an incorrect function declaration is likely to crash Excel. When developing with API calls, save your work regularly.

0 0

Post a comment