Injecting Mouse Input in WPF Applications

I've been working on injecting input into a WPF application. What makes this project hard is that I need to be able to inject the input into the application even though it's running in the background (ie another application has the input focus). Using the SendInput() function is therefore out of the question.

So far, I've got keyboard input working but am having trouble injecting mouse input.

I used Spy++ to observe the window messages that get sent to the WPF window when I physically click the mouse button. I then simply craft these same mouse messages (such as WM_LBUTTONDOWN and WM_LBUTTONUP ) manually and send them explicitly to the WPF window to emulate mouse input.

Unfortunately, this doesn't work as expected (not even when I, for testing purposes, have set the WPF window as the foreground window).

I've added a button to my test WPF window which when clicked displays a message box. Injecting the appropriate mouse messages when I've manually positioned the cursor over the button doesn't cause the button to be clicked, however (ie the clicked event isn't fired by the WPF framework).

If I add a handler for mouse clicks on the actual dialog (the client area), that handler does get called if I position the cursor over the dialog itself and inject the same window messages as before:

this.MouseLeftButtonDown += WndMouseDown;

public void WndMouseDown(object sender, EventArgs e)
{
   ...
}

Strangely enough, if I change the push mode of the button to Press (ie it's considered clicked on mouse down rather than the default mouse up), the button clicked event is now fired when I inject the same messages as before. (It's worth mentioning that the handler from the example above correctly fires for both mouse downs and ups, so it'd seem the WPF framework does process both messages successfully.)

It seems like there are some other criteria that need to be fulfilled in order for a mouse clicked event to be fired by the WPF framework. Does anybody know how mouse input is handled internally in WPF, or why it's not interpreting my mouse up and down messages as a click on the button?

(It's worth mentioning that this approach [sending window messages] works fine on ordinary Win32 windows, such as the Start->Run dialog. The difference here is that WPF only has one physical Win32 window and the rest is WPF specific, which means all window messages go to that top-level window rather than the actual button.)

I've been searching high and low for an answer to this and would appreciate any thoughts or ideas.


I'd highly suggest going the UIAutomation route. You create an AutomationElement by window handle. Crawl to the button and invoke it. I'd just like to know how you managed to get the keyboard input working. I am currently trying to resolve the converse issue. How to get a WPF window (I've managed to get a hWnd to it via Win32 calls), to respond to virtual keyboard messages. I've logged ++spy sessions on the window in question and replicated it's input without success.


使用UI自动化来做到这一点 - 试图通过窗口消息手动模拟输入是一个教科书的错误,就像试图开始对俄罗斯的土地战争。


Your strategy is basically sound but in order to send a message to a window owned by another process you must first register the message.

Here is an article explaining the whole business. The sample code is unfortunately in VB but I'm sure that won't stop you.

链接地址: http://www.djcxy.com/p/44926.html

上一篇: 多行WPF文本框

下一篇: 在WPF应用程序中注入鼠标输入