1

Note- This question is not a duplicate, because i'm asking how to send to the window that was/is active at the time the button is clicked. The answer that was linked to will find a window and make it active. That's different.

In C#, using Winforms, how can I send a character to the active window eg to notepad, when a button is clicked?

I have a form which has a button. Having opened notepad manually (not from my program), I want to click on the notepad window to activate it, then click my button and have it enter a character into that active window, notepad.

I can use the native .NET functionality and do Sendkeys.Send("A")

or I can do these two lines using the InputSimulator package installable via NuGet [1]

WindowsInput.InputSimulator s = new WindowsInput.InputSimulator();
s.Keyboard.TextEntry("A");

Either way, they don't put characters into notepad. That might be partly because the button takes focus.

I can do a solution mentioned here, to get the button to not take focus (though it doesn't stop my program's window from taking focus)

How to create a Button that can send keys to a conrol without losing focus - Virtual Keyboard

static void SetSty(Control control, ControlStyles flags, bool value)
{
    Type type = control.GetType();
    BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
    MethodInfo method = type.GetMethod("SetStyle", bindingFlags);
    if (method != null)
    {
        object[] param = { flags, value };
        method.Invoke(control, param);
    }
}

and I can call

SetSty(button1, ControlStyles.Selectable, false);

With that technique, I can click in a textbox on a form and then clicking my button can write text into that textbox without losing focus from the textbox.

But this doesn't work for an external notepad window

So if starting notepad (start..run..notepad), then clicking the button in my program, it takes the focus away from notepad, and doesn't enter text into that active notepad window.

[1] Installed InputSimulator via NuGet, no members accessible and https://inputsimulator.codeplex.com

barlop
  • 12,887
  • 8
  • 80
  • 109
  • 2
    Possible duplicate of [C# using Sendkey function to send a key to another application](https://stackoverflow.com/questions/15292175/c-sharp-using-sendkey-function-to-send-a-key-to-another-application) – Rand Random Nov 10 '17 at 16:00
  • @RandRandom While I haven't tested/seen that one yet, I don't think it's a duplicate because this one is specifically to the application that was active when the button was clicked. I guess if I could detect what window was active when the program then combine that with that method then that could work, if my program taking focus is inevitable – barlop Nov 10 '17 at 16:02
  • @RandRandom I will see if combining that question you link to, with this one https://stackoverflow.com/questions/115868/how-do-i-get-the-title-of-the-current-active-window-using-c will solve my problem.. will see.. – barlop Nov 10 '17 at 16:05
  • @RandRandom It's not a duplicate. See my note at the top – barlop Nov 11 '17 at 00:19
  • @RandRandom the correct answer which is the only answer and the accepted one, further shows how this is not a duplicate.. notice how the answer is not the answer to the question you thought this was a duplicate of. – barlop Nov 11 '17 at 01:07

1 Answers1

2

The form which contains the button, should be prevented from being foreground window. To do so, you need to add WS_EX_NOACTIVATE to your form:

private const int WS_EX_NOACTIVATE = 0x08000000;
protected override CreateParams CreateParams
{
    get
    {
        CreateParams createParams = base.CreateParams;
        createParams.ExStyle |= WS_EX_NOACTIVATE;
        return createParams;
    }
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398