As a programmer you might never have to use a Windows API, The fact is that serious programmers use API all the time. When they need to do something that VB cannot handle, they turn to the Windows API! The API are procedures that exist in files on your PC which you can call from within your VB program - and there are thousands of them!. Written by Microsoft, debugged by tens of thousands of users, and available for free with Windows - the API are one of the very best tools you have available to add power to your VB application.

API - Application Programmer's Interface

When Microsoft wrote Windows they put a huge amount of code into procedure libraries which programmers can access. No matter which language you're using (VB, C++, ...) you can use the Windows API to greatly expand the power of your application.

There are a lot of Windows programs whose code is spread across multiple files. The .EXE file does not always contain all of the code that a programmer might use. For example, by creating his own library of procedures (usually in the form of a file with a .DLL extension) a programmer can allow more than one of his applications to access the same code.

Microsoft does a similar thing with Windows. There are many files which have code that you can access, but the three most often named files are:

Later, I'll bring up some of the other files whose procedures you might want access. However, there are some key issues that you should note before making a decision to use an API call.

Version Compatibility
Microsoft has long been known to update it's files without much fanfare - read that as without telling anyone about it until it's already happened! And often, the updated code may not perform exactly as did the older version. Users often find this out by seeing unexected errors or by having their system crash and/or lock up on them! In VB5 there were a huge number of programmer's who got bit by this problem.

If you stick with the basic 3 OS files listed above, you won't see to much of this. But the further away you go from the main 3 files, the more likely you are to get into code which hasn't seen the testing and improvement cycle that the main Windows OS files have gone through.

File Size
One of the very major downsides to the concept of API is that all of this great code lives in some very big files! Worse yet, sometimes the API you want are spread over multiple files and you may be using only one or two procedures from enormous files which have hundreds of procedures in them. Where this becomes a problem is in a)load time - where it can takes several seconds to load the procedure libraries, and b) - where you want to distribute your application and in order to make sure that all of the procedure libraries are on your user's machine, you have to put all of them into the distribute files. This can add many megabytes of files to your distribution applications. It is a major problem for distribution of software over the net, where 5 minutes per megabyte can deter a usage from trying out an application just because he doesn't want to wait for the download! 

Documentation
Finding the documentation of what procedures are in a library and how to use them can be very difficult. On my PC I have 3,380 files with a .DLL extension with a total size of 539MB. That's a lot of code! Unfortunately I can count on one hand the pages of documentation that I have to tell me what that code is or does! You'll learn how to use DLLs in this tutorial, but without the documentation from the creator of the DLLs you cannot use them successfully.

Despite these problems, the powerful magic of the API is that they are code that you don't have to write. If you've read my Beginner's section you know that I am a big fan of using 3rd party software to lighten my own programming load. As with 3rd party controls, the API provide procedures which someone else wrote, debugged, and made available for you to benefit from. In the Windows DLLs files, there are literally thousands of procedures. The key to API programming is learning which of these procedures are useful and which ones you are unlikely to ever need! This tutorial tries to address just that problem.

Getting Started It's actually simpler than you might imagine. By now, you've already written procedures for your own VB programs. Using procedures from other files is almost exactly the same as using procedures from within your own program.

The one big difference is that you must tell your application which file the procedure is contained in. To do so, you must put 1 line of code into your VB program. And, you have to do this for every external procedure that you plan to use. I suppose it would be nice for VB to have the ability to find the procedures for you - but you can see that searching through the 3,380 procedures on my PC might slow my applications down a lot!

Ok, let's get to an example. Telling VB about the procedure you want to use is known as "declaring" the procedure, and (no surprise) it uses a statement which starts with the word declare. Here's what a declaration looks like:

Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags as Long, ByVal dwReserved as Long) as Long

Let's take about the parts of the declaration statement:

The biggest issue that VB programmers would see in this case is that any unsaved code will be lost!. So remember the rule when using API - save often!

Because many of the DLLs you will use have been debugged extensively you probably won't see many cases where the DLL crashes because of programming bug. Far more frequently VB programmers will see a crash because they passed arguments to the procedure which the procedure could not handle! For example, passing a string when an integer was needed will likely crash the system. The DLLs don't include extensive protection in order to keep their own code size small and fast.

It is simple to say that if you pass the correct type of argument, that you won't see API crashes. However, the documentation is not always clear exactly what argument type is needed, plus when writing code it is all too common to simply make a mistake!

