MathT
MathT

Reputation: 65

Send key to a form even when minimized

I have a very basic C# program, with a simple textbox and some other stuff. I have a button, which triggers a timer, what I want is that with every tick of the timer I can send a key to the textbox (set so that sending a key to the form will send it to the textbox).

my code now is:

    private void timer2_Tick(object sender, EventArgs e)
    {
        SendKeys.SendWait("ciao");
    }

But this works only when the form is visible and with focus

EDIT: for some reasons I don't want to use the "textbox.text = text"

Upvotes: 2

Views: 1938

Answers (1)

Eugene Podskal
Eugene Podskal

Reputation: 10401

You can't use SendKeys because it sends input to the currently active window:

Because there is no managed method to activate another application, you can either use this class within the current application or use native Windows methods, such as FindWindow and SetForegroundWindow, to force focus on other applications.

But you can use WinAPI SendMessage function like it is described in greater details here.

Taking into account that you know the Form that textbox is contained in, you can get its handle using Control.Handle property, so it will look like:

public static class WinApi
{
    public static class KeyBoard
    {
        public enum VirtualKey
        {
            VK_LBUTTON = 0x01,
            ...
            VK_RETURN = 0x0D
        }
    }


    public static class Message
    {
        public enum MessageType : int
        {
            WM_KEYDOWN = 0x0100
        }

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SendMessage(IntPtr hWnd, MessageType Msg, IntPtr wParam, IntPtr lParam);
    }
}

private void timer2_Tick(object sender, EventArgs e)
{
    WinApi.Message.SendMessage(
        hWnd: this.textBox.Handle, // Assuming that this handler is inside the same Form.
        Msg: WinApi.Message.MessageType.WM_KEYDOWN,
        wParam: new IntPtr((Int32)WinApi.KeyBoard.VirtualKey.VK_RETURN),
        lParam: new IntPtr(1)); // Repeat once, but be careful - actual value is a more complex struct - https://msdn.microsoft.com/en-us/library/ms646280(VS.85).aspx
}

P.S.: You may also be interested in PostMessage function.

P.S.1: Though this solution should work, I'd like to point that ideally you shouldn't use such mechanisms to do something inside your own application - sending keys is not always reliable and can be difficult to test. And usually there is a way to achieve the desired result without resorting to such approaches.

Upvotes: 1

Related Questions