9

I am starting a process from a Windows application. When I press a button I want to simulate the pressing of key F4 in that process. How can I do that?

[Later edit] I don't want to simulate the pressing of the F4 key in my form, but in the process I started.

Jainendra
  • 24,713
  • 30
  • 122
  • 169
Stefan Filip
  • 1,791
  • 3
  • 15
  • 25

3 Answers3

13

You can use System.Windows.Forms.SendKeys.Send("{F4}");

Patrick McDonald
  • 64,141
  • 14
  • 108
  • 120
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 1
    Thanks for your quick replies. I want to send the F4 key to the process started by my form, not to my form. – Stefan Filip May 05 '09 at 16:23
  • This is correct. From a note in the MSDN page linked above: 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. So you need to activate the window, then SendKeys the F4. – lc. May 05 '09 at 16:27
  • ...apparently line breaks in comments are stripped. The last line above (So...) is my own. – lc. May 05 '09 at 16:28
11

To send the F4 key to another process you will have to activate that process

http://bytes.com/groups/net-c/230693-activate-other-process suggests:

  1. Get Process class instance returned by Process.Start
  2. Query Process.MainWindowHandle
  3. Call unmanaged Win32 API function "ShowWindow" or "SwitchToThisWindow"

You may then be able to use System.Windows.Forms.SendKeys.Send("{F4}") as Reed suggested to send the keystrokes to this process

EDIT:

The code example below runs notepad and sends "ABC" to it:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace TextSendKeys
{
    class Program
    {
        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        static void Main(string[] args)
            {
                Process notepad = new Process();
                notepad.StartInfo.FileName = @"C:\Windows\Notepad.exe";
                notepad.Start();

                // Need to wait for notepad to start
                notepad.WaitForInputIdle();

                IntPtr p = notepad.MainWindowHandle;
                ShowWindow(p, 1);
                SendKeys.SendWait("ABC");
            }
    }
}
Patrick McDonald
  • 64,141
  • 14
  • 108
  • 120
  • Can you be more explicit on how I can set another process active? I mean could you post a code sample? – Stefan Filip May 05 '09 at 17:37
  • 2
    You can avoid the Sleep using notepad.WaitForInputIdle()- That way it will work in machines other than your :-) – Juanma May 05 '09 at 19:56
  • thanks, figured there'd be a better way, updated my answer :) – Patrick McDonald May 06 '09 at 08:57
  • 2
    I am using this approach in a WinForms application but have found that SendWait (and Send) only seem to work once. I am calling the sending code from a button click event handler. – Richard Ev Jul 02 '09 at 10:16
  • Still works fine for me, is your application taking the focus after the first Send? – Patrick McDonald Jul 02 '09 at 10:55
  • My target application (notepad, receiving the SendKeys) takes focus. However it only appears to process the SendKeys on the first invocation of my SendKeys-sending application. – Richard Ev Jul 02 '09 at 11:55
  • Maybe you should post this as a new question, I can't replicate it sorry – Patrick McDonald Jul 02 '09 at 12:41
  • @Richard E: did you solve this "only works once" problem? – hawbsl Jan 06 '10 at 18:09
  • 1
    I had the "work once" problem too. What worked out for me was using Jon Raynor's answers in this thread: http://stackoverflow.com/questions/7421840/why-does-sendkey-send-only-work-once-in-a-while – Aliza Jan 25 '12 at 08:08
1

You can focus the window (SetForegroundWindow WINAPI), and then use windows forms SendKeys to send F4.

Marineio
  • 415
  • 4
  • 10