将快速textinput发送到另一个进程(Window)

时间:2011-09-24 22:06:11

标签: c# wpf input sendmessage cross-process

我正在编写一个C#WPF程序,它将文本消息发送到另一个程序的窗口。我有一个宏程序作为我的键盘驱动程序(Logitech g15)的一部分已经这样做了,虽然它不会直接向进程发送击键,而是向当前聚焦的窗口发送。它运作良好但我需要能够从我的程序发送输入。还有其他人使用该过程,因此来自我的程序的输入文本消息需要足够快,以便我的文本不会干扰他们的输入。 问题是,当我尝试使用c#程序执行此操作时,我会遇到太多延迟。宏程序(Logitech G系列Profiler)立即发送命令。我尝试了以下三个命令来发送消息进行处理。 (按最慢到最快的顺序列出)

SetForegroundWindow(_hWnd);
SendKeys.SendWait("{Enter}This is a keystroke input.{Enter}");

它可能在名称中,但是这样执行命令的速度很慢,以至于我实际上可以用文字跟随文本,因为它是逐字输入的。我尝试使用“SendKeys.Send”方法,但我收到一条错误消息:“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

2 个答案:

答案 0 :(得分:2)

首先,您是否故意在WM_KEYDOWN (0x0100)示例中使用WM_KEYUP (0x0101)而不是SendMessage?这只是按键,永远不会释放它们,因此应用程序将无法正确处理它们。

另一种值得尝试的方法是发送WM_SETTEXT,假设控件正确解释它(如编辑控件或组合框)。

最后一个选项是使用SendInput在很低的水平上合成键盘和鼠标输入,但与键盘的宏程序类似,这需要你激活正确的窗口并设置焦点,这可以非常痛苦。

答案 1 :(得分:0)

根据您的其他程序窗口类型,您可以使用UI Automation。请在此处查看此示例:

Add Content to a Text Box Using UI Automation