How To Get Started Programming with the Windows API (LONG)

This article was previously published under Q190000
This article has been archived. It is offered "as is" and will no longer be updated.
This article demonstrates how to get started calling functions in theWindows Application Programming Interface (Windows API) in your VisualBasic projects. This article assumes you are familiar with using VisualBasic but have never used it to call the functions in the Windows API.
Although Visual Basic has an extensive list of statements, methods, events,and procedures to help you create a Windows program quickly and easily,there are limitations within the development environment that may preventyou from implementing your ideas. One way to go beyond these limitations isto call the Windows API from within your Visual Basic project. At the heartof the Windows operating system are the functions that make up the WindowsAPI. The majority of these functions are accessible from Visual Basicprograms.

The following topics are covered in this article:
  • What is the Windows API? - A brief overview of the Windows Application Programming Interface.
  • Why Use the Windows API? - Explains the advantages of calling Windows API functions in addition to using the functions, methods, and procedures provided by Visual Basic.
  • How to call a Windows API function - The details of calling a function from a Visual Basic program.
  • Sample Project - Shows how to create your first Visual Basic project that calls two functions in the Windows API.
  • Tips - Some tips and tricks to make Windows API programming easier.
  • Where to go from here? - additional resources and articles on the topics of using the Windows API with Visual Basic.

What is the Windows API?

If you look at the Windows System directory, typically \Windows\Systemunder Window 95/98 and \Winnt\System32 under Windows NT, you will find anumber of Dynamic Link Library (.DLL) files. These files contain functionsthat are used to run the operating system and to ensure a consistent userinterface and operating environment. These files make up the Windows API.

The purpose of the Windows API is to allow you to develop programsconsistent with the Windows operating system and user interface. Instead ofindividuals writing the code to create components of the Windows operatingsystem, such as forms, command buttons, and menus, you can call theappropriate functions in the Windows API and let the operating systemcreate those components.

The purpose of each function in the Windows API is documented in thePlatform Software Development Kit (SDK). The Platform SDK is shipped withMicrosoft Visual C++ and as part of a subscription to the MicrosoftDeveloper Network (MSDN.)

You can also download the Platform SDK from the following Microsoft Web site:As with any other Windows program, Visual Basic uses the functions in theWindows API. When you perform a task in Visual Basic, such as adding acommand button to a form, Visual Basic calls the appropriate functions toperform the task. The features of Visual Basic are wrappers to thesefunctions.

Why Use the Windows API?

The reason why you would use the Windows API is to perform a task beyondwhat is available from Visual Basic. For example, you cannot determine orset the cursor blinking rate through any statement, property, procedure, ormethod in Visual Basic. You can get the blink rate by calling theGetCaretBlinkTime function, which returns the cursor blink rate inmilliseconds. If you want to set the cursor to blink at another rate underspecified conditions, you can call the SetCaretBlinkTime function, passingthe specified time in milliseconds.

You can get the same functionality as almost any of the features of VisualBasic by calling the appropriate Windows API functions. However, callingthese functions directly is typically more complicated and can causeunpredictable behavior if not done correctly, resulting in system errors.For the best performance and predictable behavior, you should use theintrinsic Visual Basic functionality.

How to Call a Windows API Function

There are two steps required to call a Windows API function:
  • Declare the function in a module or form.
  • Call the function in your program as you would any other function.
The topic "Declaring a DLL Procedure" in "Part 4 Accessing DLLs and theWindows API" of the "Visual Basic Component Tools Guide" explains how todeclare a function in a module. The topic also shows how to use the APIText Viewer to find the appropriate declaration and copy and paste thedeclaration to your project.

