Using variable argument types in API calls from Visual Basic
Introduction
This page shows how to use a variable argument type with API calls from Visual Basic.
Example code
The example below clips and unclips the mouse cursor to a specific screen area.
- Using the any type in API calls:
' Declarations
Public Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type Private Declare Function ClipCursor Lib "user32" (lpRect As Any) As Long'This is the alternative declaration:
'
'Private Declare Function MakeTheCursorClip Lib "user32" _
' Alias "ClipCursor" (lpRect As RECT) As Long
'
'Private Declare Function UpClipTheCursor Lib "user32" _
' Alias "ClipCursor" (ByVal ThisShouldBeZero As Long) As Long
Private Declare Function timeGetTime Lib "winmm.dll" () As Long'------------------------------------------------------------------
' Clip the mouse
Public Sub ClipMouse(Left As Long, Top As Long, _ Right As Long, Bottom As Long) Dim rctClip As RECT rctClip.Left = Left rctClip.Top = Top rctClip.Right = Right rctClip.Bottom = Bottom If ClipCursor(rctClip) = 0 Then _ Err.Raise 12345, "MouseIO", "Could not clip cursor!" End Sub Public Sub UnClipMouse() If ClipCursor(ByVal 0&) = 0 Then _ Err.Raise 12345, "MouseIO", "Could not un clip cursor!" End Sub'------------------------------------------------------------------
' Pausing without freezing
Public Sub Wait(TimeOut As Long) Dim TimeNow As Long TimeNow = timeGetTime() Do DoEvents Loop While TimeNow + TimeOut > timeGetTime() End Sub'------------------------------------------------------------------
' Main
Public Sub Main() Call ClipMouse(20,20,400,400) Debug.Print "The mouse will be clipped for 4 seconds" Wait 4000 Call UnClipMouse Debug.Print "Everything is back to normal" End Sub
The ClipCursor() API accepts one parameter; the location (address) of your RECT buffer in the system memory. This is called "a pointer to a RECT" in C programming.
Supplying a pointer is exactly what Visual Basic does with it's ByRef keyword. The language doesn't allow programmers to supply a "null-location" (also called "null pointer"), as required by the ClipCursor() API. A null pointer indicates there is no reference to a memory location at all. Using the statement ByVal 0&, you can pass a long value of 0 to the function.
The ClipCursor() function expects a "null" location to unset the clipping area. This problem can be solved with the As Any declaration. Using this keyword, Visual Basic no longer performs certain checks on the API function call, and allows you to use free-form values.
There is also an alternative solution to this problem. It's possible to declare two API functions with different names, using the "alias" keyword. Both of names refer to the same API, but have a different argument list. This is shown in the example above.
There is one problem with the As Any declaration, Visual Basic can no longer perform it's magic on the parameters (or at a very late moment).
blog comments powered by Disqus