Difference between revisions of "SimConnect - Accessing from VB"

From FSDeveloper Wiki
Jump to: navigation, search
 
Line 2: Line 2:
 
The SimConnect documentation states that you must use C or C++ to access SimConnect, unless you use the managed API, in which case you can use any of the Microsoft .Net language compilers.  However I have found, after a bit of experimentation, that you can access the non-managed SimConnect API from VB and VBA, using appropriate DECLARE statements.
 
The SimConnect documentation states that you must use C or C++ to access SimConnect, unless you use the managed API, in which case you can use any of the Microsoft .Net language compilers.  However I have found, after a bit of experimentation, that you can access the non-managed SimConnect API from VB and VBA, using appropriate DECLARE statements.
  
Below are the DECLARE statements I have written so far, with example calls.  Others can contribute to this section as well, until the entire API is covered.
+
Below are the DECLARE statements I have written so far.  Others can contribute to this section if they wish, until the entire API is covered.
  
 
Note : to make these work, you'll have to place a copy of SimConnect.dll somewhere where VB can find it, or else specify the path to it directly in the Declare statement
 
Note : to make these work, you'll have to place a copy of SimConnect.dll somewhere where VB can find it, or else specify the path to it directly in the Declare statement
Line 39: Line 39:
 
Declare Function SimConnect_Close Lib "SimConnect.dll" (ByVal hSimConnect As Long) As Long
 
Declare Function SimConnect_Close Lib "SimConnect.dll" (ByVal hSimConnect As Long) As Long
 
</pre>
 
</pre>
 +
 +
==Constants & Enums==
 +
<pre>
 +
Const S_OK = 0
 +
Const E_FAIL = &H80004005
 +
Const E_INVALIDARG = &H80070057
 +
 +
Enum SIMCONNECT_RECV_ID
 +
    SIMCONNECT_RECV_ID_NULL
 +
    SIMCONNECT_RECV_ID_EXCEPTION
 +
    SIMCONNECT_RECV_ID_OPEN
 +
    SIMCONNECT_RECV_ID_QUIT
 +
    SIMCONNECT_RECV_ID_EVENT
 +
    SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE
 +
    SIMCONNECT_RECV_ID_EVENT_FILENAME
 +
    SIMCONNECT_RECV_ID_EVENT_FRAME
 +
    SIMCONNECT_RECV_ID_SIMOBJECT_DATA
 +
    SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE
 +
    SIMCONNECT_RECV_ID_WEATHER_OBSERVATION
 +
    SIMCONNECT_RECV_ID_CLOUD_STATE
 +
    SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID
 +
    SIMCONNECT_RECV_ID_RESERVED_KEY
 +
    SIMCONNECT_RECV_ID_CUSTOM_ACTION
 +
    SIMCONNECT_RECV_ID_SYSTEM_STATE
 +
    SIMCONNECT_RECV_ID_CLIENT_DATA
 +
End Enum
 +
 +
Enum SIMCONNECT_DATATYPE
 +
    SIMCONNECT_DATATYPE_INVALID        ' invalid data type
 +
    SIMCONNECT_DATATYPE_INT32          ' 32-bit integer number
 +
    SIMCONNECT_DATATYPE_INT64          ' 64-bit integer number
 +
    SIMCONNECT_DATATYPE_FLOAT32        ' 32-bit floating-point number (float)
 +
    SIMCONNECT_DATATYPE_FLOAT64        ' 64-bit floating-point number (double)
 +
    SIMCONNECT_DATATYPE_STRING8        ' 8-byte string
 +
    SIMCONNECT_DATATYPE_STRING32      ' 32-byte string
 +
    SIMCONNECT_DATATYPE_STRING64      ' 64-byte string
 +
    SIMCONNECT_DATATYPE_STRING128      ' 128-byte string
 +
    SIMCONNECT_DATATYPE_STRING256      ' 256-byte string
 +
    SIMCONNECT_DATATYPE_STRING260      ' 260-byte string
 +
    SIMCONNECT_DATATYPE_STRINGV        ' variable-length string
 +
 +
    SIMCONNECT_DATATYPE_INITPOSITION  ' see SIMCONNECT_DATA_INITPOSITION
 +
    SIMCONNECT_DATATYPE_MARKERSTATE    ' see SIMCONNECT_DATA_MARKERSTATE
 +
    SIMCONNECT_DATATYPE_WAYPOINT      ' see SIMCONNECT_DATA_WAYPOINT
 +
    SIMCONNECT_DATATYPE_LATLONALT      ' see SIMCONNECT_DATA_LATLONALT
 +
    SIMCONNECT_DATATYPE_XYZ            ' see SIMCONNECT_DATA_XYZ
 +
 +
    SIMCONNECT_DATATYPE_MAX            ' enum limit
 +
