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 (i.e. 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 (i.e. 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 (i.e. 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.