For example, to declare the GetCaretBlinkTime function in a module, copythe following text to the code window of your module:
Declare Function GetCaretBlinkTime Lib "user32" Alias _                 "GetCaretBlinkTime" () As Long				
If you want to use the same function only in a specific form, add thekeyword "Private" to the beginning of the function declaration. TheGetCaretBlinkTime function declaration is written in the code window of aform as follows:
Private Declare Function GetCaretBlinkTime Lib "user32" Alias _                         "GetCaretBlinkTime" () As Long				
This function returns a Long value that is the cursor blink rate inmilliseconds. The Lib keyword precedes the name of the file that containsthe function; in this case, User32.DLL. The Alias keyword is used to definethe specific function in the DLL file. This clause is optional when thefunction is being declared with the same name as in the DLL.

You will often see the Private notation used in Microsoft Knowledge Basearticles because not using a module streamlines the implementation of thesample code. If you need to use a Windows API function in more than onesource file in a project, it should be declared in a module.

For more information about the Declare statement, see "Declare Statement"in the Language Reference in Books Online.

Once you have declared the function, you can call it as you would anyVisual Basic function and a pass any appropriate parameters. The followingexample shows how to call the GetCaretBlinkTime function:
Dim lngCaretBlinkTime as Long   ' Blink Rate variable   lngCaretBlinkTime =  GetCaretBlinkTime				
For functions that require parameters, you can pass parameters by referenceor by value.

A parameter passed by reference passes the 32-bit address of the locationwhere the value is stored. By default, Visual Basic passes parameters byreference. You can also explicitly pass parameters by reference using theByRef keyword.

The values of parameters passed by reference can be changed in the calledprocedure. For example, the InvertRect function inverts a specifiedrectangle by inverting the value of each pixel. The function requires thehandle to the device context containing the rectangle and the address of auser defined type (UDT) variable with the logical coordinates of therectangle. The address of the user defined variable is passed by reference.

When you call this function, the logical coordinates of the rectangle areplaced in the user defined variable.

To use this function, add the following declarations to a module:
   Public Type RECT      Left As Long      Top As Long      Right As Long      Bottom As Long   End Type   Declare Function InvertRect Lib "user32" Alias "InvertRect" _   (ByVal hdc As Long, ByRef lpRect As RECT) As Long				
The first declaration specifies a user defined type required for aparameter of the InvertRect function while the second declaration is forthe function.

Passing a parameter by value sends the actual value of the parameter to thefunction. You pass a parameter by value if the parameter is not changed bythe called procedure. To pass a parameter by value, add the ByVal keywordto each parameter you want to pass to the function.

NOTE: When you pass a string variable to an API call, you actually pass the memory address of the string, so you should always pass string parameters as ByVal. If you pass a string parameter by reference, you pass the memory address containing the memory address of the string, which causes the API function receiving the parameter to behave incorrectly and may cause a memory violation error.

The SetCaretBlinkTime function requires the rate in milliseconds parameterto be passed by value to the function. Declare this function by adding thefollowing statement to a module:
   Declare Function SetCaretBlinkTime Lib "user32" Alias _   "SetCaretBlinkTime" (ByVal wMSeconds As Long) As Long				
To use this function to set the cursor blink rate to 250 milliseconds, addthe following to your project:
Dim lBlinkRate as Long   ' Blink rate variableDim lResult as Long      ' Result VariablelBlinkRate = 250lResult = SetCaretBlinkTime (lBlinkRate)If lResult = 0 Then   ' Error codeEnd If				

Sample Project

This section shows you how to create a sample project that controls thecursor blink rate by calling two functions in the Windows API. TheGetCaretBlinkRate function returns the current blink rate in millisecondswhile the SetCaretBlinkRate function sets the blink rate. Both of thesefunctions will be declared in a module. You can also declare thesefunctions in the form by prefacing each function declaration with thePrivate keyword.

NOTE: The SetCaretBlinkRate function sets the cursor blink rate for the operating system. If you exit the project before setting the blink rateback to the default, the cursor blink rate will change for all programs.