End Enum
 +
 +
Enum SIMCONNECT_SIMOBJECT_TYPE
 +
  SIMCONNECT_SIMOBJECT_TYPE_USER
 +
  SIMCONNECT_SIMOBJECT_TYPE_ALL
 +
  SIMCONNECT_SIMOBJECT_TYPE_AIRCRAFT
 +
  SIMCONNECT_SIMOBJECT_TYPE_HELICOPTER
 +
  SIMCONNECT_SIMOBJECT_TYPE_BOAT
 +
  SIMCONNECT_SIMOBJECT_TYPE_GROUND
 +
End Enum
 +
 +
Enum SIMCONNECT_EXCEPTION
 +
  SIMCONNECT_EXCEPTION_NONE = 0
 +
  SIMCONNECT_EXCEPTION_ERROR = 1
 +
  SIMCONNECT_EXCEPTION_SIZE_MISMATCH = 2
 +
  SIMCONNECT_EXCEPTION_UNRECOGNIZED_ID = 3
 +
  SIMCONNECT_EXCEPTION_UNOPENED = 4
 +
  SIMCONNECT_EXCEPTION_VERSION_MISMATCH = 5
 +
  SIMCONNECT_EXCEPTION_TOO_MANY_GROUPS = 6
 +
  SIMCONNECT_EXCEPTION_NAME_UNRECOGNIZED = 7
 +
  SIMCONNECT_EXCEPTION_TOO_MANY_EVENT_NAMES = 8
 +
  SIMCONNECT_EXCEPTION_EVENT_ID_DUPLICATE = 9
 +
  SIMCONNECT_EXCEPTION_TOO_MANY_MAPS = 10
 +
  SIMCONNECT_EXCEPTION_TOO_MANY_OBJECTS = 11
 +
  SIMCONNECT_EXCEPTION_TOO_MANY_REQUESTS = 12
 +
  SIMCONNECT_EXCEPTION_WEATHER_INVALID_PORT = 13
 +
  SIMCONNECT_EXCEPTION_WEATHER_INVALID_METAR = 14
 +
  SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_GET_OBSERVATION = 15
 +
  SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_CREATE_STATION = 16
 +
  SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_REMOVE_STATION = 17
 +
  SIMCONNECT_EXCEPTION_INVALID_DATA_TYPE = 18
 +
  SIMCONNECT_EXCEPTION_INVALID_DATA_SIZE = 19
 +
  SIMCONNECT_EXCEPTION_DATA_ERROR = 20
 +
  SIMCONNECT_EXCEPTION_INVALID_ARRAY = 21
 +
  SIMCONNECT_EXCEPTION_CREATE_OBJECT_FAILED = 22
 +
  SIMCONNECT_EXCEPTION_LOAD_FLIGHTPLAN_FAILED = 23
 +
  SIMCONNECT_EXCEPTION_OPERATION_INVALID_FOR_OJBECT_TYPE = 24
 +
  SIMCONNECT_EXCEPTION_ILLEGAL_OPERATION = 25
 +
  SIMCONNECT_EXCEPTION_ALREADY_SUBSCRIBED = 26
 +
  SIMCONNECT_EXCEPTION_INVALID_ENUM = 27
 +
  SIMCONNECT_EXCEPTION_DEFINITION_ERROR = 28
 +
  SIMCONNECT_EXCEPTION_DUPLICATE_ID = 29
 +
  SIMCONNECT_EXCEPTION_DATUM_ID = 30
 +
  SIMCONNECT_EXCEPTION_OUT_OF_BOUNDS = 31
 +
