What does WPF use to capture mouse and keyboard input?

4.8k views Asked by At

I globally (system-wide) filter certain mouse clicks using SetWindowsHookEx and WH_MOUSE_LL. The problem is it doesn't work for WPF applications (all WPF applications detect mouse clicks whether or not I have instructed the system to ignore these clicks). I've already asked a similar question here, but I made an assumption that WPF uses DirectInput instead of standard Windows messages for detecting the input. But does it?

I've been able to find a code that was able to inject mouse clicks into WPF applications using SendMessage. If that's possible, then I think it somehow means WPF does not use DirectInput for mouse input. But then, why it's not possible to prevent WPF applications from detecting mouse clicks with SetWindowsHookEx?

Although this question is mainly about the mouse input, I would also like to know how it works for keyboard input as well.

Example

I've quickly created the following solution to reproduce the odd WPF behavior. It consists of 3 projects:

  • HookTester
    StartUp project, automatically launches other 2 projects, so you should be mainly concerned about this one. Installs mouse hook when launched, and uninstalls the hook when you close the form.

  • WinFormsTest
    Contains a TextBox with default context menu where you can test the right mouse button. When the HookTester is running, you should not be able invoke the context menu using right mouse button.

  • WpfTest
    Contains a TextBox as well, with custom context menu (although I could use default menu as well), so this is again the place to test right mouse button. You should not be able to invoke the context menu (using right mouse button) as long as HookTester is running, but for some reason, the menu will be showed anyway (Why???).

WARNING: When you run the solution, the HookTester project will start and will immediately install the hook to reject any right-buttom mouse clicks (system-wide). You can easily uninstall the hook simply by closing the HookTester form. Test with caution.

Download SO5036143.ZIP: mirror 1, mirror 2

2

There are 2 answers

9
Marat Khasanov On BEST ANSWER
  • WPF Window creates HwndSource (Window.CreateSourceWindow).
  • HwndSource creates HwndWrapper (HwndSource.Initialize).
  • HwndWrapper creates Win32 window with window procedure that delegate Windows messages to hooks, specified by HwndSource.
  • One hook is the HwndSource.InputFilterMessage that delegate Windows messages to four input providers: stylus, mouse, keyboard, appcommand.
  • Provider parses appropriate Windows message and invokes InputManager to raise input events on elements.

HwndMouseInputProvider process messages such as WM_MOUSEMOVE, WM_LBUTTONDOWN, etc. So I think there is no DirectInput used to handle mouse and keyboard input.

2
Akash Kava On

Even if you try to set filter, .NET Framework may have some undocumented API to put WPF's filter on high priority not allowing your filter to execute at all in order to make sure WPF works correctly.

WPF windows are same as normal window and they are supposed to work correctly with pre-existing input APIs as well as new APIs in order to make WPF work with remote desktop and other such software.

Update:

Windows Hook were provided in earlier windows API because that time the concepts like Event Bubbling and Preview of events were not available and for such implementations hooks were useful. WPF already provides event filtering with Preview events and bubbling of events, and that is the reason hooks may not be supported.

Hooks are not very standard part of API because only very few applications use them. May be you can post bug at Microsoft that their filter is not allowing your hook filter.