问题
I am trying to figure out how I can make my C# application to send keys to another application window, without focusing on it. I have a list of words and 3 notepads files. Imagine I have all 3 notepad windows opened in order, and my program would take the first word in the listbox and write it in the first Notepad window. The second word in the second Notepad window and third one in the third Notepad window. Then start over and continue. So I want it to post 1 word in each and continue like that over and over.
But I only figured out how to do it with 1 notepad window (while having it active).
int i = 0;
i = listBox1.SelectedIndex;
i = i + 1;
if (i > listBox1.Items.Count - 1)
i = 0;
listBox1.SelectedIndex = i;
string message = listBox1.SelectedItem.ToString();
SendKeys.Send(message);
SendKeys.Send("{ENTER}");
This would require me to first focus on the notepad window, start the timer and then keep focus on the notepad window. It would then just loop through the list and type the word (1 on each line). And it works fine. But I want to be able to do it on 3 windows.
And then I need to get the window title somehow, not the process name. I would have 3 processes called Notepad then. But if they are named Note1, Note2, Note3 how would I do that?
I need help to make some kind of list of what programs to write to:
listofprograms = ["Note1", "Note2", "Note3"];
And it would find the application windows opened with those names, then somehow write the text into those windows.
Could anyone help me out? Haven't found anything about this so far and trust me I've looked around!
回答1:
Unfortunately there is no great way to do this. SendKeys
is a really simple and desirable API but it only applies to the active window. There is no way to make it work on an inactive window nor is there an API with the same ease of access that works on inactive windows.
Generally when people run up against this problem they have to go one of two routes
- Physically active the apps you want to send the keys to one at a time
- Drop down to a much lower level of
SendMessage
orPostMessage
to send keyboard events
The second option is generally more reliable but harder to implement.
回答2:
SendKeys
is not made for this type of functionality. To do what you're looking for, you're going to need to use some Win32 API calls in your code. See How to send text to Notepad in C#/Win32? for reference.
回答3:
If you're looking for a way to send keys to an application, using SendKeys.Send(keys) is an option, but you need to bring the window to the top via the SetForegroundWindow API.
So, if you continue using your approach, you could use FindWindow, SetForegroundWindow to force the Notepad windows to be activated and focused, so that you could send the keys.
[DllImportAttribute("User32.dll")]
private static extern int FindWindow(String ClassName, String WindowName);
[DllImport("user32.dll")]
private static extern IntPtr SetForegroundWindow(int hWnd);
public int Activate(int hWnd)
{
if (hWnd > 0) {
SetForegroundWindow(hWnd);
return hWnd;
}
else {
return -1;
}
}
public int GetWindowHwnd(string className, string windowName) {
int hwnd = 0;
string cls = className == string.Empty ? null : className;
string win = windowName == string.Empty ? null : windowName;
hwnd = FindWindow(cls , win );
return hwnd;
}
Although there is also another solution, which could help you out. Here all Notepad processes are handled:
How to send text to Notepad in C#/Win32?
With some adaptions it should work for your case, too (basically you would iterate and loop through the notepad instances found and place a word in each instance).
You might also want to take a look at the following information about FindWindow:
http://www.pinvoke.net/default.aspx/user32.findwindow
SetKeyboardState:
http://www.pinvoke.net/default.aspx/user32/SetKeyboardState.html
As well as SendMessage:
http://www.pinvoke.net/default.aspx/coredll/SendMessage.html
You should find some useful hints in the examples and descriptions.
来源:https://stackoverflow.com/questions/21339502/sendkeys-to-inactive-application