End Enum
 +
</pre>
 +
 +
==Structures==
 +
<pre>
 +
Type SIMCONNECT_RECV
 +
  dwSize As Long
 +
  dwVersion As Long
 +
  dwID As Long
 +
End Type
 +
 +
Type SIMCONNECT_RECV_EXCEPTION
 +
  dwException As Long
 +
  dwSendID As Long
 +
  dwIndex As Long
 +
End Type
 +
 +
Type SIMCONNECT_RECV_OPEN
 +
  szApplicationName As String * 256
 +
  dwApplicationVersionMajor As Long
 +
  dwApplicationVersionMinor As Long
 +
  dwApplicationBuildMajor As Long
 +
  dwApplicationBuildMinor As Long
 +
  dwSimConnectVersionMajor As Long
 +
  dwSimConnectVersionMinor As Long
 +
  dwSimConnectBuildMajor As Long
 +
  dwSimConnectBuildMinor As Long
 +
  dwReserved1 As Long
 +
  dwReserved2 As Long
 +
End Type
 +
 +
Type SIMCONNECT_RECV_SIMOBJECT_DATA
 +
  dwRequestID As Long
 +
  dwObjectID As Long
 +
  dwDefineID As Long
 +
  dwFlags As Long
 +
  dwentrynumber As Long
 +
  dwoutof As Long
 +
  dwDefineCount As Long
 +
  dwData As Long
 +
End Type
 +
</pre>
 +
 +
==Sample Code==
 +
This code retrieves the latitude / longitude of the user aircraft.
 +
 +
<pre>
 +
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
 +
      (Destination As Any, _
 +
      Source As Any, _
 +
      ByVal Length As Long)
 +
 +
Public Declare Function GetTickCount Lib "kernel32" () As Long
 +
 +
Enum DATA_DEFINE_ID
 +
  DATA_DEF_POSITION
 +
End Enum
 +
 +
Enum DATA_REQUEST_ID
 +
  DATA_REQUEST_POSITION
 +
End Enum
 +
 +
Enum DATA_IDS
 +
  DATA_LATITUDE
 +
  DATA_LONGITUDE
 +
End Enum
 +
 +
Type PosRec
 +
  Latitude As Double
 +
  Longitude As Double
 +
End Type
 +
 +
Dim hSimConnect As Long
 +
Dim Position As PosRec
 +
 
 +
Sub GetPosition()
 +
  Dim hr As Long
 +
  Dim T As Long
 +
 
 +
  hr = SimConnect_Open(hSimConnect, "MYAPP", 0, 0, 0, 0)
 +
  If (hr <> S_OK) Then
 +
      MsgBox "Unable to connect with FSX!", vbExclamation, "SimConnect"
 +
  Else
 +
      hr = SimConnect_AddToDataDefinition(hSimConnect, DATA_DEF_POSIION, "PLANE LATITUDE", "Degrees", _
 +
                  SIMCONNECT_DATATYPE_FLOAT64, 0, DATA_LATITUDE)
 +
      hr = SimConnect_AddToDataDefinition(hSimConnect, DATA_DEF_POSIION, "PLANE LONGITUDE", "Degrees", _
 +
                  SIMCONNECT_DATATYPE_FLOAT64, 0, DATA_LONGITUDE)
 +
      hr = SimConnect_RequestDataOnSimObjectType(hSimConnect, DATA_REQUEST_POSITION, DATA_DEF_POSITION, _
 +
                  0, SIMCONNECT_SIMOBJECT_TYPE_USER)
 +
      T = GetTickCount()
 +
      Do
 +
        DoEvents
 +
        RequestID = GetNextDispatch()
 +
      Loop Until (RequestID = DATA_REQUEST_POSITION) Or (GetTickCount() > T + 2000)
 +
      If RequestID = DATA_REQUEST_POSITION Then
 +
        MsgBox "Latitude : " + Format(Position.Latitude, "Fixed") + vbCrLf + _
 +
                "Longitude : " + Format(Position.Longitude, "Fixed"), vbInformation
 +
      Else
 +
        MsgBox "No data available!", vbExclamation
 +
      End If
 +
      SimConnect_Close hSimConnect
 +
  End If
 +
