我正在制作一个供个人使用的应用程序,其中可以使用手写笔在当前屏幕上绘图,但不会中断正常使用(使用鼠标)。
目前,我正在尝试使用 WS_EX_TRANSPARENT 设置窗口以允许鼠标事件通过,但似乎手写笔事件也可以通过而不被捕获。
是否有任何其他方法可以用来传递鼠标/键盘事件,同时仍然允许手写笔事件?这是我的程序到目前为止的样子:
最佳答案
Disable the RealTimeStylus for WPF Applications MSDN 上指出:
[...] (WPF) has built in support for processing Windows 7 touch input [...] Windows 7 also provides multi-touch input as Win32 WM_TOUCH window messages. These two APIs are mutually exclusive on the same HWND.
这似乎意味着,对于给定的窗口,您可以接收手写笔事件或触摸事件,但不能同时接收两者。由于您确实想要处理手写笔事件,这意味着您无需费心过滤触摸事件。只剩下鼠标和键盘了。
起初我以为您可以使用自定义窗口过程(WndProc)并过滤掉鼠标和键盘消息。但是,WndProc(在 WPF 中使用时)实际上只是一种通知机制,您无法阻止接收到的消息。
我发现了一个名为 BlockInput 的 Windows API据说“阻止键盘和鼠标输入事件到达应用程序”。然而,从文档来看,这似乎是系统范围的而不是特定于应用程序的,因此可能对您没有任何用处。
我能想到的唯一其他方法是使用低级键盘或鼠标 Hook 。这需要一些 P/Invoke,但并不是太困难。这些 Hook 允许您注册在引发键盘和鼠标事件时调用的回调函数。优点是您可以阻止这些事件传播并有效地“吞噬”它们,这听起来正是您所需要的。
我不太喜欢发布一个基本上是“搜索...”的答案,但所涉及的代码量并不小,并且已发布在 Stack Overflow 和其他地方的许多地方,因此:尝试搜索low level Keyboard hook c# wpf
,您应该会找到一些可能有帮助的代码!
即使您走这条路,您也可能会遇到麻烦的一件事是焦点。一旦您的“不可见”最顶层窗口收到它响应的手写笔消息,我假设焦点将切换到您的 WPF 应用程序,从而从之前使用的任何应用程序中“窃取”焦点。您也许可以再次使用 P/Invoke 设置主窗口的窗口样式标志以防止出现这种情况(根据 this SO question 的接受答案)。
原始答案
您可以重写窗口的相应键盘、鼠标和触摸预览...事件处理程序方法,并将它们标记为已处理。这具有阻止子控件接收这些事件的效果。
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,因为我认为如果没有前者,后者是不相关的。我可能还实现了一些不需要处理的内容,并且我不确定是否需要调用基本方法。正如我所说,不断尝试,直到找到适合您的东西。
关于c# - 传递所有鼠标事件,但不传递手写笔事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28869048/