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)