End Sub
 +
 +
Function GetNextDispatch() As Long
 +
  ' this function returns the dwRequestID field of SIMCONNECT_RECV_SIMOBJECT_DATA, if applicable
 +
  ' otherwise -1
 +
  Dim hr As Long
 +
  Dim pData As Long, pcbData As Long
 +
  Dim Recv As SIMCONNECT_RECV
 +
 
 +
  GetNextDispatch = -1
 +
  hr = SimConnect_GetNextDispatch(hSimConnect, pData, pcbData)
 +
  If hr = S_OK Then
 +
      CopyMemory Recv, ByVal pData, Len(Recv)
 +
      Select Case Recv.dwID
 +
        Case SIMCONNECT_RECV_ID_OPEN
 +
            Dim RecvOpen As SIMCONNECT_RECV_OPEN
 +
            pData = pData + Len(Recv)
 +
            CopyMemory RecvOpen, ByVal pData, Len(RecvOpen)
 +
        Case SIMCONNECT_RECV_ID_EXCEPTION
 +
            Dim RecvException As SIMCONNECT_RECV_EXCEPTION
 +
            pData = pData + Len(Recv)
 +
            CopyMemory RecvException, ByVal pData, Len(RecvException)
 +
        Case SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE
 +
            Dim RecvData As SIMCONNECT_RECV_SIMOBJECT_DATA
 +
            pData = pData + Len(Recv)
 +
            CopyMemory RecvData, ByVal pData, Len(RecvData)
 +
            GetNextDispatch = RecvData.dwRequestID
 +
            Select Case RecvData.dwRequestID
 +
              Case DATA_REQUEST_POSITION
 +
                  pData = pData + Len(RecvData) - 4
 +
                  CopyMemory Position, ByVal pData, Len(Position)
 +
            End Select
 +
      End Select
 +
  End If
 +
End Function
 +
</pre>
 +
  
 
[[category:SimConnect]]
 
[[category:SimConnect]]

Revision as of 11:02, 9 October 2006

Introduction

The SimConnect documentation states that you must use C or C++ to access SimConnect, unless you use the managed API, in which case you can use any of the Microsoft .Net language compilers. However I have found, after a bit of experimentation, that you can access the non-managed SimConnect API from VB and VBA, using appropriate DECLARE statements.

Below are the DECLARE statements I have written so far. Others can contribute to this section if they wish, until the entire API is covered.

Note : to make these work, you'll have to place a copy of SimConnect.dll somewhere where VB can find it, or else specify the path to it directly in the Declare statement

Declare Statements

Declare Function SimConnect_Open Lib "SimConnect.dll" _
   (phSimConnect As Long, _
    ByVal szName As String, _
    ByVal hWnd As Long, _
    ByVal UserEventWin32 As Long, _
    ByVal hEventHandle As Long, _
    ByVal ConfigIndex As Long) As Long
 
Declare Function SimConnect_GetNextDispatch Lib "SimConnect.dll" _
      (ByVal hSimConnect As Long, _
       ppData As Long, _
       pcbData As Long) As Long
       
