"Deep
in the sea are riches beyond compare.
But if you seek safety, it is on the shore."
API
(Application Program Interface)
API
parameter types
When you already have an SDK Help, you will surely
notice that functions return values and parameters have some strange
types like VOID, LPCSTR or DWORD. If you are familiar with C,
then you know what they mean. For the rest, here is a table taken
from VB Books Online (topic is ‘Converting C Declarations
to Visual Basic’):
C language data type |
In Visual Basic declare
as |
Call with |
ATOM |
ByVal variable As Integer |
An expression that evaluates
to an Int. |
BOOL |
ByVal variable As Long |
An expression that evaluates
to a Long |
BYTE |
ByVal variable As Byte |
An expression that evaluates
to a Byte |
CHAR |
ByVal variable As Byte |
An expression that evaluates
to a Byte |
COLORREF |
ByVal variable As Long |
An expression that evaluates
to a Long |
DWORD |
ByVal variable As Long |
An expression that evaluates
to a Long |
HWND, HDC, HMENU, etc. (Windows
handles) |
ByVal variable As Long |
An expression that evaluates
to a Long |
INT, UINT |
ByVal variable As Long |
An expression that evaluates
to a Long |
LONG |
ByVal variable As Long |
An expression that evaluates
to a Long |
LPARAM |
ByVal variable As Long |
An expression that evaluates
to a Long |
LPDWORD |
variable As Long |
An expression that evaluates
to a Long |
LPINT, LPUINT |
variable As Long |
An expression that evaluates
to a Long |
LPRECT |
variable As type |
Any variable of that user-defined
type |
LPSTR, LPCSTR |
ByVal variable As String |
An expression that evaluates
to a String |
LPVOID |
variable As Any |
Any variable (use ByVal when
passing a string) |
LPWORD |
variable As Integer |
An expression that evaluates
to an Int. |
LRESULT |
ByVal variable As Long |
An expression that evaluates
to a Long |
NULL |
As Any or ByVal
variable As Long |
ByVal Nothing or ByVal 0& or vbNullString |
SHORT |
ByVal variable As Integer |
An expression that evaluates
to an Int. |
VOID |
Sub procedure |
Not applicable |
WORD |
ByVal variable As Integer |
An expression that evaluates
to an Int. |
WPARAM |
ByVal variable As Long |
An expression that evaluates
to a Long |
Notes: You should notice that the BOOL type (boolean)
evaluates to Long and not Boolean. So, 0 refers to False and any
other value to True.
HWND, HDC, HMENU, etc. - etc. means there also
other types like these. All of them begin with H and stand for
handles for different type of objects. For example HBITMAP is
a bitmap handle, HBRUSH is a brush handle and so on. They all
evaluate to Long and should be passes ByVal.
Notice also that LPVOID is declared as variable
As Any. There is a separate topic dedicated to Any.
Some types begin with LP. It is an abbreviation
of Long Pointer to. So LPWORD is actually a memory location where
the data is stored. No, you won't have to call a function to get
this address. When you pass your argument ByRef (the defaul) you
actually pass its address. The thing to remember here is that,
if you parameter type begins with LP - you should pass it ByRef.
By the way LPARAM is like Lparam and not LParam. It is not a pointer.
You must pass the actual value here, so it is passed ByVal.
There is also some strange type NULL. You know
from VB so I won't discuss it here. Just choose a way you will
pass it when needed. In most of the cases I see passing it as
ByVal 0& or as vbNullString.
And lastly, VOID is used for functions return
value to specify that there is no such value. API doen not have
Subs so this is the it implements them. Just remember - if the
function is declared as VOID - you must declare it as Sub in your
VB code.
Any
Some messages contain parameters declared as Any.
It means this parameter can be a variety of types (you may pass
an integer, a string, or a user-defined type, or else). So, here
is an example of a function (SendMessage) which contains a parameter
of type Any:
Public
Declare Function SendMessage Lib "User32" Alias "SendMessageA"
_
ByVal Hwnd as Long, ByVal wMsg as Long, _
ByVal wParam as Long, lParam as Any) as Long
lParam
is declared ByRef (default) and as Any. Now, here are some rules
to follow when passing different type of values to this function
as lParam.
If
the value is: Pass it As:
numeric ByVal (as Long, or as Any)
Null ByVal (as Long, or as Any)
string ByRef (as String, or as Any)
Type ByRef (as Any)
array of Type ByRef (as Any)
If
your function declaration looks like the one above, and you need
to pass a Long, write something like:
Call
SendMessage(Me.Hwnd, WM_XXXX, 0&, ByVal LongValue)
Note
that there is nothing in front of the first three parameter although
they are numeric values. This is so, because in the function declaration
they are declared as ByVal. The fourth parameter, though, is declared
ByRef (VB doesn't know what kind of values you are going to pass)
and you must explicitly specify ByVal in front of it.
Sometimes it's much simpler to just declare several
versions of one function and use a different one for different
calls. You may declare something like:
Public
Declare Function SendMessageLng Lib "User32" Alias "SendMessageA"
_
(ByVal Hwnd as Long, ByVal wMsg as Long, _
ByVal wParam as Long, ByVal lParam as Long) as
Long
OR:
Public
Declare Function SendMessageStr Lib "User32" Alias "SendMessageA"
_
(ByVal Hwnd as Long, ByVal wMsg as Long, _
ByVal wParam as Long, lParam as String) as Long
Notice
that the parameter type does not change for API. The fourth parameter
is always a 4-byte Long value. When you pass a Long or Null ByVal,
a the 4-byte value is passed directly to the function. If you
pass a String or else, you pass it ByRef and so VB actually passes
the address of you variable, and it is a 4-byte value again.
Passing
Parameter
Of course you know how to pass parameters, just
put it in the function call and its done! Well there are some
details you should be aware of when passing parameters to API
function.
ByVal or ByRef. Usually you don't have to bother
about these keywords as VB API Text Viewer declares the function
parameters as API wants them and when you just enter your value,
it is passed as is declared. Generally, when a value is passed
ByVal, the actual value is passed directly to the function, and
when passed ByRef, the address of the value is passed. The only
thing you may encounter is the Any type.
Passing strings to API function isn't difficult
too. The API expects the address of the first character of the
string and reads ahead of this address till it reaches a Null
character. Sound bad, but this the way VB actually handles strings.
The only thing to remember is always to pass the String ByRef.
The situation is slightly different when you expect
some information to be returned by the function. Here is the declaration
of GetComputerName API function:
Declare
Function GetComputerName Lib "kernel32" Alias "GetComputerNameA"
_
(ByVal lpBuffer As String, nSize As Long) As Long
The
first parameter is a long pointer to string, and the second the
length of the string. If you just declare a variable as String
and pass it to this function, an error occurs. So, you need to
initialize the string first. Here is how to get the computername:
Dim
Buffer As String
Buffer = Space(255)
Ret& = GetComputerName(Buffer, Len(Buffer))
if Ret& > 0 then CompName$ = Left(Buffer,
Ret&)
Here,
the string is initialized as 255-spaces string. We pass it to
the function and give it the length too. The function returns
0 for an error or the actual length of the computer name otherwise.
CompName$ will contain the computer name.
Some functions also expect arrays. Here an exmaple:
Declare
Function SetSysColors Lib "user32" Alias "SetSysColors"
_
(ByVal nChanges As Long, lpSysColor As Long, _
lpColorValues As Long) As Long
The last two parameter are arrays of Long. To
pass an array to a function, you pass just the first element.
Here is a sample code:
Const
COLOR_ACTIVECAPTION = 2
Const COLOR_INACTIVECAPTION = 3
Const COLOR_CAPTIONTEXT = 9
Const COLOR_INACTIVECAPTIONTEXT = 19
Dim
SysColor(3) As Long
Dim ColorValues(3) As Long
SysColor(0)
= COLOR_ACTIVECAPTION
SysColor(1) = COLOR_INACTIVECAPTION
SysColor(2) = COLOR_CAPTIONTEXT
SysColor(3) = COLOR_INACTIVECAPTIONTEXT
ColorValues(0)
= RGB(58, 158, 58) 'dark green
ColorValues(1) = RGB(93, 193, 93) 'light green
ColorValues(2) = 0 'black
ColorValues(3) = RGB(126, 126, 126) 'gray
Ret&
= SetSysColors(4&, SysColor(0), ColorValues(0))
This
sample changes the system colors for the active window caption
background and text and for the inactive window caption background
and text.
-by
Invincible(psycho@nepalimail.com)
|