Declare Statement |
No
Syntax for subroutines
[Public | Private] Declare Sub name Lib "libname" _ [Alias "aliasname"] [([arglist])]
Syntax for functions
[Public | Private] Declare Function name Lib "libname" [Alias "aliasname"] [([arglist])] [As type]
Public
Use: Optional
Keyword used to declare a procedure that has scope in all procedures in all modules in the application.
Private
Use: Optional
Keyword used to declare a procedure that has scope only within the module in which it's declared.
Sub
Use: Optional
Keyword indicating that the procedure doesn't return a value. Mutually exclusive with Function.
Function
Use: Optional
Indicates that the procedure returns a value. Mutually exclusive with Sub.
name
Use: Required
Data Type: String
Any valid procedure name within the DLL or code library. If the aliasname argument is used, name represents the name the function or procedure is called in your code, while aliasname represents the name of the routine as found in the external library.
Lib
Use: Required
Keyword indicating that the procedure is contained within a DLL or other code library.
libname
Use: Required
Data Type: String
The name of the DLL or other code library that contains the declared procedure.
Alias
Use: Optional
Keyword whose presence indicates that name is different from the procedure's real name within the DLL or other code library.
aliasname
Use: Optional
Data Type: String
The real name of the procedure within the DLL or code library.
arglist
Use: Optional
Data Type: Any
A list of variables representing the arguments that are passed to the procedure when it's called. (For details of the arglist syntax and elements, see the entries for the Sub statement or Function statement.)
type
Use: Optional
Data type of the value returned by a function. (For further details see the Function statement entry.)
Used at module level to declare references to external procedures in a dynamic-link library (DLL).
You can place a Declare statement within a code module, in which case it can be public or private, or within the declarations section of a form or class module, in which case it must be private.
Leaving the parentheses empty and not supplying an arglist indicates that the Sub or Function procedure has no arguments.
The number and type of arguments included in arglist are checked each time the procedure is called.
The data type you use in the As clause following arglist must match that returned by the function.
Option Explicit Declare Function GetVersion Lib "kernel32"() As Long Public Function WhereAmI() As Boolean Dim lWinVersion As Long Dim lWinMajVer As Long Dim lWinMinVer As Long Dim sSys As String lWinVersion = GetVersion() lWinMajVer = lWinVersion And 255 lWinMinVer = (lWinVersion And 65280) / 256 If lWinVersion And &H80000000 Then sSys = "Windows 95" Else sSys = "Windows NT" End If Msgbox "Platform: " & sSys & vbCrLf & _ "Version: " & lWinMajVer & "." & lWinMinVer
If you don't specify a Public or Private keyword, the visibility of the external procedure is public by default. However, if the routine is declared in the declarations section of a form or a class module, a compiler error ("Constants, fixed length strings, arrays, and Declare statements not allowed as Public members of object modules") results.
Using an alias is useful when the name of an external procedure would conflict with a Visual Basic keyword or with the name of a procedure within your project, or when the name of the procedure in the code library isn't allowed by the Visual Basic DLL naming convention. In addition, aliasname is frequently used in the case of functions in the Win32 API that have string parameters, where the "official" documented name of the function is used in code to call either of two "real" functions, one an ANSI and the other a Unicode version. For example:
Declare Function ExpandEnvironmentStrings _ Lib "kernel32" Alias "ExpandEnvironmentStringsA" _ (ByVal lpSrc As String, ByVal lpDst As String, _ ByVal nSize As Long) As Long
defines the documented Win32 function ExpandEnvironmentStrings to a VB application. However, although calls to the function take the form:
lngBytes = ExpandEnvironmentStrings(strOriginal, _ strCopy, len(strCopy)
the actual name of the function as it exists in Kernel32.dll is ExpandEnvironmentStringsA. (Windows API functions ending in A are the ANSI string versions, and those ending in W (for Wide) are the Unicode string versions.)
You can use the # symbol at the beginning of aliasname to denote that aliasname is in fact the ordinal number of a procedure within the DLL or code library. In this case, all characters following the # sign that compose the aliasname argument must be numeric. For example:
Declare Function GetForegroundWindow Lib "user32" _ Alias "#237" () As Long
Remember that DLL entry points are case sensitive. In other words, either name or, if it's present and doesn't represent a routine's ordinal position, aliasname must correspond in case exactly to the routine as it's defined in the external DLL. Otherwise, VB displays runtime error 453, "Specified DLL function not found." If you aren't sure how the routine name appears in the DLL, use QuickView to browse the DLL and scan for its export table.
libname can include an optional path that identifies precisely where the external library is located. If the path isn't included along with the library name, VB by default searches the current directory, the Windows directory, the Windows system directory, and the directories in the path, in that order.
If the external library is one of the major Windows system DLLs (like Kernel32.dll or Advapi32.dll ), libname can consist of only the root filename, rather than the complete filename and extension.
In some cases, a single parameter to an API function can accept one of several data types as arguments. This is particularly common when a function accepts a pointer to a string buffer if an argument is to be supplied and a null pointer if it doesn't; the former is expressed in Visual Basic by a string argument and the latter by a passed to the function by value. It's also the case whenever an API function designates a parameter's data type as LPVOID, which indicates a pointer to any data type. To handle this, you can define separate versions of the DECLARE statement, one for each data type to be passed to the function. (In this case, name designates the name by which a particular API function is referenced in your program, while the ALIAS clause designates the name of the routine as it exists in the DLL.) A second alternative, rather than having to "strongly type" a parameter in arglist, is to designate its data type as As Any, indicating that the routine accepts an argument of any data type. While this provides you with a flexible way of partly overcoming the mismatch between VB and C data types, you should use it with caution, since it suspends Visual Basic's normal type checking for that argument.
Windows NT was built from the ground up using Unicode (two-byte) strings; however, it also supports ANSI strings. OLE 2.0 was built to use Unicode strings exclusively. Visual Basic from Version 4 onwards uses Unicode strings internally, but passes ANSI strings into your program. What does all this mean for you? Well, Windows NT and OLE 2.0 API calls that have string parameters require them to be passed as Unicode strings. Unfortunately, although Visual Basic uses Unicode strings internally, it converts strings passed to these DLLs back into ANSI. The remedy is to use a dynamic array of type Byte. Passing and receiving arrays of bytes circumvents Visual Basic's Unicode-ANSI conversion.
To pass a string to a Unicode API function, declare a dynamic byte array, assign your string to the array, and concatenate a terminating null character (vbNullChar) to the end of the string, then pass the first byte of the array (at element 0) to the function, as the following simple snippet shows:
Dim bArray() As Byte bArray() = "My String" & vbNullChar someApiCall(bArray(0))
One of the most common uses of the Declare statement is to make routines in the Win32 API accessible to your programs. For more information on calling the Win32 API from Visual Basic, see Dan Appleman's The Visual Basic Programmer's Guide to the Win32 API, published by Ziff-Davis Press.