Declare Function SimConnect_AddToDataDefinition Lib "SimConnect.dll" _
      (ByVal hSimConnect As Long, _
       ByVal DefineID As Long, _
       ByVal DatumName As String, _
       ByVal UnitsName As String, _
       Optional ByVal DatumType As Long, _
       Optional ByVal fEpsilon As Single, _
       Optional ByVal DatumID As Long) As Long
       
Declare Function SimConnect_RequestDataOnSimObjectType Lib "SimConnect.dll" _
      (ByVal hSimConnect As Long, _
       ByVal RequestID As Long, _
       ByVal DefineID As Long, _
       ByVal dwRadiusMeters As Long, _
       ByVal ObjectType As Long) As Long
       
Declare Function SimConnect_Close Lib "SimConnect.dll" (ByVal hSimConnect As Long) As Long

Constants & Enums

Const S_OK = 0
Const E_FAIL = &H80004005
Const E_INVALIDARG = &H80070057

Enum SIMCONNECT_RECV_ID
    SIMCONNECT_RECV_ID_NULL
    SIMCONNECT_RECV_ID_EXCEPTION
    SIMCONNECT_RECV_ID_OPEN
    SIMCONNECT_RECV_ID_QUIT
    SIMCONNECT_RECV_ID_EVENT
    SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE
    SIMCONNECT_RECV_ID_EVENT_FILENAME
    SIMCONNECT_RECV_ID_EVENT_FRAME
    SIMCONNECT_RECV_ID_SIMOBJECT_DATA
    SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE
    SIMCONNECT_RECV_ID_WEATHER_OBSERVATION
    SIMCONNECT_RECV_ID_CLOUD_STATE
    SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID
    SIMCONNECT_RECV_ID_RESERVED_KEY
    SIMCONNECT_RECV_ID_CUSTOM_ACTION
    SIMCONNECT_RECV_ID_SYSTEM_STATE
    SIMCONNECT_RECV_ID_CLIENT_DATA
End Enum

Enum SIMCONNECT_DATATYPE
    SIMCONNECT_DATATYPE_INVALID        ' invalid data type
    SIMCONNECT_DATATYPE_INT32          ' 32-bit integer number
    SIMCONNECT_DATATYPE_INT64          ' 64-bit integer number
    SIMCONNECT_DATATYPE_FLOAT32        ' 32-bit floating-point number (float)
    SIMCONNECT_DATATYPE_FLOAT64        ' 64-bit floating-point number (double)
    SIMCONNECT_DATATYPE_STRING8        ' 8-byte string
    SIMCONNECT_DATATYPE_STRING32       ' 32-byte string
    SIMCONNECT_DATATYPE_STRING64       ' 64-byte string
    SIMCONNECT_DATATYPE_STRING128      ' 128-byte string
    SIMCONNECT_DATATYPE_STRING256      ' 256-byte string
    SIMCONNECT_DATATYPE_STRING260      ' 260-byte string
    SIMCONNECT_DATATYPE_STRINGV        ' variable-length string

    SIMCONNECT_DATATYPE_INITPOSITION   ' see SIMCONNECT_DATA_INITPOSITION
    SIMCONNECT_DATATYPE_MARKERSTATE    ' see SIMCONNECT_DATA_MARKERSTATE
    SIMCONNECT_DATATYPE_WAYPOINT       ' see SIMCONNECT_DATA_WAYPOINT
    SIMCONNECT_DATATYPE_LATLONALT      ' see SIMCONNECT_DATA_LATLONALT
    SIMCONNECT_DATATYPE_XYZ            ' see SIMCONNECT_DATA_XYZ

    SIMCONNECT_DATATYPE_MAX             ' enum limit
End Enum

Enum SIMCONNECT_SIMOBJECT_TYPE
  SIMCONNECT_SIMOBJECT_TYPE_USER
  SIMCONNECT_SIMOBJECT_TYPE_ALL
  SIMCONNECT_SIMOBJECT_TYPE_AIRCRAFT
  SIMCONNECT_SIMOBJECT_TYPE_HELICOPTER
  SIMCONNECT_SIMOBJECT_TYPE_BOAT
  SIMCONNECT_SIMOBJECT_TYPE_GROUND
