Jump to content
The simFlight Network Forums

Paul Henty

Members
  • Posts

    1,728
  • Joined

  • Days Won

    78

Everything posted by Paul Henty

  1. Looking through the control list document there is this control: FULL_WINDOW_TOGGLE 65553 There seems to be some confusion about if this is P3D only but it's worth a try for FSX. A dedicated control is much better than sending a key press. If that doesn't work or does something different than the full screen toggle then I'll have a look at the key press route. Paul
  2. Hi, I've looked at the SimConnect SDK and I can't see any support there for adding a menu separator. There's no mention of it in the FSUIPC docs either so I would say it's not possible via FSUIPC. If Pete knows differently I'm sure he'll chip in. Paul
  3. Hi Motus, I've highlighted where your mistakes are. It looks like you've copied and pasted from the one above, but not changed all the variable names. Paul
  4. Two things to check: 1. The FSUIPCClient.dll is in the same folder as your .exe. All supporting DLLs must be placed alongside your .exe. 2. If you've used the 'release' build profile, make sure it's also set to compile to a 32bit (x86) .exe. Otherwise it will run as a 64bit .exe and won't be able to load the FSUIPCClient.dll. for #2: go to the properties of your project go to the 'build' tab on the left, select the 'release' profile from the 'configuration' dropdown near the top. Make sure the 'platform target' is set to 'x86'. Paul
  5. The usual way to handle this is to attempt the connection and catch the error thrown if FSUIPC is not running. This could be because the user doesn't have it installed or because FSX isn't loaded yet. Either way, you can display a message or a status in your application to let the user know that your application cannot connect to FSUIPC. If you have a look at my C# Example Application there is code in there that attempts a connection and if it doesn't find one it will keep trying. Meanwhile, the connection status is displayed on the form. If the connection is ever lost it goes back to the looking state and the main functionality is suspended until the connection comes back. Paul
  6. I've reread your post where you did the logging. I think I misread it earlier. It seems to me now that line I quoted was not sent by PMDG but by your code. What you need to do is turn on the event logging in FSUIPC and press the keys on the CDU with your mouse and see what controls and parameters PMDG is sending. That will help us replicate the correct messages. Paul
  7. I've really no idea how you would use the mouse flags. Controls do have parameters, so my first thought was that the mouse flags could be send as the parameter to the control. However, looking at your log from FSUIPC it clearly shows the menu control being sent by PMDG without any parameter (it's 0). If you want to try sending the mouse flag you can but I don't have much expectation that it will work: To do this you need another offset. This one MUST be declared before the sendControl offset, or it won't work properly (you can set the values in any order you like). // Order is important! private Offset<int> controlParameter = new Offset<int>("SendControl", 0x3114, true); // Both in the SendControl group, not a typo! private Offset<int> sendControl = new Offset<int>("SendControl", 0x3110, true); private readonly int MOUSE_FLAG_LEFTSINGLE = 0x20000000; // Press MENU button sendControl.Value = THIRD_PARTY_EVENT_ID_MIN + 551; controlParameter.Value = MOUSE_FLAG_LEFTSINGLE; FSUIPCConnection.Process("SendControl"); If that doesn't work then you really need to ask PMDG directly or on their support forums how these CDU controls are meant to be used. Paul
  8. Hi Ralph, Here is the updated version of the DLL (Version 3.0 beta) containing the sub menu functionality. To update, either overwrite your existing DLL and XML file with the new ones, or you can put them in a new folder and redo the reference in the C# project. The sub menu functionality is the same as the main menu except you have to specify the parent menu: Here's some sample code which should be self-explanatory. In all other respects (e.g. responding to the user clicking them) the sub menus are exactly the same as the normal menu. I refer you back to the main 2.4 thread. ui = FSUIPCConnection.UserInputServices; // Add our main menu items // The first parameter is the key and can be whatever you want. // Second is the text to display // Third is whether to pause FS on selection ui.AddMenuItem("MenuA", "Menu A", false); ui.AddMenuItem("MenuB", "Menu B", false); ui.AddMenuItem("MenuC", "Menu C", false); // Adding sub menus to menu B // First is the ID of this sub menu // Second is the ID of the parent menu // Third is the test to display ui.AddSubMenuItem("SubMenuB1", "MenuB", "Sub B1"); ui.AddSubMenuItem("SubMenuB2", "MenuB", "Sub B2"); As an aside, I've improved the way the payload stations and fuel tanks work as you can now hold on to a reference to a particular tank or payload station between calls to RefreshData(). Before it was recreating new tank and payload objects forcing users to get new copies from PayloadServices after RefreshData(). It is still the case that you need to call RefreshData() at least once before any fuel tanks are available. I couldn't see an elegant way around that. Paul FSUIPCClient3.0_BETA.zip
  9. Thanks very much for the donation, it's much appreciated. I can't see anything wrong with your code. I can't test it properly because I don't have the PMDG 737. I've tested sending a normal 'fsx' control (parking brakes toggle) and it's working okay. Maybe you can adding this to the end of your controls and see if this one reacts. sendControl.Value = 65752; // parking brakes FSUIPCConnection.Process("SendControl"); If this doesn't work on the 737NGX then try on a stock FS aircraft, just to prove the code/dll/fsuipc is working okay. If it's just the 737NGX CDU events that aren't working, try enabling the event (non axis) logging in FSUIPC. You can show the log in a separate console window to get real time feedback. Then press the buttons on the CDU and see what events are being triggered. Make sure they are the ones you are expecting. You can also run your code and compare the events fired manually with the ones your code it firing. Paul
  10. Thanks for that Pete, I didn't know about those control for sending Key Presses. Ralph - here's an example of sending the key presses for your sequence: First you need to declare the offset to send the control to (0x3110). Here i've put it in it's own group and made it write only. Also I've declared the constant for the THIRD_PARTY_EVENT_ID_MIN value to make things easier. private Offset<int> sendControl = new Offset<int>("SendControl", 0x3110, true); private readonly int THIRD_PARTY_EVENT_ID_MIN = 0x00011000; // equal to 69632 Then to send the sequence you need this: // Press MENU button sendControl.Value = THIRD_PARTY_EVENT_ID_MIN + 551; FSUIPCConnection.Process("SendControl"); // Press FS ACTIONS> LSK5R sendControl.Value = THIRD_PARTY_EVENT_ID_MIN + 544; FSUIPCConnection.Process("SendControl"); // Press <FUEL LSK1L sendControl.Value = THIRD_PARTY_EVENT_ID_MIN + 534; FSUIPCConnection.Process("SendControl"); // Press digit 3 sendControl.Value = THIRD_PARTY_EVENT_ID_MIN + 563; FSUIPCConnection.Process("SendControl"); // Press digit 4 sendControl.Value = THIRD_PARTY_EVENT_ID_MIN + 564; FSUIPCConnection.Process("SendControl"); Etc... You could go to the trouble of declaring all the constants as well as the 'min' constant. You can then use those variable names instead of using the '+' syntax all the time. e.g. private readonly int EVT_CDU_L_4 = THIRD_PARTY_EVENT_ID_MIN + 564; then you can just use this to set the control value. It will make the code much more readable. sendControl.Value = EVT_CDU_L_4; Paul
  11. The DLL has nothing specific, but FSUIPC has a key send facility at offset 0x3200. It seems to be a 'front' for a normal Win32 SendMessage() however, so unless you're familiar with the Win32 API and working with bits and bytes it might be a bit of a challenge. The documentation for the key down message is here: (You'll need this to know what to set as the Iparam and Wparam). http://msdn.microsoft.com/en-us/library/windows/desktop/ms646280%28v=vs.85%29.aspx You'll also need to manage each key up as well. I wonder if the PMDG interface has a more direct way of simulating key presses for the CDU through a flight sim 'control' (aka 'events')? It's worth looking in the PMDG SDK for the control list (I think it's in the form of a C header file). This would be much easier than sending actual keyboard presses into the Flight Sim windows process.. If it does exist then report back and we'll go from there. If they don't have such a control then I could put a feature in the DLL to send real key presses to FSX so that you don't have to deal directly with the Win32 API parameters. It will make it much simpler. Paul
  12. new Offset<string>("info", 0x3D00, 24); Yes, the 24 is the number of bytes to read. This is only required for certain offset types where the length cannot be determined from the type itself. So with 'int' for example you don't need to specify the length because an 'int' is always 4 bytes. For strings and arrays the dll needs some extra info as strings don't have a fixed length. The "info" part is an example of the grouping feature. You don't have to use grouping, but it can make sense when you don't want to read some offsets as often as others. Typically in applications there is data that needs to be updated frequently (e.g. aircraft position, airspeed etc) and other data that may only be required infrequently or just once. To avoid reading more data than is required you can place offsets in named groups. The names can be anything you like. You can then choose when to Process() the different groups by passing the name to the Process() method as you've seen. You can also process multiple groups at once, see the user guide for how to do that. You could declare the offset like this: private Offset<string> aircraftName = new Offset<string>(0x3D00, 24); and then it will work with the normal Process(). It's really up to you how, or if, you use the grouping. Paul
  13. You need to call ps.RefreshData() before you try to get any tank objects back. I'm not happy with how that works so I look at improving this, but for now you need to call RefreshData() at least once to create the fuel tanks in the dll. Paul
  14. Seems this was a new feature for FSUIPC4. I don't know why I didn't include this feature in the DLL, but I'll fix this and get you a new version by the end of the week. Thanks for spotting this. Paul
  15. I have to apologise - I've read the FSUIPC documentation completely wrong. You can indeed do sub menu items. Let me look into it some more. Paul
  16. Nested menus are not possible via FSUIPC. The SimConnect interface (which is how FSUIPC mainly talks to FSX) only allows 16 items directly under the Add-ons menus. Paul
  17. Thanks for the information. I've just run your code here and the reason you're not reading back the new fuel level is that the refresh is too soon. It seems that FSX or FSUIPC needs a bit of time to adjust to the new values in the fuel tank. If you put a pause between them then it works as expected. // Get a reference to save so much typing later... PayloadServices ps = FSUIPCConnection.PayloadServices; // Get the latest data from FSUIPC ps.RefreshData(); // Display centre tank percentage string str1 = ps.GetFuelTank(FSFuelTanks.Centre_Main).WeightLbs.ToString("F0"); ps.GetFuelTank(FSFuelTanks.Centre_Main).WeightLbs = 16000; ps.WriteChanges(); Thread.Sleep(2000); // Wait 2 seconds for everything to catch up ps.RefreshData(); string str2 = ps.GetFuelTank(FSFuelTanks.Centre_Main).WeightLbs.ToString("F0"); this.Text = str1 + " " + str2; You probably don't need to wait a full 2 seconds, that's just what I used to test this. The 'get' part is getting the fuel tank object. Once you have got the fuel tank object you set the WeightLbs property on that object. If I break it into two steps you can see it makes more sense. FsFuelTank leftTank = ps.GetFuelTank(FSFuelTanks.Left_Main); leftTank.WeightLbs = 8000; Putting it all in one line just saves typing and creating a variable. You might want to break it out though if you need to do more work on the single tank. This will save running the GetFuelTank method over and over. So imagine some code like this: FsFuelTank leftTank = ps.GetFuelTank(FSFuelTanks.Left_Main); if (leftTank.WeightLbs < 1000 && automaticRefuelActive) { leftTank.LevelPercentage = 100; ps.WriteChanges(); } This makes more sense than calling GetFuelTank twice and also makes the code cleaner and easier to read. So now to the main problem of the PDMG737 not respecting the fuel level changes. What's probably happening is that the PMDG code is constantly updating the fuel levels in the FSX tanks, So when you write your level it's soon overwritten again by the PMDG code. The reason for this is so they can more accurately simulate fuel consumption and feeding fuel betweens tanks. There are special offsets in FSUIPC for the PMDG 737ngx which allow access to areas of the aircraft that are modelled outside of FSX. These would normally not be available to FSUIPC but Pete has integrated FSUIPC with PDMG's SDK. For details of how to enable this interface and the extra offsets available see the document called "Offset Mapping for PMDG 737NGX.pdf" in the FSUIPC Documents folder under your FSX modules folder. This will not help with your fuel however as they are all read-only. The document does however mention that certain aspects of the 737NGX can be changed by sending 'controls' via FSUIPC. These are listed in the PMDG 737 SDK documentation. I don't have this aircraft so I can't look myself, but there might be controls to set fuel levels. Another place you can look for help is the 'User Contributions' forum under Pete's main support forum. Someone may have already solved this problem. Also if PMDG have forums then you could also try asking there. Paul
  18. If you write fuel tank levels with WriteChanges() then these should show up instantly in the sim. To really make sure the new level is being written, do another ps.RefreshData() after the WriteChanges() and then get the value again. At the moment your check is just reading the local (pending) value you've set as it's before the WriteChanges() call. If that comes back okay then here are some other thoughts: 1. If you just read the centre tank without changing it, does it match the gauge on the 737? 2. Is the change from your program reflected in the FSX Fuel dialog from the Aircraft menu? 3. Have you tried the code with the default 737? It may be that PDMG don't use the FSX fuel tanks at all, but use their own code. This sort of thing is common with complex add-on aircraft. 4. Maybe they are using one of the other centre tanks - try Centre_2 and Centre_3. I'm not sure about the nested menus - I'll look in to that tomorrow. Paul
  19. The documentation hasn't been updated since 2.0. The documentation for the new 2.4 features (which includes the payload services) is in the thread I linked you to. Please see the section in the user guide pdf called 'licence' (page 3) for details about donations. Paul
  20. Firstly you're declaring an offset in the method. This is not good practice as you run the risk of creating duplicate offsets. I recommend you always create the offsets at class (form) level. See the C# sample application (the top of the main form code) to see the correct place to put all the offset declarations. Turning to the main problem.... the centerFuelTankLevel is a variable representing the Offset<int> class. That's why ToString() is giving you that class name back. To get the value from the offset you need to use the Value property: this.Text = centerFuelTankLevel.Value.ToString(); Now, this will give you a large number which won't mean much. In the documentation Pete says the value here is scaled like this: So you need to reverse this scaling to get a value that's useful to you. double centerFuelPercent = (double)centerFuelTankLevel.Value / 128d / 65536d * 100d; this.Text = centerFuel.ToString("F0") + "%"; The (double) is a cast to convert the integer to a double so we can do floating point maths on it. The 'd' after the literal numbers is to define these as doubles instead of integers. The "F0" in the ToString() method is to format the number with 0 decimal places. Having said all of that, there is much easier way of working with payloads and fuel in my DLL. You need version 2.4 if you've not already got that. You can get it from the link below. At the bottom of the same thread is example code in C# of reading the fuel tanks with the "PayloadServices". With this method everything is converted to the various units for you (lbs, kg, percentages etc) and you don't need to worry about any conversions or scaling. http://forum.simflight.com/topic/74848-fsuipc-client-dll-for-net-version-24/ You code would become: try { FSUIPCConnection.Open(); } catch (Exception ex) { MessageBox.Show(ex.Message, "FSUIPC Connetion Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } // Get a reference to save so much typing later... PayloadServices ps = FSUIPCConnection.PayloadServices; // Get the latest data from FSUIPC ps.RefreshData(); // Display centre tank percentage this.Text = ps.GetFuelTank(FSFuelTanks.Centre_Main).LevelPercentage.ToString("F0") + "%"; If you need any more help with this let me know. Paul
  21. Sorry, posted before it was ready... Correct post below.
  22. I've just seen your replies in the main support forum with your PC specs. As you can see they are way better than mine, so there must be something else going on as you've got plenty of horse power and memory. I have no other suggestions though, sorry. Paul
  23. Hi Ralph, 1) FSUIPC should be loaded by FSX. If the FSUIPC menu is in the 'Addons' menu in FSX then it's running and the DLL should connect. If you continue to have problems connecting then the text in the message box might help diagnose the problem. 2) Yes, FSX (or WideClient.exe) needs to be running on the same machine. 3) If your PC/Laptop is fast enough and has enough memory it shouldn't be a problem running VS and FSX at the same time. My development laptop is an i7 running at 1.6 ghz and has 8gb of memory and runs both at the same time with no problem (although I have set FSX to low settings - see next paragraph). If your computer doesn't have much memory or has a slow processor then that could be the cause of your problems. You can try to improve things by turning down all the scenery options in FSX to very low settings and avoiding third-party scenery and aircraft. Also running in a very small sized window might help. I see you've got the PMDG 737 in your signature - that will not be helping matters if you have that loaded. Of course if this is essential for your application then there's not much you can do. If you have another PC on your home network that can run Visual Studio then you could invest in Pete's WideFS program. You'll need to buy a licence for WideFS (make sure it's version 7) and register it on the FSX PC. Then on the Visual Studio PC you can run WideClient.exe which is tiny in comparison to FSX. This will act like FSUIPC on the VS pc and will talk to the FSX PC over the network to get all your values, but it hardly uses any resources. So, yes, it sounds like you're doing everything right, it's just that your PC doesn't sound like it's up to the job of running two large programs like FSX and VS2013. Paul
  24. You could check the Ground Speed at offset 0x02B4. See the "FSUIPC4 Offset Status.pdf" for details. Paul
  25. Hi Tom, Your post appeared eventually - I think it's because new users need their first posts need to be reviewed by a moderator. Even though we dealt with this on PM I'm including my reply here in case anyone else comes across this post who has a similar problem. When using Hexadecimal notation in VB you need to add &H at the start of the number so the compiler knows that you want to use Hex. So in the brackets you need: (&H23A) Note that you can type (&H023A) but the code editor will probably remove the leading 0 to give the above. FSUIPC offsets are always given in Hex, so even if the offset address contains only numbers you still need to prefix with &H. If you don't, it will compile okay but you'll be getting a completely different offset. I notice from your code that you've declared (Dim'ed) the offset inside the Form load event. You should always declare the offsets at the class (form) level. This means they will be accessible from anywhere in the form and will prevent the offsets being created more than once. So your code should look more like this: Imports FSUIPC Public Class Form1 Dim secondfstime as Offset(Of Byte) = New FSUIPC.Offset(Of Byte)(&H23A) ' Other offsets go here Public Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load FSUIPCConnection.Open() End Sub End Class 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.