我正在编写一个c# WPF程序,它将文本消息发送到另一个程序的窗口。我有一个宏程序作为我的键盘驱动程序(Logitech g15)的一部分,它已经做到了这一点,尽管它不直接将击键发送到进程,而是发送到当前聚焦的窗口。它工作得很好,但我需要能够从我的程序以及发送输入。还有其他人在使用这个过程,所以从我的程序输入的文本消息需要足够快,这样我的文本就不会干扰他们的输入。问题是,当我尝试用c#程序这样做时,我得到了太多的延迟。宏程序(罗技g系列分析器)立即发送命令。我尝试了以下三个命令来发送消息到进程。(按慢到快排序)
SetForegroundWindow(_hWnd);
SendKeys.SendWait("{Enter}This is a keystroke input.{Enter}");
它可能在名称中,但它执行命令的速度很慢,以至于我实际上可以用眼睛跟随文本,因为它是一个字母一个字母地输入的。我试过使用"SendKeys"。方法,但我得到一个错误说:"SendKeys不能在这个应用程序中运行,因为应用程序不处理Windows消息。"
PostMessage((IntPtr)_hWnd, (uint)WMessages.WM_KEYUP, (int)key, (int)key);
PostMessage是快一点,但仍然不够快,我的程序的目的。此外,该方法在消息被进程读取之前返回,这意味着两个顺序的PostMessage调用可能不会发送顺序的消息。
SendMessage(_hWnd, 0x100, (int) VKeys.VK_2, (int) VKeys.VK_2);
这比PostMessage快,但不如Logitech的宏程序快。此外,接收程序处理输入的方式也很奇怪,显然与处理键盘"真正"输入的方式不同。
SetForegroundWindow(_hWnd);
const string text = "This is a keystroke input.";
IInputElement target = Keyboard.FocusedElement;
IInputElement target = InputManager.Current.PrimaryKeyboardDevice.FocusedElement;
var routedEvent = TextCompositionManager.TextInputEvent;
target.RaiseEvent(new TextCompositionEventArgs(InputManager.Current.PrimaryKeyboardDevice, new TextComposition(InputManager.Current, target, text)) { RoutedEvent = routedEvent });
这是我最后一次尝试。文本发送到进程的方式似乎是即时的。然而,自从Keyboard之后,我只能把它发送到我自己的程序中。FocusedElement返回null当我有另一个程序设置为前台窗口。如果有人能告诉我如何获得另一个窗口的IInputElement,我肯定想知道。或者,如果有人有一个更好的发送输入的方法的建议,我非常希望听到它。
规格:Windows 7, 64位Visual Studio 2010 Framework 4
首先,您是否有意在SendMessage
示例中使用WM_KEYDOWN (0x0100)
而不是WM_KEYUP (0x0101)
?这将只是按下键,而不会释放它们,因此应用程序将无法正确处理它们。
另一种值得尝试的方法是发送WM_SETTEXT,假设控件正确地解释它(如编辑控件或组合框)。
最后一个选择是使用SendInput,它在非常低的级别上合成键盘和鼠标输入,但与键盘的宏程序类似,这需要您激活正确的窗口并设置焦点,这可能相当痛苦。
根据您的程序窗口类型,您可以使用UI自动化。请看下面的例子:
使用UI自动化向文本框添加内容