End Enum

Enum SIMCONNECT_EXCEPTION
  SIMCONNECT_EXCEPTION_NONE = 0
  SIMCONNECT_EXCEPTION_ERROR = 1
  SIMCONNECT_EXCEPTION_SIZE_MISMATCH = 2
  SIMCONNECT_EXCEPTION_UNRECOGNIZED_ID = 3
  SIMCONNECT_EXCEPTION_UNOPENED = 4
  SIMCONNECT_EXCEPTION_VERSION_MISMATCH = 5
  SIMCONNECT_EXCEPTION_TOO_MANY_GROUPS = 6
  SIMCONNECT_EXCEPTION_NAME_UNRECOGNIZED = 7
  SIMCONNECT_EXCEPTION_TOO_MANY_EVENT_NAMES = 8
  SIMCONNECT_EXCEPTION_EVENT_ID_DUPLICATE = 9
  SIMCONNECT_EXCEPTION_TOO_MANY_MAPS = 10
  SIMCONNECT_EXCEPTION_TOO_MANY_OBJECTS = 11
  SIMCONNECT_EXCEPTION_TOO_MANY_REQUESTS = 12
  SIMCONNECT_EXCEPTION_WEATHER_INVALID_PORT = 13
  SIMCONNECT_EXCEPTION_WEATHER_INVALID_METAR = 14
  SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_GET_OBSERVATION = 15
  SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_CREATE_STATION = 16
  SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_REMOVE_STATION = 17
  SIMCONNECT_EXCEPTION_INVALID_DATA_TYPE = 18
  SIMCONNECT_EXCEPTION_INVALID_DATA_SIZE = 19
  SIMCONNECT_EXCEPTION_DATA_ERROR = 20
  SIMCONNECT_EXCEPTION_INVALID_ARRAY = 21
  SIMCONNECT_EXCEPTION_CREATE_OBJECT_FAILED = 22
  SIMCONNECT_EXCEPTION_LOAD_FLIGHTPLAN_FAILED = 23
  SIMCONNECT_EXCEPTION_OPERATION_INVALID_FOR_OJBECT_TYPE = 24
  SIMCONNECT_EXCEPTION_ILLEGAL_OPERATION = 25
  SIMCONNECT_EXCEPTION_ALREADY_SUBSCRIBED = 26
  SIMCONNECT_EXCEPTION_INVALID_ENUM = 27
  SIMCONNECT_EXCEPTION_DEFINITION_ERROR = 28
  SIMCONNECT_EXCEPTION_DUPLICATE_ID = 29
  SIMCONNECT_EXCEPTION_DATUM_ID = 30
  SIMCONNECT_EXCEPTION_OUT_OF_BOUNDS = 31
End Enum

Structures

Type SIMCONNECT_RECV
   dwSize As Long
   dwVersion As Long
   dwID As Long
End Type

Type SIMCONNECT_RECV_EXCEPTION
  dwException As Long
  dwSendID As Long
  dwIndex As Long
End Type

Type SIMCONNECT_RECV_OPEN
  szApplicationName As String * 256
  dwApplicationVersionMajor As Long
  dwApplicationVersionMinor As Long
  dwApplicationBuildMajor As Long
  dwApplicationBuildMinor As Long
  dwSimConnectVersionMajor As Long
  dwSimConnectVersionMinor As Long
  dwSimConnectBuildMajor As Long
  dwSimConnectBuildMinor As Long
  dwReserved1 As Long
  dwReserved2 As Long
End Type

Type SIMCONNECT_RECV_SIMOBJECT_DATA
  dwRequestID As Long
  dwObjectID As Long
  dwDefineID As Long
  dwFlags As Long
  dwentrynumber As Long
  dwoutof As Long
  dwDefineCount As Long
  dwData As Long
