NOTE: Some of the content of this tutorial assumes you know how pointers work in VB. This is covered by my tutorial "Tips & Tricks - Visual Basic and Pointers"
We're living in a C++ world with C++ documentation all over the place. Unfortunately, references for VB syntax for calling API's and their structures and constants are hard to find with the exception of
www.allapi.net - but even they have stopped updating.
So what do you do if you can't find the VB syntax for some API or structure? Well, you gotta use the only thing that's out there. C documenation.
But first, we need to know the VB datatypes really well. So here's the important ones.
Byte = 1 byte unsigned number (0 to 255)
Integer = 2 byte signed number (-32768 to 32767)
Boolean = 2 bytes. (-1 TRUE, 0 FALSE)
Long = 4 byte signed number (-2147483648 to 2147483647)
Single = 4 byte signed number
Double = 8 byte signed number
Now here's some common C datatypes
BYTE = 1 byte unsigned number
USHORT = 2 byte unsigned number
SHORT = 2 byte signed number
UINT = 4 byte unsigned number
INT = 4 byte signed number (on 32-bit systems)
BOOL = 4 byte signed number (on 32-bit systems)
now keep in mind that in a 32-bit system, you're going to have 32-bit handles and mostly 32-bit numbers in your API functions and structures. So the LONG datatype will be the most common. For instance, all the below types are 4 byte numbers. A VB long type works fine.
HACCEL, HANDLE, HBITMAP, HBRUSH, HCONV, HCONVLIST, HCURSOR, HDC, HDDEDATA, HDESK, HDROP, HDWP, HENHMETAFILE, HFILE, HFONT, HGDIOBJ, HGLOBAL, HHOOK, HICON, HIMAGELIST, HIMC, HINSTANCE, HKEY, HKL, HLOCAL, HMENU, HMETAFILE, HMODULE, HMONITOR, HPALETTE, HPEN, HRGN, HRSRC, HSZ, HWINSTA, HWND
Alright, with the above in mind. Let's convert a function from C to VB syntax. Let's say we wanna create a window with CreateWindowEx. goto msdn.microsoft.com. See the 'Search For' text box? Type 'CreateWindowEx' in there and press Enter. You'll get several results. The first 3 entries look good. Let's choose the top one.
Before we get into the conversion process, start the API functon line and we'll add to it as we go.
Declare Function CreateWindowEx Lib "" () As something
Scrolling down the the bottom of the page, we see that is says we need to import user32.lib. That's the clue we needed to know what dll the function is stored in. Add that in.
Declare Function CreateWindowEx Lib "user32.dll" () As something
The second thing is to be sure we have the correct name. You see, many functions in windows has a ANSI and UNICODE version. ANSI is where each character takes 1 byte. And in UNICODE each character takes 2 bytes. WIDE is another name for UNICODE. So we need to make sure the function isn't REALLY called CreateWindowExA (for ANSI) or CreateWindowExW (for WIDE).
There's 2 ways to be sure. 1, this MSDN page says there's a ANSI and WIDE version. 2, you can open user32.dll in wordpad and do a string search for CreateWindowEx. You'll see if it'll require a W or A. All function names can be looked at in a dll like this.
Well, now I want to use the ANSI version, so I format my declare line like this.
Declare Function CreateWindowEx Lib "user32.dll" Alias "CreateWindowExA" () As something
An alias is the TRUE name contained in the dll. CreateWindowEx is what we'll be using in our code.
HWND CreateWindowEx(
DWORD dwExStyle,
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
woof, what a mess. Let's take this line by line. The first line says "HWND CreateWindowEx(". That means CreateWindowEx returns a HWND datatype. We know this to be a LONG 4 byte number. So instead of 'As something', you put 'as long'
Declare Function CreateWindowEx Lib "user32.dll" Alias "CreateWindowExA" () As Long
DWORD dwExStyle; = dwExStyle As Long
DWORD dwStyle, = dwStyle As Long
DWORD stands for Double Word. A Word is 2 bytes. So we need a 4 byte LONG number.
LPCTSTR lpClassName, = lpClassName As String
LPCTSTR lpWindowName, = lpWindowName As String
LP stands for Long Pointer. C is for constant. and a TSTR is compatible in C for either ANSI or UNICODE. All that complexity simply means it's a string in VB. However, it is important to know that the function expects a POINTER to the string. (see: Tips & Tricks - Visual Basic and Pointers)
int x, = X As Long
int y, = Y As Long
int nWidth, = nWidth As Long
int nHeight, = nHeight As Long
On a 32-bit system, an INT is a 32-bit value. That's yet another 4 byte type translated to visual basic's LONG.
HWND hWndParent, = hWndParent As Long
HMENU hMenu, = hMenu As Long
HINSTANCE hInstance, = hInstance As Long
We've got three more types all starting with H. That means they're handles. On a 32-bit system, handles are 32-bit values. So many types which all translate to a simple LONG in VB.
LPVOID lpParam = lpParam As Any
Now here's something you don't see everyday. Once again LP stands for Long Pointer. However, the VOID means it could be anything. It could be a pointer to a string, a number, or a structure. The specialized type 'Any' is only used in these API's. This is the only type which you don't want the 'ByVal' keyword before the argument. On all those other arguments, we want the VALUE of the variables we provide to the function. In this case, we want the POINTER to the variable. Below is the finished declaration statement.
Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
The MSDN is also great for looking up structures. Structures are the 'Type' statements you rarely need in Visual Basic unless you're working with the API. Here's a structure in both C and VB format.
struct WSAData {
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYSSTATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
};
Here we see a few more different types. Remember when I said a WORD is 2 bytes? That means you'll want Integers for those. A char is a string, but NOT a pointer to a string like we had before. This is a fixed length string. unsigned shorts (USHORT) are also 2 byte values or again - Visual Basic integers. char FAR * - I have no earthly idea. char makes it seem like it's a string, but it's not. lpVendorInfo clues us in that it's a Long pointer - hence a Visual Basic LONG. Just like handles, all pointers in a 32-bit system are 4 bytes.
Here's the Visual Basic version:
Type WSADATA
wVersion As Integer
wHighVersion As Integer
szDescription As String * WSA_DescriptionSize
szSystemStatus As String * WSA_SysStatusSize
iMaxSockets As Integer
iMaxUdpDg As Integer
lpVendorInfo As Long
End Type
Well, that's all I have to say about that. WSA_DescriptionSize and WSA_SysStatusSize are numerical constants. To get constant values you must download API-Viewer from
www.allapi.net - or do a text search through C HEADER files to get the values of the constants. MSDN doesn't give them to you.
Once again, if there's any questions, or you want me to convert a mysterious API or structure to VB syntax - feel free to reply.