earthdog Posted June 10, 2022 Report Posted June 10, 2022 Is there any way to use SendKeyToFS or any other method to send keystrokes to MSFS without the app getting focus every time? Thanks.
Paul Henty Posted June 10, 2022 Report Posted June 10, 2022 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
earthdog Posted June 10, 2022 Author Report Posted June 10, 2022 11 hours ago, Paul Henty said: 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 SendMessage), 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 Thanks for the answer! I just want to send simple keystrokes to control the drone camera, and i will not be needing modifier keys. If i understand correctly this mean that i can use SendMessage?
Paul Henty Posted June 11, 2022 Report Posted June 11, 2022 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 1
earthdog Posted June 21, 2022 Author Report Posted June 21, 2022 On 6/11/2022 at 12:08 PM, Paul Henty said: 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 I tried your code and it does not work , giving no errors. I also tried with the following signature for PostMessage: [DllImport("User32.Dll", EntryPoint = "PostMessageA", SetLastError = true)] public static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); But also i get no keys sent to MSFS. Any idea why?
Paul Henty Posted June 21, 2022 Report Posted June 21, 2022 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
earthdog Posted June 22, 2022 Author Report Posted June 22, 2022 13 hours ago, Paul Henty said: 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 I will try what you propose and let you know. I also read somewhere that i may have to get hold of a child window to get the appropriate handle and not the parent MSFS window. On the other hand SendKeytoFS works just fine with the main window handle. Thanks.
Paul Henty Posted June 22, 2022 Report Posted June 22, 2022 2 minutes ago, earthdog said: On the other hand SendKeytoFS works just fine with the main window handle. The handle you pass to SendKeyToFS is for the window you want to return focus to, after the key has been sent. It's not the MSFS window handle. Paul 1
earthdog Posted June 22, 2022 Author Report Posted June 22, 2022 13 minutes ago, Paul Henty said: The handle you pass to SendKeyToFS is for the window you want to return focus to, after the key has been sent. It's not the MSFS window handle. Paul 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?
Paul Henty Posted June 22, 2022 Report Posted June 22, 2022 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 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now