End Type

Sample Code

This code retrieves the latitude / longitude of the user aircraft.

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
      (Destination As Any, _
       Source As Any, _
       ByVal Length As Long)

Public Declare Function GetTickCount Lib "kernel32" () As Long

Enum DATA_DEFINE_ID
   DATA_DEF_POSITION
End Enum

Enum DATA_REQUEST_ID
   DATA_REQUEST_POSITION
End Enum

Enum DATA_IDS
   DATA_LATITUDE
   DATA_LONGITUDE
End Enum

Type PosRec
   Latitude As Double
   Longitude As Double
End Type

Dim hSimConnect As Long
Dim Position As PosRec
   
Sub GetPosition()
   Dim hr As Long
   Dim T As Long
   
   hr = SimConnect_Open(hSimConnect, "MYAPP", 0, 0, 0, 0)
   If (hr <> S_OK) Then
      MsgBox "Unable to connect with FSX!", vbExclamation, "SimConnect"
   Else
      hr = SimConnect_AddToDataDefinition(hSimConnect, DATA_DEF_POSIION, "PLANE LATITUDE", "Degrees", _
                  SIMCONNECT_DATATYPE_FLOAT64, 0, DATA_LATITUDE)
      hr = SimConnect_AddToDataDefinition(hSimConnect, DATA_DEF_POSIION, "PLANE LONGITUDE", "Degrees", _
                  SIMCONNECT_DATATYPE_FLOAT64, 0, DATA_LONGITUDE)
      hr = SimConnect_RequestDataOnSimObjectType(hSimConnect, DATA_REQUEST_POSITION, DATA_DEF_POSITION, _
                  0, SIMCONNECT_SIMOBJECT_TYPE_USER)
      T = GetTickCount()
      Do
         DoEvents
         RequestID = GetNextDispatch()
      Loop Until (RequestID = DATA_REQUEST_POSITION) Or (GetTickCount() > T + 2000)
      If RequestID = DATA_REQUEST_POSITION Then
         MsgBox "Latitude : " + Format(Position.Latitude, "Fixed") + vbCrLf + _
                "Longitude : " + Format(Position.Longitude, "Fixed"), vbInformation
      Else
         MsgBox "No data available!", vbExclamation
      End If
      SimConnect_Close hSimConnect
   End If
End Sub

Function GetNextDispatch() As Long
   ' this function returns the dwRequestID field of SIMCONNECT_RECV_SIMOBJECT_DATA, if applicable
   ' otherwise -1
   Dim hr As Long
   Dim pData As Long, pcbData As Long
   Dim Recv As SIMCONNECT_RECV
   
   GetNextDispatch = -1
   hr = SimConnect_GetNextDispatch(hSimConnect, pData, pcbData)
   If hr = S_OK Then
      CopyMemory Recv, ByVal pData, Len(Recv)
      Select Case Recv.dwID
         Case SIMCONNECT_RECV_ID_OPEN
            Dim RecvOpen As SIMCONNECT_RECV_OPEN
            pData = pData + Len(Recv)
            CopyMemory RecvOpen, ByVal pData, Len(RecvOpen)
         Case SIMCONNECT_RECV_ID_EXCEPTION
            Dim RecvException As SIMCONNECT_RECV_EXCEPTION
            pData = pData + Len(Recv)
            CopyMemory RecvException, ByVal pData, Len(RecvException)
         Case SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE
            Dim RecvData As SIMCONNECT_RECV_SIMOBJECT_DATA
            pData = pData + Len(Recv)
            CopyMemory RecvData, ByVal pData, Len(RecvData)
            GetNextDispatch = RecvData.dwRequestID
            Select Case RecvData.dwRequestID
               Case DATA_REQUEST_POSITION
                  pData = pData + Len(RecvData) - 4
                  CopyMemory Position, ByVal pData, Len(Position)
            End Select
      End Select
   End If
End Function