WndProc in my WPF app not 'handling' WM_INPUT event

3

[Edit] Here's what I've gleaned about mouse input handling thus far. Note that I've learned this via a bunch of different sources and via experimentation, so don't take this as gospel: 1) Mouse event originates with mouse move 2) SetWindowsHookEx(WH_MOUSE_LL) handler LowLevelMouseProc sees event first 3) OS/app framework handles Mouse event at some high level (mouse cursor moves) 4) WM_INPUT event is picked up by app event queue and handled by WndProc (although handling at this time does not stop mouse cursor from moving in step 3). 5) Message is dispatched via ComponentDispatcher 6) PreviewMouseMove and MouseMove events are triggered and may be handled by the app.

Based on this, I think the only way to ensure that the mouse cursor doesn't move is to filter via WH_MOUSE_LL. Of course, as I've mentioned earlier in this post, there isn't sufficient information at this point to know which device this mouse event is coming from, so it's all or nothing filtering, which doesn't meet my requirements.


[Edit] I've verified that I'm able to drop events by hooking WH_MOUSE_LL and returning a value larger than 0 from the handler. Now I just need to figure out how to match a mouse event generated at the WH_MOUSE_LL level with events coming from my device...

I did try returning a value greater than 0 from WndProc. The event was still processed by my app.


I'm trying to integrate a rotary input device that's based upon the Y-axis of a mechanical USB mouse. I'd like for this device to behave solely as a raw input device and for the normal mouse move events generated by the device (at least in the context of my application) to be dropped.

So far, I've been able to hook WndProc into my WPF application MainWindow using WindowIteropHandler and AddHook. I'm able to receive WM_INPUT events and filter those for mouse events from my specific USB VID/PID device (sufficient for my needs).

I would expect that marking the message as handled and returning 0 would cause the message to not be propagated to the rest of the WPF window, but that's not the case... I'm still getting MouseMove events when I move my device. Here's my code (simplified to remove processing the WM_INPUT message, but still exhibits the same issue):

 public partial class MainWindow : Window
{
    private const int WM_INPUT = 0x00FF;

    public MainWindow()
    {
        InitializeComponent();
    }

    public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg == WM_INPUT)
        {
            // TODO - figure out why this doesn't halt further processing of this handled event
            handled = true;
        }
        return IntPtr.Zero;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct RAWINPUTDEVICE
    {
        [MarshalAs(UnmanagedType.U2)]
        public ushort usUsagePage;
        [MarshalAs(UnmanagedType.U2)]
        public ushort usUsage;
        [MarshalAs(UnmanagedType.U4)]
        public int dwFlags;
        public IntPtr hwndTarget;
    }

    private const int RIDEV_INPUTSINK = 0x00000100;

    [DllImport("User32.dll")]
    extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize);

    private void Window_SourceInitialized(object sender, EventArgs e)
    {
        WindowInteropHelper helper = new WindowInteropHelper(this);
        HwndSource source = HwndSource.FromHwnd(helper.Handle);
        RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[1];

        rid[0].usUsagePage  = 0x01;
        rid[0].usUsage      = 0x02;
        rid[0].dwFlags      = RIDEV_INPUTSINK; 
        rid[0].hwndTarget   = source.Handle;
        RegisterRawInputDevices(rid, (uint)rid.Length, (uint)Marshal.SizeOf(rid[0]));

        source.AddHook(WndProc);
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        e.Handled = true;
    }

    private void button1_MouseMove(object sender, MouseEventArgs e)
    {
        e.Handled = true;
    }
}

Anyone know how to dequeue or otherwise block a mouse event that I've handled in WndProc from being propagated to MainWindow?

TIA!

-Matt

c#
wpf
wndproc
asked on Stack Overflow Jul 6, 2012 by Matt • edited Jul 10, 2012 by Matt

2 Answers

3

After long hours of Googling, it looks like someone else has already described and solved what I'm trying to do using a UMDF: http://oblita.com/Interception

I was hoping I wouldn't have to go there, but it's looking like this is the only way to actually intercept events coming from a particular device.

answered on Stack Overflow Jul 20, 2012 by Matt
2

I also had this problem, and I solved it by running my application with Administrator privileges.

It seems that the WM_INPUT message is subject to the UIPI (User Interface Privilege Isolation). Check out the reference here:

SendMessage, PostMessage, and Related Functions

Although the method DefWindowProc() will deliver the message, it does not process it to the next application. But if there is an application that’s running as Administrator, such as Task Manager, Window Device Manager and so on, the lower privileges application can not received some of window messages delivered from the application mentioned above. This problem is not only the WN_IPUT, but alse the Hook.

answered on Stack Overflow Nov 1, 2019 by iDream • edited Nov 1, 2019 by Tzar

User contributions licensed under CC BY-SA 3.0