Step-by-Step Example

  1. Start a new Standard EXE project in Visual Basic. Form1 is created by default.
  2. Add a Module to the project by completing the following steps:
    1. From the Project menu, click Add module. The Add Module dialog box appears.
    2. From the New tab, choose Module and click OK. A new module, Module1, is added to your project.
  3. Copy the following code to the Code window of Module1:
    Option Explicit' Returns the current cursor blink rateDeclare Function GetCaretBlinkTime Lib "user32" () As Long' Sets the cursor blink rateDeclare Function SetCaretBlinkTime Lib "user32" _                (ByVal wMSeconds As Long) As Long' Returns the error code if either GetCaretBlinkTime or' SetCaretBlinkTime functions failsPublic Declare Function GetLastError Lib "kernel32" () As Long					
  4. Add a HScrollBar, a TextBox, and a CommandButton to Form1.
  5. Copy the following code to the Code window of Form1:
    Option ExplicitDim lDefaultTime As LongDim lResult As LongDim lErrorCode As LongPrivate Sub Form_Load()   lResult = GetCaretBlinkTime   If lResult = 0 Then      Call DisplayError(0)   Else      lDefaultTime = lResult      HScroll1.Min = 10      HScroll1.Max = 1000      HScroll1.Value = lDefaultTime      Text1.Text = CStr(lDefaultTime)      Command1.Caption = "Return to Default"   End IfEnd SubPrivate Sub Command1_Click()   lResult = SetCaretBlinkTime(lDefaultTime)      ' If the function fails then display a message box with the error code   If lResult = 0 Then      Call DisplayError(1)   Else      ' Display the new blink rate.      HScroll1.Value = lDefaultTime      Text1.Text = CStr(GetCaretBlinkTime)      HScroll1.SetFocus   End IfEnd SubPrivate Sub HScroll1_Change()   lResult = SetCaretBlinkTime(HScroll1.Value)   If lResult = 0 Then      Call DisplayError(1)   Else      lResult = GetCaretBlinkTime      If GetCaretBlinkTime = 0 Then         Call DisplayError(0)      Else         Text1.Text = CStr(lResult)      End If   End IfEnd SubPrivate Sub HScroll1_Scroll()   Text1.Text = CStr(HScroll1.Value)End SubPrivate Sub Text1_KeyPress(KeyAscii As Integer)   If KeyAscii = vbKeyReturn Then      Dim iTextValue As Integer      iTextValue = CInt(Text1.Text)      If iTextValue > 1000 Or iTextValue < 10 Then         MsgBox "Enter a number between 10 and 1000."         Text1.Text = CStr(HScroll1.Value)         Exit Sub      Else         HScroll1.Value = iTextValue      End If   End IfEnd SubPrivate Sub Form_Terminate()   lResult = SetCaretBlinkTime(lDefaultTime)   If lResult = 0 Then      lErrorCode = GetLastError      MsgBox ("SetCaretBlinkTime failed. Error" & CStr(lErrorCode))   End IfEnd SubPrivate Sub DisplayError(iFail As Integer)   Dim sErrorMsg As String   lErrorCode = GetLastError   Select Case iFail      Case 0   ' GetCaretBlinkRate Function Failed         sErrorMsg = "GetCaretBlinkRate Failed. Error Code "         sErrorMsg = sErrorMsg & CStr(lErrorCode)      Case 1         sErrorMsg = "SetCaretBlinkRate Failed. Error Code "         sErrorMsg = sErrorMsg & CStr(lErrorCode)      Case Else         sErrorMsg = "Unknown Error"   End Select   MsgBox (sErrorMsg)End Sub						
  6. On the Run menu, click Start or press the F5 key to start the program. Move the scroll bar to change the cursor blink rate. You can also enter a number between 10 and 1000 in the TextBox to change the blink rate. Click the "Return to Default" button to set the blink rate back to the default setting. To exit the application, you should click the Close button at the far right of the title bar instead of the stop button in the Visual Basic environment. This will restore your original cursor blink rate.


  • Save your work often: because you are calling functions in the Windows API, you are bypassing the syntax checking feature of Visual Basic. If the function fails, then an application error can occur and lock up your system. You can set Visual Basic to always save your work prior to running the project by enabling the Prompt to Save Changes option in the Environment Tab of the Options dialog box. You can get to this dialog box by clicking Options from the Tools menu.
  • Specify the variable type explicitly rather than using the Any variable type; a number of functions in the API Text Viewer can accept any type of variable as a parameter. These functions have parameters declared as Any. You can change the parameter to as specified variable type in order to simplify debugging your code.
  • Verify that you are passing the correct variable types, constants, and values required by the function by checking the function documentation in the Platform SDK. Although the SDK was written for a C programmer and therefore uses C data types, you can pass the appropriate data types by using the following Visual Basic data types:
    Function Data Type Parameter     Appropriate Visual Basic Data Type
    int, INT ByVal Long
    UNINT ByVal Long
    BOOL ByVal Long
    WORD ByVal Integer
    DWORD ByVal Long
    WPARAM ByVal Long
    COLORREF ByVal Long
    ATOM ByVal Integer
    HANDLE ByVal Long
    BYTE ByVal Byte
    char ByVal Byte
    LPINT, int * ByRef Long
    LPUINT, UINT * ByRef Long
    LPBOOL, BOOL * ByRef Long
    LPBYTE, BYTE * ByRef Byte
    LPWORD, WORD * ByRef Integer
    LPDWORD, DWORD * ByRef Long

  • Use the Add-In Manager to add the API Text Viewer as an add-in to theIDE. To use the Add-In Manager, see Using Wizards and Add-Ins in "Chapter 4-Managing Projects" of the "Visual Basic Programmer's Guide."
  • When using the API Text Viewer, convert the API text file to an Access database for faster searches.
  • Always pass strings to a DLL using the ByVal keyword.
