Jump to content
The simFlight Network Forums

Paul Henty

Members
  • Posts

    1,652
  • Joined

  • Days Won

    74

Posts posted by Paul Henty

  1. 4 hours ago, Intood said:

    What is SimConnect.dll?

    Microsoft.FlightSimulator.SimConnect.dl is a library supplied by the authors of the Flight Sim to enable .NET languages to interface with SimConnect directly. SimConnect is an API for reading and writing data to/from the Flight Sim. It was written to do the same job as FSUIPC. FSUIP4 and above uses SimConnect in the background. 

    4 hours ago, Intood said:

    What is FSUIPC WAPID.dll?

    It's a library to enable programs written in any language to talk to John Dowson's WASM module for MSFS (2020). The WASM module allows the client program to read/write LVar and HVar variables from aircraft that use them. My FSUIPCClientDLL for ,NET uses this in the background for the MSFSVariableServices feature.

    4 hours ago, Intood said:

    Why would you use both of these in the same project?

    You would use SimConnect if you didn't want to use FSUIPC. 

    You would use FSUIPC_WAPID.dll if you want access to John's WASM module and you are not using my FSUIPCClientDLL for .NET.

    4 hours ago, Intood said:

    How do you install both of these in the same project?

    SimConnect is installed in the normal way you add any .NET library through Visual Studio - PROJECT-> Add Reference. You must have installed the Flight Sim sdk to get the SimConnect dll installed on your computer.

    The WASM dll is not a .NET dll, so this is just copied into the project and loaded at runtime with the [DLLImport] tag. You must also declare copies of each of the functions in the DLL that you want to access.

     

    In summary if you're using .NET just use my ClientDLL and everything is taken care of for you. You won't need to worry about either of these DLLs. Use of both of these DLLs requires advanced knowledge of programming.

    Paul

  2. Hi,

    I don't have any plans to add an automatic update. 

    In version 1.0.0 of the WebSocketServer I added a property to the 'about.read' response called 'newServerVersionAvailable'.

    Your web socket client program (or website) can check this. If it's 'true' it means that the WebSocketServer you are connected to is out of date. You can then warn the user and give instructions on updating.

    Will that fit your needs?

    Paul 

  3. Quote

     it appears those offsets are currently read only.

    Ah, yes. I've checked the offset status for FSUIPC7 - the writes for those offsets are not working yet. Apparently waiting for Asobo add an event:

    "Currently no available event. Reported to Asobo.".

    I don't know of any other way of setting three decimal frequencies. There might be an LVar you can use, but that would be specific to the aircraft you're using. 

    Paul

  4. When you get 0 back it usually means the LVar doesn't exist.

    Please see John's advice above.

    Alternatively, if this is a new application you might consider using the new MSFSVariableServices class. It's much faster than the ReadLVar() method, although it's a bit more complicated to use. One advantage is that it has an event that tells you when the LVars have been scanned and are ready to use.

    See this post for details:

    https://forum.simflight.com/topic/92372-added-support-for-lvarshvars-access-in-msfs-via-john-dowsons-wasm-module/

    Or download the MSFSVariableServices example application from the website:

    http://fsuipc.paulhenty.com/#downloads

    Paul

  5. Hi Matt,

    Quote

    Is there an offset to set five vs four digits?

    Yes, they were added for P3D which also allows 5 digits. Extended offsets are as follows and are 4 byte integers (int for c#, Integer for vb). Read these to see the format. It's pretty obvious as I remember.

    0x05C4: COM 1 Active
    0x05C8: COM 2 Active
    0x05CC: COM 1 Standby
    0c05D0: COM 2 Standby

     

    Quote

    how do you read 6538 2 BYTE x 2 AIR_PackSwitch[2] eng 2 value?  how do you get the value of the second bit?

    It will just be the stored in the offset after the one mentioned. 0x6538 is the first one and is one byte long. The second will be stored after it, so one byte later = 0x6539. 

    You just declare two offsets of Byte with each address.

    If you see an array of 2 byte integers (WORD x 2) you would add 2 to the original offset address to get the next item(s) as each 'word' is 2 bytes long.

    FLT32 x 2 you would need to add 4 as FTL32 is a 4-byte floating point.

    Paul

     

  6. Do you mean Microsoft.FlightSimulator.SimConnect.dll and FSUIPC_WAPID.DLL?

    Assuming you do:

    FSUIPC_WAPID.DLL is 64 bit only. So your application must run as a 64-bit process. The best way to do this is to set it to target x64 only. Not Any CPU.

    FSUIPC_WAPID.DLL is not a managed (.net) library. Therefore it cannot be linked into your application at compile time. It is only loaded at runtime. So this DLL can not prevent the application from compiling. If the architecture is wrong (e.g. your application is running at 32-bit) then you will get an error at runtime, not compile time. I surprised you're saying this is causing a compile problem.

    Microsoft.FlightSimulator.SimConnect.dll that comes with FSX is compiled to target 'Any CPU'. I don't have MSFS but the managed simconnect libraries for MSFS must be either 'Any CPU' or 'x64'. Therefore they should run ok in an x64 application.

    Are you using any other third-party dlls or Nuget packages? Maybe one of those is causing the issue.

    I suggest making a new blank project targeting x64 and adding in the libraries you need one by one. After adding each one, make sure it compiles and that you can still open the WAPID.dll connection. This might narrow down the problem for you.

    Paul 

     

     

  7. You've probably got this code at the class level, rather than inside a method.

    You can't use variables (sector1pol) to initialise other variables at the class level (sector1). 

    If you need these variable at the class (form) level then easiest fix is to move the initialisation into the constructor of the class. e.g. if it's a form do this:

            private FsLatLonPoint[] sector1pol;
            private FsLatLonPolygon sector1;
    
            public Form1()
            {
                InitializeComponent();
                this.sector1pol = new FsLatLonPoint[]
                {
                    new FsLatLonPoint(39.158189, -6.560815),
                    new FsLatLonPoint(39.44173, -6.291623),
                    new FsLatLonPoint(39.847553, -4.565154),
                    new FsLatLonPoint(39.594515, -4.687465),
                    new FsLatLonPoint(39.019832, -6.427709),
                    new FsLatLonPoint(39.158189, -6.560815)
                };
                this.sector1 = new FsLatLonPolygon(sector1pol);
            }

    Paul

  8. Hi,

    The PMDG_737_NGX_Control enum will not work with the MSFS PMDG aircraft. It was written for the FSX and P3D aircraft.

    PMDG changed the way they handle controls in the new MSFS aircraft. Everything gets sent as a parameter to the built-in ROTOR BRAKE control.

    As far as I know they have not finalised the SDK for the MSFS version. When they do I can build helpers into my DLL. Until then you can use this conversion code below to convert the old P3D control numbers into the new Rotor Brake parameters:

     

            public enum PMDGMouseCode
            {
                LeftClick = 1,
                RightClick = 2,
                MouseMove = 3,
                LeftRelease = 4,
                RightRelease = 5,
                MiddleClick = 6,
                WheelUp = 7,
                WheelDown = 8
            }
    
            private void sendPMDGControl(PMDG_737_NGX_Control control, PMDGMouseCode mouseCode)
            {
                // Convert P3D control to MSFS equivalent
                int msfsControl = (((int)control - (int)PMDG_737_NGX_Control.THIRD_PARTY_EVENT_ID_MIN) * 100) + (int)mouseCode;
                // Send converted control via RotorBrake 
                FSUIPCConnection.SendControlToFS(FsControl.ROTOR_BRAKE, msfsControl);
            }

    E.g. Then you can send your control like this:

    sendPMDGControl(PMDG_737_NGX_Control.EVT_MCP_HDG_SEL_SWITCH, PMDGMouseCode.LeftClick);

    As for the PMDG offsets, you will need to ask @John Dowsonabout that. Usually the problem is that you haven't enabled the SDK broadcast in the PMDG .ini file.

    Paul

  9. Yes; the short explanation is:

    Create two FsLatLonPoint objects. The constructor takes the Lat/Lon in decimal degrees or FsLat/FsLon objects.

    Then with one of the objects you can call DistanceFromInFeet(), or DistanceFromInMetres() and pass the other FsLatLonPoint object.

    For more details about this and other Lat/Lon helpers see the example code application, specifically the section called "Lon/Lat Helper Classes". The distance example is on the form called LL002_DistancesAndBearings.

    Paul

  10. Quote

    Is it possible to have access to Rotary Encoders too?

    Only if your encoders can be seen by FSUIPC as joystick button presses. This will depend on the drivers\software you use to read the encoders.

    Some encoders can be set up to simulate a joystick button press when they are rotated left, and another button when rotated right. Sometimes you will get two buttons for each direction, one for a slow turn and one for a fast turn. In this case you just use the encoders as if they were joystick buttons in FSUIPC, using the method described above.

    If your encoders cannot be set up like this then you won't be able to use the switches/buttons method described above. You will need to use different software to read the encoders and send the controls directly to FSUIPC. What that software is will depend on the specific hardware you are using.

    Paul

    • Like 1
  11. NOTE: This guide references an out-dated method for controlling the PMDG aircraft in MSFS. While it might still work, a better method is explained in this linked FAQ:

     

    Background

    PMDG Aircraft for MSFS do not use the normal controls provided by the flight sim. This means that many of the aircraft's switches cannot be assigned to buttons and keys using the list of controls in the FSUIPC dropdown boxes. Assigning a standard control in FSUIPC will likely do nothing in the PMDG aircraft when the button or key is pressed.

     

    Solution

    Instead of using the standard list of controls shown in the FSUIPC dropdown box, users must send codes as a parameter to the standard MSFS 'Rotor Brake' control. The parameter code specifies which switch to operate and what type of mouse click to simulate.

    The control numbers vary for each aircraft and are listed in the SDK that is installed alongside the aircraft.

    This guide will show you, step-by-step:

    1. How to find the SDK files
    2. How to calculate the 'Rotor Brake' parameter codes
    3. How to assign the code to buttons/keys in FSUIPC

    The specific examples shown will be taken from the PMDG 737-700, but the same method works for any PMDG aircraft with an SDK.

     

    1. Locating the SDK

    • From your main Flight Sim install folder, open the PMDG folder.
    • Then select the folder belonging to the aircraft you want to use. e.g. PMDG 737 NGXu
    • Then select the SDK folder
    • Locate the file with the .h extension. For the 737 it's called PMDG_NG3_SDK.h
    • You can open this file with Notepad or your favourite text editor.

    As an example, the document you need for the 737 will be:

    [FlightSimInstallFolder]\PMDG\PMDG 737 NGXu\SDK\PMDG_NG3_SDK.h

     

    2. Calculating the 'Rotor Brake' Parameter Code 

    2.1. Find the control you want to use.

    Search for the control by name, or look through the listed controls to find the one you want. They are helpfully grouped together by panel.

    The controls are listed under a comment:

    // Control Events

    You can search for this to find where the list of control numbers starts.

    As an example we'll use the "Autopilot CMD A" switch on the MCP. This is the relevant line in the 737 SDK:

    #define    EVT_MCP_CMD_A_SWITCH                    (THIRD_PARTY_EVENT_ID_MIN + 402)

    To calculate the control number for this switch we ignore THIRD_PARTY_EVENT_ID_MIN and take the number after it. In this case 402.

    NOTE: Some controls reference other controls. For example:

    #define EVT_EFB_L_BACK									(EVT_EFB_L_START + 1)

    For this you need to find the value of EVT_EFB_L_START and add 1. Searching for EVT_EFB_L_START we find this:

    #define EVT_EFB_L_START									(THIRD_PARTY_EVENT_ID_MIN + 1700)

    As before, THIRD_PARTY_EVENT_ID_MIN is always ignored. So we get the value of 1700.

    Adding 1 to this will give us the value for EVT_EFB_L_BACK. Therefore EVT_EFB_L_BACK would be 1700 + 1 = 1701.

    We have now calculated the control number. 

     

    2.2. Adding the Mouse Action Code

    You now need to add a number to tell the aircraft what kind of mouse interaction you want to simulate. (e.g. left click, right click, scroll wheel up).

    First multiply the control number you have so far by 100. In our example for EVT_MCP_CMD_A_SWITCH we get:

    402 * 100 = 40200

    Now you ADD the following number, depending on the mouse operation you want:

    1 for left mouse click
    2 for right mouse click
    3 for mouse move
    4 for left mouse button release
    5 for right mouse button release
    6 for middle mouse button click
    7 for mouse wheel up
    8 for mouse wheel down

    For our example, we'll have our key assignment simulate the left mouse button clicking on the CMD A autopilot button. So we'll need to add 1:

    40200 + 1 = 40201

    Now we have the final code number.

     

    3. Assigning the control to a button or key in FSUIPC

    Select [Assignments] -> [buttons + switches] or [key presses] in the FSUIPC7 menu. Then select the button or key to program.

    From the "control sent..." dropdown select Rotor Brake

    In the Parameter field below type in your calculated code number from the previous step. For our 'Autopilot CMD A' example, we enter 40201 

    If you're programming a key press, remember to press the [confirm] button.

    Here is our example control assigned to a button in FSUIPC:

    image.png.faa9e5aa0352df1669b1b95b50b81f15.png

    Your button or key press should now operate the switch in your PMDG aircraft.

    • Thanks 1
  12. 3 hours ago, 777ipod said:

    Are those new offsets available true the .net dll.

    Yes, you can use them. At the moment you will need to declare them as normal offsets with the correct type.

    The PMDG_737_NGX_Offsets helper class will not work because the offset addresses have changed.

    I will eventually add a new helper class for this aircraft after John releases the official FSUIPC version that includes these offsets. 

    Paul

  13. It's difficult to know where the problem is with the WASM module as there are many interacting parts.

    Please try the following to narrow it down:

    Instead of my example application, use John's WASMClien.exe program from the FSUIPC-WASMv0.5.9a.zip file. It's in the \WASMClient folder.

    If John's client doesn't work on your user's machine then you'll need to ask John about this. This program generates a log which John can look at.

    If John's client does work then it's something in my DLL. Try turning the log level to _DEBUG in my sample application source code. Recompile and run it again to see if the extra logging provides any useful information.

    Paul

  14. 26 minutes ago, kingm56 said:

    Paul, is there literature pertaining to the LogLevel property?

    There's not much - just what's on the intellisense.

    The default is LOG_LEVEL_INFO which won't give you errors.

    To see errors, try LOG_LEVEL_DEBUG first which will probably be sufficient. Failing that, you can try with the highest (LOG_LEVEL_TRACE) but that's very verbose.

    Paul

  15. Quote

    indicates that your client is requesting lvar updates. You should leave lvar updates to the WASM if using multiple WASM clients (i.e. if also using FSUIPC7). And if you do want to control lvar update frequency from the client, then you should turn of the lvar update in the WASM otherwise such calls will be ignored. However, this will not help with your current issue.

    When using MSFSVariableServices you should normally leave the LVARUpdateFrequency property set to 0. This is the default from version 3.2.20, so make sure you're not overriding it in your code.

    Quote

    There should be another WAPI log for your client, although I am not sure what this is called if/when using the .net client dll - Paul should be able to help with this...

    My DLL does not create a log file for the WAPI. It's up to the user to do that by setting the LogLevel property and handling the OnLogEntryReceived event.

    Quote

    Be aware that once you have started the WAPI connection, it should NOT be used until lvars/hvars are available. 

    This is automatically handled inside my DLL. The user doesn't directly interact with the events from the WAPI dll.

    Paul

  16. Quote

    Meaning that i can get the window that has the focus before send the key and return there? In an effort for the user no to be disrupted somehow?

    Yes. You can pass the handle of your application's form (e.g. this.Handle). The sim will still be given focus, but after the key is sent the focus will be returned to your form.

     

    FSUIPCConnection.SendKeyToFS(Keys.F12, SendModifierKeys.Control); // Flight Sim keeps focus

     

    FSUIPCConnection.SendKeyToFS(Keys.F12, SendModifierKeys.Control, this.Handle); // focus returns to this form

    Paul

    • Like 1
  17. The only things I can think of to check is:

    • Make sure your .NET program is running as 64bit. 
    • Make sure you're running your program at the same privilege level as MSFS. Either both 'As Administrator' or both not as administrator.
    • Try sending keys to another application like Notepad.exe to check the code.

    If it still doesn't work then maybe MSFS is not processing these kinds of messages. 

    Paul

  18. Yes you can try PostMessage then. (I wrongly called it SendMessage in the last post):

    I can't try it on MSFS as I don't have it, but it works with FS9. The following example is setting the pause function without giving focus to the Sim:

     

    First declare the PostMessage call and the KeyDown code:

            const UInt32 WM_KEYDOWN = 0x0100;
    
            [DllImport("user32.dll")]
            static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);

    This call requires the handle of the main window of the flight sim. You can get this from the process name. I don't know what the process name is for MSFS, you'll need to find out with a tool like Spy++ while MSFS is running. (Visual Studio -> TOOLS menu -> Spy++ -> Spy Menu -> Processes).

    using System.Diagnostics;

     

                IntPtr wHnd = IntPtr.Zero; // Handle to main FS window
                string simProcessName = "FS9"; // Example for Flight Sim 2004
    
                Process[] procs = Process.GetProcessesByName(simProcessName);
                if (procs.Length>0)
                {
                    wHnd = procs[0].MainWindowHandle; // Used later in PostMessage
                }
                else
                {
                    // Flight sim not loaded
                }

    Now you just need to call PostMessage to send the key presses:

    // Send P key to FS to pause/unpause
    PostMessage(wHnd, WM_KEYDOWN, (int)Keys.P, 0);

    Paul

    • Like 1
  19. There isn't because of the way Windows works. The Win32 API that send key press messages (SendInput) assumes that the application has focus.

    It's possible to send a KeyDown/KeyUp message to a window that doesn't have focus (using PostMessage), but this doesn't support modifier keys.

    If you want to control the sim without shifting the focus you need to use another method like Offsets, Controls (Event) or LVars.

    If these are not available, and your only choice is keyboard presses, then you're just stuck with having to give focus to the sim.

    Paul

  20. I've just released a helper DLL on NuGet called FSUIPCWebSocketClientDLL.

    This makes it easier for .NET applications to talk to my FSUIPCWebSocket server. This server is installed with FSUIPC7 but can be used with any version from FSUIPC3 onwards.

    The server runs on the Flight Sim computer and allows offsets, LVars and HVars to be read and written over a TCP/IP connection (even over the internet if your Flight Sim PC is accessible from the internet).

    It was written to allow Web Browser/JavaScript applications to use FSUIPC, but it can be used by any language that can use WebSockets and read/write JSON data structures. The new DLL makes this easy in .NET by handling the WebSocket/JSON transfers for you.

    The DLL targets .NET Standard 2.0 so it's possible to use this DLL with any operating systems than supports .NET Standard 2.0.

    If your application is only for Windows and you don't need access to FSUIPC across a network or the internet, or you are using WideClient.exe then the current FSUIPCClientDLL offers a much more comprehensive, feature-rich and streamlined way of writing .NET applications for FSUIPC. 

    Everything you need to know about the WebSocket server and the .NET Client is on the website:

    http://fsuipcwebsockets.paulhenty.com

    Paul

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.