在的WndProc我的WPF应用程序不'处理'WM_INPUT事件 [英] WndProc in my WPF app not 'handling' WM_INPUT event

查看:461
本文介绍了在的WndProc我的WPF应用程序不'处理'WM_INPUT事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我所收集到的有关鼠标输入处理迄今。请注意,我已经通过了一堆的不同来源,并通过实验了解到这一点,所以不要以此为福音:
1)鼠标事件与鼠标移动
2)和SetWindowsHookEx(WH_MOUSE_LL)处理LowLevelMouseProc起源看到事件第一
3)OS /应用程序框架处理的鼠标事件在一些高级别(鼠标光标移动)
4)WM_INPUT事件是由应用程序事件队列拾起和处理通过的WndProc(虽然此时处理不从步骤3)停止移动鼠标光标。
5分配)消息经由ComponentDispatcher
6分配)PreviewMouseMove和的MouseMove事件被触发,并且可以由应用来处理调度

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.

根据此,我想,以确保鼠标光标不移动是通过WH_MOUSE_LL过滤的唯一途径。当然,正如我前面在这篇文章中提到,没有在这一点上足够的信息来了解这款鼠标事件来自哪个设备,所以它的全有或全无的过滤,这不符合我的要求。

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.

我已经验证了我能够通过挂钩WH_MOUSE_LL,并从返回的值大于0砸事件该处理程序。现在我只需要弄清楚如何搭配在WH_MOUSE_LL水平从事件我的设备来产生一个鼠标事件......

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...

我也尝试返回值大于从0 WndProc的。本次活动还在我的应用程序进行处理。

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

我试图整合这是基于在Y旋转式输入装置机械USB鼠标的轴。我想这个设备仅仅表现为原始输入设备和用于设备(​​在我的应用程序的情况下至少)被丢弃产生的正常的鼠标移动事件。

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.

到目前为止,我已经能够使用主窗口和WindowIteropHandler AddHook挂钩的WndProc到我的WPF应用程序。我能够接收WM_INPUT事件,并从我的特定USB VID / PID设备(足以满足我的需求),过滤那些鼠标事件。

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).

我希望这标志着消息作为处理并返回0,将导致该消息不会传播到WPF窗口的其余部分,但事实并非如此......我仍然得到的MouseMove事件,当我把我的设备。这里是我的代码(简化删除处理WM_INPUT消息,但仍然表现出同样的问题):

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;
    }
}



任何人都知道如何来消除或以其他方式阻止鼠标事件我已经在WndProc中传播到主窗口处理?

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

TIA!

-Matt

推荐答案

长时间的谷歌搜索后,它看起来像别人已经描述和解决什么,我尝试使用UMDF做:< A HREF =http://oblita.com/Interception相对=nofollow> http://oblita.com/Interception

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.

这篇关于在的WndProc我的WPF应用程序不'处理'WM_INPUT事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