SimConnect - Accessing from VB
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_POSITION, "PLANE LATITUDE", "Degrees", _
SIMCONNECT_DATATYPE_FLOAT64, 0, DATA_LATITUDE)
hr = SimConnect_AddToDataDefinition(hSimConnect, DATA_DEF_POSITION, "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)
' add code here
Case SIMCONNECT_RECV_ID_EXCEPTION
Dim RecvException As SIMCONNECT_RECV_EXCEPTION
pData = pData + Len(Recv)
CopyMemory RecvException, ByVal pData, Len(RecvException)
' add code here
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
--Russdirks 19:04, 9 October 2006 (CEST)