Codingdomain.com

Using structures in API calls from Visual Basic

Introduction

This page shows how to use data structures with API calls from Visual Basic.

Example code

The example below reads the size and location of a window.

Using data structures in API calls:
' Declarations

Public Type RECT
  Left As Long
  Top As Long
  Right As Long
  Bottom As Long
End Type

Private Declare Function GetClientRect _
  Lib "user32" (ByVal hWnd As Long, ByRef lpRect As RECT) As Long

Private Declare Function GetWindowRect Lib "user32" _
(ByVal hWnd As Long, ByRef lpRect As RECT) As Long

Private Declare Function IsWindow Lib "user32" _
                         (ByVal hWnd As Long) As Long

' Get the coordinates of the rectangular window
' at the screen, relative or absolute position
Public Function WindowRect(hWnd As Long, _
                           Optional AbsolutePos As Boolean) As RECT
  Dim rctBuff As RECT
  Dim Success As Boolean

  If IsWindow(hWnd) = 0 Then Error 5

  If AbsolutePos Then
    ' From the (0,0) point of the screen
    Success = GetWindowRect(hWnd, rctBuff)
  Else
    ' From the (0,0) point of the parent window
    Success = GetClientRect(hWnd, rctBuff)
  End If

  If Not Success Then Error 5
  WindowRect = rctBuff
End Function


'------------------------------------------------------------------
' Main

Public Sub Main()
  ' This is just a sample what you can do with the previous functions,
  ' not a complete listing

  Dim Handle As Long
  Dim Pos As RECT

  Form1.Show
  Handle = Form1.hWnd

  Pos = WindowRect(Handle, True)

  Debug.Print "Location of Form1 at the screen:"
  Debug.Print "  (" & Pos.Left & ", " & Pos.Top & ")" _
            & "-(" & Pos.Right & ", " & Pos.Bottom & ")"
End Sub

The code in the WindowRect() function creates a RECT data structure at the function's stack frame. The GetWindowRect() API only receives the address of your locally declared RECT data structure. The API fills that particular data block with the information about the window, and the control returns to your function.

This approach might sound weird from a Visual Basic standpoint, but this is a very normal approach in less type-safe langauges like C/C++. There is no such thing as "returning a block of data" in most programing languages. It's not efficient either. In C/C++ you have to maintain your own buffer, and let functions write data in it. This is the most safe and stable way if you know the rules, because you (actuall Visual Basic itself) are the one maintaining the memory being allocated.

Just to let you know...
It's worth mentioning that the API function just writes the data to the memory location given by it's caller. If your declaration is not correct, it's likely some other part of your system memory is being overwritten, which causes your application to crash. Using the correct API declaration and parameter data is very important for API functions.

blog comments powered by Disqus