首页 文章

直通所有鼠标事件但不是手写笔事件

提问于
浏览
1

我正在制作个人使用的应用程序,其中手写笔可用于在当前屏幕上绘图,但正常使用(使用鼠标)不会被中断 .

目前,我正在尝试使用WS_EX_TRANSPARENT设置窗口以允许鼠标事件通过,但似乎手写笔事件也可以在不被捕获的情况下通过 .

有没有其他方法可以用来通过鼠标/键盘事件同时仍然允许手写笔事件?这是我的程序到目前为止的样子:

Example picture

1 回答

  • 1

    Disable the RealTimeStylus for WPF Applications在MSDN上声明:

    [...](WPF)内置支持处理Windows 7触摸输入[...] Windows 7还提供多点触控输入作为Win32 WM_TOUCH窗口消息 . 这两个API在同一个HWND上是互斥的 .

    这似乎意味着,对于给定的窗口,您可以接收手写笔事件或触摸事件,但不能同时接收两者 . 由于您确实想要处理手写笔事件,这意味着您无需过滤触摸事件 . 那就是鼠标和键盘 .

    起初我以为您可以使用自定义窗口过程(WndProc)并过滤掉鼠标和键盘消息 . 但是,WndProc(在WPF中使用时)实际上只是一种通知机制,您无法阻止收到的消息 .

    我找到了一个名为BlockInput的Windows API,据说是"Blocks keyboard and mouse input events from reaching applications" . 但是从文档来看,这似乎是系统范围的,而不是特定于应用程序的,因此可能对您没有任何用处 .

    我能想到的另一种方法是使用低级键盘或鼠标钩 . 这需要一些P / Invoke,但这并不困难 . 这些钩子允许您注册在引发键盘和鼠标事件时调用的回调函数 . 优点是你可以阻止这些事件传播并有效地“吞下”它们,这听起来像你需要的 .

    我真的不喜欢发布一个基本上说"do a search for ..."的答案,但涉及的代码量并不重要,并且已经在Stack Overflow和其他地方的许多地方发布,所以:尝试搜索 low level keyboard hook c# wpf ,你应该找到一些可能有帮助的代码!

    即使你沿着这条路走下去,你可能遇到的一件事就是关注焦点 . 一旦你的"invisible"最顶层的窗口得到它响应的手写笔消息,我假设焦点将切换到你的WPF应用程序,因此"stealing"焦点来自之前使用的任何应用程序 . 您可以再次使用P / Invoke来设置主窗口的窗口样式标志以防止这种情况(根据this SO question的接受答案) .


    ORIGINAL ANSWER

    您可以覆盖相应的键盘,鼠标并触摸 WindowPreview... 事件处理程序方法,并将它们标记为已处理 . 这具有阻止子控件接收这些事件的效果 .

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            e.Handled = true;
            base.OnPreviewKeyDown(e);
        }
    
        protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
        {
            e.Handled = true;
            base.OnPreviewMouseDown(e);
        }
    
        protected override void OnPreviewMouseMove(MouseEventArgs e)
        {
            e.Handled = true;
            base.OnPreviewMouseMove(e);
        }
    
        protected override void OnPreviewMouseWheel(MouseWheelEventArgs e)
        {
            e.Handled = true;
            base.OnPreviewMouseWheel(e);
        }
    
        protected override void OnPreviewTouchDown(TouchEventArgs e)
        {
            e.Handled = true;
            base.OnPreviewTouchDown(e);
        }
    
        protected override void OnPreviewTouchMove(TouchEventArgs e)
        {
            e.Handled = true;
            base.OnPreviewTouchMove(e);
        }
    }
    

    我在这里完成了基本的键盘,鼠标和触摸事件 . 在一个简单的应用程序测试中它似乎可以做到这一点,我认为它仍然会让手写笔事件通过(我没有手写笔,我可以测试) .

    您可能需要尝试像这样处理哪些事件 . 我只做 KeyDown 例如,而不是 KeyUp 因为我认为后者与前者无关 . 我也可能已经实现了一些不确定是否需要调用基本方法的方法 . 就像我说的那样,试验直到你得到适合你的东西 .

相关问题