Finally, it is the case that most of the DLLs you'll want to use were written in C++. The significance of this is that the data types in C++ do not map cleanly into the data types that are used in Visual Basic. Here are some of the issues which you need to be aware of:

Okay, stay with me just a bit longer and we'll get into the actual use of some API. But first, here is a list of other DLLs which have procedures that could be of use to you. These DLLs will show up later in this tutorial when we get to the API which I recommend that you consider for use in your own applications.

Often, the documentation that you might find for an API will be written for a C++ programmer. Here's a short table which helps you translate the C++ variable type declaration to its equivalent in Visual Basic:

ATOM

ByVal variable as Integer

BOOL

ByVal variable as Long

BYTE

ByVal variable as Byte

CHAR

ByVal variable as Byte

COLORREF

ByVal variable as Long

DWORD

ByVal variable as Long

HWND

ByVal variable as Long

HDC

ByVal variable as Long

HMENU

ByVal variable as Long

INT

ByVal variable as Long

UINT

ByVal variable as Long

LONG

ByVal variable as Long

LPARAM

ByVal variable as Long

LPDWORD

variable as Long

LPINT

variable as Long

LPUINT

variable as Long

LPRECT

variable as Type any variable of that User Type

LPSTR

ByVal variable as String

LPCSTR

ByVal variable as String

LPVOID

variable As Any use ByVal when passing a string

LPWORD

variable as Integer

LPRESULT

ByVal variable as Long

NULL

ByVal Nothing or ByVal 0& or vbNullString

SHORT

ByVal variable as Integer

VOID

Sub Procecure not applicable

WORD

ByVal variable as Integer

WPARAM

ByVal variable as Long

We're not quite ready to get into using the API. Here is a scattering of issues/comments about using API which you will want to be aware of:

Which API Should I Use?
Finally we get to the good part. First the bad news, then the good news. In this section I do not provide code that you can simply copy into your own applications. The good news is that I provide a list of features that you might want to incorporate into your own application and then tell you which of the API to use. For the purposes of this relatively short tutorial, the best I can do is to point you off in the right direction!

So, here's the list:

 

Play sound

Declare Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName as string, ByVal uFlags as Long) as Long
Result = sndPlaySound (SoundFile, 1)

 

 

SubClassing

Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc as Long, ByVal hwnd as Long, byval msg as long, byval wParam as long, byval lParam as Long ) as long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

 

 

Run associated EXE

Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

 

 

List window handles

Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long

 

 

Find prior instance of EXE

Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

 

 

Draw dotted rectangle

Declare Function DrawFocusRect Lib "user32" Alias "DrawFocusRect" (ByVal hdc As Long, lpRect As RECT) As Long

 

 

Invert colors of rectangle

Declare Function InvertRect Lib "user32" Alias "InvertRect" (ByVal hdc As Long, lpRect As RECT) As Long

 

 

Get cursor position

Declare Function GetCursorPos Lib "user32" Alias "GetCursorPos" (lpPoint As POINTAPI) As Long

 

 

Always on top

Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

 

 

Send messages to a window

Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

 

 

Find directories

Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long
Declare Function GetSystemDirectory Lib "kernel32" Alias "GetSystemDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long
Declare Function GetTempPath Lib "kernel32" Alias "GetTempPathA" (ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
Declare Function GetCurrentDirectory Lib "kernel32" Alias "GetCurrentDirectory" (ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long

 

 

Text alignment

Declare Function GetTextAlign Lib "gdi32" Alias "GetTextAlign" (ByVal hdc As Long) As Long
Declare Function SetTextAlign Lib "gdi32" Alias "SetTextAlign" (ByVal hdc As Long, ByVal wFlags As Long) As Long

 

 

Flash a title bar

Declare Function FlashWindow Lib "user32" Alias "FlashWindow" (ByVal hwnd As Long, ByVal bInvert As Long) As Long

 

 

Manipulate bitmaps

Declare Function BitBlt Lib "gdi32" Alias "BitBlt" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Declare Function PatBlt Lib "gdi32" Alias "PatBlt" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal dwRop As Long) As Long
Declare Function StretchBlt Lib "gdi32" Alias "StretchBlt" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Declare Function CreateCompatibleBitmap Lib "gdi32" Alias "CreateCompatibleBitmap" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Declare Function CreateCompatibleDC Lib "gdi32" Alias "CreateCompatibleDC" (ByVal hdc As Long) As Long

 

 

Rotate text

Declare Function CreateFontIndirect Lib "gdi32" Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long

 

 

Timing

Declare Function GetTickCount Lib "kernel32" Alias "GetTickCount" () As Long

 

 

File information

Declare Function GetFileAttributes Lib "kernel32" Alias "GetFileAttributesA" (ByVal lpFileName As String) As Long
Declare Function GetFileSize Lib "kernel32" Alias "GetFileSize" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long
Declare Function GetFullPathName Lib "kernel32" Alias "GetFullPathNameA" (ByVal lpFileName As String, ByVal nBufferLength As Long, ByVal lpBuffer As String, ByVal lpFilePart As String) As Long

 

 

Get window information

Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Declare Function GetParent Lib "user32" Alias "GetParent" (ByVal hwnd As Long) As Long

 

 

Identify window at cursor

Declare Function WindowFromPoint Lib "user32" Alias "WindowFromPoint" (ByVal xPoint As Long, ByVal yPoint As Long) As Long

 

 

Registry editing

Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As Long, ByVal lpSubKey As String) As Long
Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey As Long, ByVal lpValueName As String) As Long
Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long

 

 

