MSDN 上的Disable the RealTimeStylus for WPF Applications 声明:
[...] (WPF) 已内置支持处理 Windows 7 触摸输入 [...] Windows 7 还提供多点触摸输入作为 Win32 WM_TOUCH 窗口消息。 这两个 API 在同一个 HWND 上是互斥的。
这似乎暗示,对于给定的窗口,您可以接收触控笔事件或触摸事件,但不能同时接收。当您确实想要处理触控笔事件时,这意味着您无需费心过滤触摸事件。就剩下鼠标和键盘了。
起初我以为您可以使用自定义窗口过程 (WndProc) 并过滤掉鼠标和键盘消息。但是,WndProc(在 WPF 中使用时)实际上只是一种通知机制,您不能阻止接收到的消息。
我发现了一个名为 BlockInput 的 Windows API,据说它“阻止键盘和鼠标输入事件到达应用程序”。但是,从文档来看,这似乎是系统范围的,而不是特定于应用程序的,因此可能对您没有任何用处。
我能想到的唯一其他方法是使用低级键盘或鼠标挂钩。这需要一些 P/Invoke,但这并不太难。这些钩子允许您注册在键盘和鼠标事件引发时调用的回调函数。优点是您可以阻止这些事件传播并有效地“吞噬”它们,这听起来就像您需要的那样。
我不太喜欢发布一个基本上说“搜索...”的答案,但所涉及的代码量并不重要,并且已在 Stack Overflow 和其他地方的许多地方发布,所以:尝试搜索low level keyboard hook c# wpf,您应该会找到一些可能有帮助的代码!
即使你走这条路,你也可能会遇到麻烦,那就是专注。一旦您的“不可见”最顶层窗口收到它响应的手写笔消息,我假设焦点将切换到您的 WPF 应用程序,从而从之前使用的任何应用程序中“窃取”焦点。您也许可以再次使用 P/Invoke 来设置主窗口的窗口样式标志以防止这种情况发生(根据接受的this SO question 答案)。
原始答案
您可以覆盖 Window 的相应键盘、鼠标和触摸 Preview... 事件处理程序方法并将它们标记为已处理。这具有阻止子控件接收这些事件的效果。
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,因为我认为后者在没有前者的情况下是无关紧要的。我可能还实现了一些不需要处理的东西,我也不确定是否需要调用基本方法。正如我所说,试验直到你得到适合你的东西。