Jump to content
The simFlight Network Forums

Sending keystrokes to MSFS without window focus


Recommended Posts

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

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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
Link to comment
Share on other sites

  • 2 weeks later...
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?

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 

  • Like 1
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • 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.