Drawing functions

Declare Function MoveToEx Lib "gdi32" Alias "MoveToEx" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, lpPoint As POINTAPI) As Long
Declare Function LineTo Lib "gdi32" Alias "LineTo" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Declare Function Ellipse Lib "gdi32" Alias "Ellipse" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long

 

 

Get icon Declare

Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As Long, ByVal lpszExeFileName As String, ByVal nIconIndex As Long) As Long

 

 

Screen capture

Declare Function SetCapture Lib "user32" Alias "SetCapture" (ByVal hwnd As Long) As Long
Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, lpInitData As DEVMODE) As Long
Declare Function DeleteDC Lib "gdi32" Alias "DeleteDC" (ByVal hdc As Long) As Long
Declare Function BitBlt Lib "gdi32" Alias "BitBlt" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Declare Function ReleaseCapture Lib "user32" Alias "ReleaseCapture" () As Long
Declare Function ClientToScreen Lib "user32" Alias "ClientToScreen" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long

 

 

Get user name

Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As LongDeclare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long

 

 

Get computer name

Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As LongDeclare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long

 

 

Get volume name/serial#

Declare Function GetVolumeInformation Lib "kernel32" Alias "GetVolumeInformationA" (ByVal lpRootPathName As String, ByVal lpVolumeNameBuffer As String, ByVal nVolumeNameSize As Long, lpVolumeSerialNumber As Long, lpMaximumComponentLength As Long, lpFileSystemFlags As Long, ByVal lpFileSystemNameBuffer As String, ByVal nFileSystemNameSize As Long) As Long

 

 

Identify drive type

Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" (ByVal nDrive As String) As Long

 

 

Get free space

Declare Function GetDiskFreeSpace Lib "kernel32" Alias "GetDiskFreeSpaceA" (ByVal lpRootPathName As String, lpSectorsPerCluster As Long, lpBytesPerSector As Long, lpNumberOfFreeClusters As Long, lpTotalNumberOfClusters As Long) As Long

 

 

INI editing

Declare Function WritePrivateProfileSection Lib "kernel32" Alias "WritePrivateProfileSectionA" (ByVal lpAppName As String, ByVal lpString As String, ByVal lpFileName As String) As Long
Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long
Declare Function GetPrivateProfileInt Lib "kernel32" Alias "GetPrivateProfileIntA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal nDefault As Long, ByVal lpFileName As String) As Long
Declare Function GetPrivateProfileSection Lib "kernel32" Alias "GetPrivateProfileSectionA" (ByVal lpAppName As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long
Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

 

 

Put icon in system tray

Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias " Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Declare Function DrawEdge Lib "user32" Alias "DrawEdge" (ByVal hdc As Long, qrc As RECT, ByVal edge As Long, ByVal grfFlags As Long) As Long

 

 

Wait for program to stop

Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As SECURITY_ATTRIBUTES, lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Declare Function WaitForSingleObject Lib "kernel32" Alias "WaitForSingleObject" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Stop ctrl-alt-del

Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByRef lpvParam As Any, ByVal fuWinIni As Long) As Long

Hopefully, this section of the tutorial has sparked some excitement! You should now see that a door of tremendous proportions has been opened to you. You've begun to leave the limitations of VB behind and joined the rest of the programming community who have already been using the API for years. I hope to add quite a bit to this tutorial section so check back often over the next few weeks.