In a previous article I described the use of the SendKeys class. This type's methods provide a last resort way to control other applications, allowing you to send keys to the keyboard buffer and have them received by the target software. One of the problems with this approach is activating the target window in the first place. A solution to this problem is to use the SetForegroundWindow function.
SetForegroundWindow is a Windows Application Programming Interface (API) function, which you can call using Platform Invocation Services (P/Invoke). The function is quite simple. It has a single parameter, to which you provide the handle of the window to be activated. The function returns a Boolean value with true indicating success and false meaning that the window could not become active. Failures can happen for several reasons, such as the window being locked or having open menus.
Declaring the Function
To demonstrate SetForegoundWindow's use we'll create a simple program that finds all of the running instances of Notepad and uses SendKeys to send them some text. To begin, create a new Windows Forms application project. We'll be using the System.Diagnostics namespace to work with processes and System.Runtime.InteropServices for P/Invoke, so add the following two using directives to the code behind the automatically generated form:
We can now declare the Windows API function by adding the following within the code block of the form's class:
[DllImport("user32.dll", SetLastError = true)]
static extern bool SetForegroundWindow(IntPtr hWnd);
Calling the Function
Our sample program is simple. Firstly we will use the Process class's static method, GetProcessesByName, to obtain an array containing one Process object for each running Notepad. We'll then loop through each of the objects so that every Notepad instance is affected.
Within the Process class is the MainWindowHandle property. This holds the handle of the application's main window. As we are targeting Notepad this will be the correct handle, as Notepad can only include one window. We'll use the handle with SetForegroundWindow to activate each Notepad window in turn. We'll then send some text to the active window using SendKeys.
To add this functionality, start by creating a new button on the form in the form designer window. Double-click the button to add a click event and include the following code within the event's method:
Process processes = Process.GetProcessesByName("notepad");
foreach (Process process in processes)
You can now test the program. Start several instances of Notepad before running the program and clicking the button. You should see the text, "Hello, world!" added to each Notepad's text.
18 May 2013