For more information about using the functions in the Windows API, refer to the following sources:
  • VB5DLL.DOC - located in the TOOLS\DOCS directory of the Visual Basicproduct CD. These are notes for developing DLLs for use with MicrosoftVisual Basic. Use this information to know what a DLL expects from Visual Basic.
  • "Visual Basic 5.0 Programmer's Guide to the Win32 API" by Dan Appleman-A "must" book for Visual Basic programmers who want to use theWindows API. The book contains information written for the Visual Basic programmer on using the Windows API.
  • Hardcore Visual Basic by Bruce McKinney-contains good examples on how to extend the capabilities of Visual Basic through the Windows API.
  • Microsoft Developer Network Subscription - contains the header files used to compile the DLLs used by the operating system. You can use this information to verify the correct function, type, and constant declarations.
  • Mastering Visual Basic 5-Chapter 5: Using Dynamic Link Libraries:contains a good tutorial on using the Windows API.
For additional information on looking for the correct parameters, values,and constants required by the Windows API, please see the following articlein the Microsoft Knowledge Base:
187674 How To Find Undocumented Constants Used by Windows API Functions
The following articles in the Microsoft Knowledge Base show you how to usefunctions in the Windows API to accomplish specific tasks:
161161 How To Search a ListBox Control Quickly
175512 How To Get a Short Filename from a Long Filename
151799 How To Use the Animated Copy Functions in Windows 95

Article ID: 190000 - Last Review: 12/05/2015 09:00:02 - Revision: 2.2

Microsoft Visual Basic 6.0 Learning Edition, Microsoft Visual Basic 6.0 Professional Edition, Microsoft Visual Basic 5.0 Professional Edition, Microsoft Visual Basic 6.0 Enterprise Edition, Microsoft Visual Basic 5.0 Enterprise Edition, Microsoft Visual Basic 4.0 Standard Edition, Microsoft Visual Basic 4.0 Professional Edition, Microsoft Visual Basic 4.0 32-Bit Enterprise Edition, Microsoft Visual Basic for Applications 5.0

  • kbnosurvey kbarchive kbhowto kbapi kbfaq KB190000