使用setwindowshookex(user32.dll)禁用触摸屏鼠标设备事件

Pro*_*mer 6 c# wpf hook mouseevent touch

我有一个WPF C#应用程序.我有双屏幕,我想在其中一个屏幕上取消鼠标事件,因为它是一个触摸屏,当用户按下它时它会将焦点从主屏幕上移开.我想在向用户请求数据时启用触摸,然后阻止它.

我找到了一些关于使用user32.dll的应用程序挂钩的好例子,这有助于我捕获设备输入.一个例子显示在这里:http://www.pinvoke.net/default.aspx/user32.setwindowshookex.而另一个,更适合鼠标事件可以在这里显示:如何避免鼠标移动触摸

我的问题不是捕获设备输入,而是禁用它.上面的第一个示例显示了如何捕获键盘输入并提取按键,但不禁用它.

第二个例子不起作用.它捕获鼠标事件,常规USB鼠标设备和触摸屏设备.我可以告诉哪个是哪个,但我无法取消触摸屏设备.在该示例中,new IntPtr(1);为触摸设备返回a .这对设备输入没有任何作用.

另一方面,当我做相反的事情时,意味着返回新的IntPtr(1); 每次鼠标事件但触摸事件,似乎我的常规鼠标根本不移动(触摸设备鼠标确实移动).

这种方法可以帮助阻止常规鼠标,但不能阻止触摸鼠标,因为我没有返回的代码会阻止这个鼠标(我找到这个鼠标并返回代码,我检查了很多次,但代码什么也没做).

这是我的代码基于以上示例:

   static readonly LowLevelMouseProc hookCallback = HookCallback;
        static IntPtr hookId = IntPtr.Zero;

        public DisableTouchConversionToMouse()
        {
            hookId = SetHook(hookCallback);
        }

        static IntPtr SetHook(LowLevelMouseProc proc)
        {
            var moduleHandle = UnsafeNativeMethods.GetModuleHandle(null);

            var setHookResult = UnsafeNativeMethods.SetWindowsHookEx(HookType.WH_MOUSE_LL, 
proc, moduleHandle, 0);
            if (setHookResult == IntPtr.Zero)
            {
                throw new Win32Exception();
            }
            return setHookResult;
        }

        delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);

        static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {

            if (nCode >= 0)
            {
                var info = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));

                var extraInfo = (uint)info.dwExtraInfo.ToInt32();

               // if ((extraInfo & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH)
                if (extraInfo>0)
                {
               Console.WriteLine("TOUCH SCREEN FOUND!");
                    return new IntPtr(1);
                }
            }

            return UnsafeNativeMethods.CallNextHookEx(hookId, nCode, wParam, lParam);
        }
   public enum HookType : int
        {
            WH_JOURNALRECORD = 0,
            WH_JOURNALPLAYBACK = 1,
            WH_KEYBOARD = 2,
            WH_GETMESSAGE = 3,
            WH_CALLWNDPROC = 4,
            WH_CBT = 5,
            WH_SYSMSGFILTER = 6,
            WH_MOUSE = 7,
            WH_HARDWARE = 8,
            WH_DEBUG = 9,
            WH_SHELL = 10,
            WH_FOREGROUNDIDLE = 11,
            WH_CALLWNDPROCRET = 12,
            WH_KEYBOARD_LL = 13,
            WH_MOUSE_LL = 14
        }

        [StructLayout(LayoutKind.Sequential)]
        struct POINT
        {

            public int x;
            public int y;
        }

        [StructLayout(LayoutKind.Sequential)]
        struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public uint mouseData;
            public uint flags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        [SuppressUnmanagedCodeSecurity]
        static class UnsafeNativeMethods
        {
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern IntPtr SetWindowsHookEx(HookType code, LowLevelMouseProc lpfn, IntPtr hMod,
                uint dwThreadId);

            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool UnhookWindowsHookEx(IntPtr hhk);

            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
                IntPtr wParam, IntPtr lParam);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern IntPtr GetModuleHandle(string lpModuleName);
        }
Run Code Online (Sandbox Code Playgroud)

use*_*466 2

如果您的主要目标是避免焦点从主窗口移动,那么有一个更简单的解决方法,使用 WS_EX_NOACTIVATE

请参阅:不获取焦点,但允许交互?