16

SetWindowsHookEx我使用和全局(系统范围)过滤某些鼠标点击WH_MOUSE_LL。问题是它不适用于 WPF 应用程序(无论我是否指示系统忽略这些点击,所有 WPF 应用程序都会检测到鼠标点击)。我已经在这里问过一个类似的问题,但我假设 WPF 使用DirectInput而不是标准的 Windows 消息来检测输入。但真的吗?

我已经能够找到一个能够使用SendMessage. 如果这是可能的,那么我认为这在某种程度上意味着 WPF 不DirectInput用于鼠标输入。但是,为什么不能阻止 WPF 应用程序检测鼠标点击SetWindowsHookEx呢?

虽然这个问题主要是关于鼠标输入的,但我也想知道它是如何用于键盘输入的。

例子

我快速创建了以下解决方案来重现奇怪的 WPF 行为。它由3个项目组成:

  • HookTester
    启动项目,自动启动其他2个项目,所以你应该主要关注这个。启动时安装鼠标钩子,关闭窗体时卸载钩子。

  • WinFormsTest
    包含一个带有默认上下文菜单的文本框,您可以在其中测试鼠标右键。当 HookTester 运行时,您应该无法使用鼠标右键调用上下文菜单。

  • WpfTest 也
    包含一个文本框,带有自定义上下文菜单(虽然我也可以使用默认菜单),所以这又是测试鼠标右键的地方。只要 HookTester 正在运行,您就不能调用上下文菜单(使用鼠标右键),但是由于某种原因,无论如何都会显示菜单(为什么???)。

警告:当您运行解决方案时,HookTester 项目将启动并立即安装挂钩以拒绝任何鼠标右键单击(系统范围)。您只需关闭 HookTester 表单即可轻松卸载挂钩。谨慎测试。

下载 SO5036143.ZIP: 镜像 1 ,镜像 2

4

2 回答 2

11
  • WPF 窗口创建 HwndSource (Window.CreateSourceWindow)。
  • HwndSource 创建 HwndWrapper (HwndSource.Initialize)。
  • HwndWrapper 使用将 Windows 消息委托给 HwndSource 指定的挂钩的窗口过程创建 Win32 窗口。
  • 一个钩子是 HwndSource.InputFilterMessage,它将 Windows 消息委托给四个输入提供程序:手写笔、鼠标、键盘、应用程序命令。
  • Provider 解析适当的 Windows 消息并调用 InputManager 以引发元素上的输入事件。

HwndMouseInputProvider处理WM_MOUSEMOVE、WM_LBUTTONDOWN等消息。所以我认为没有DirectInput用来处理鼠标和键盘输入。

于 2011-03-01T19:16:10.290 回答
1

即使您尝试设置过滤器,.NET Framework 也可能有一些未记录的 API 将 WPF 的过滤器置于高优先级,根本不允许您的过滤器执行以确保 WPF 正常工作。

WPF 窗口与普通窗口相同,它们应该与预先存在的输入 API 以及新的 API 一起正常工作,以使 WPF 与远程桌面和其他此类软件一起工作。

更新:

Windows Hook 是在早期的 Windows API 中提供的,因为那时事件冒泡和事件预览等概念不可用,并且对于此类实现,挂钩很有用。WPF 已经提供了带有预览事件和事件冒泡的事件过滤,这就是可能不支持挂钩的原因。

钩子不是 API 的标准部分,因为只有很少的应用程序使用它们。可能您可以在 Microsoft 发布错误,即他们的过滤器不允许您的钩子过滤器。

于 2011-02-27T08:10:55.753 回答