使用 LowLevelMouseProc 捕获触摸事件并不适用于所有应用程序

pie*_*iet 5 c# touch setwindowshookex

tldr:我正在使用 LowLevelMouseProc 捕获触摸屏上的所有触摸事件。这适用于我的应用程序和其他一些应用程序,但不幸的是不适用于所有应用程序。有人可以解释一下为什么吗?

完整故事:

我有一个 C# 应用程序,它使用LowLevelMouseProc + SetWindowsHookEx来检测触摸屏上的触摸位置。该钩子使我能够捕获触摸屏上的所有触摸操作

  • 如果我的应用程序在前台
  • 对于 Windows 桌面(我的应用程序已最小化)
  • 对于某些应用程序,例如 Visual Studio 或 Firefox

不幸的是,这种机制并不适用于所有应用程序,例如,它不会捕获在 Google Chrome 覆盖的显示区域中进行的任何触摸。

  1. 这是否意味着,例如 Google Chrome,已经消耗了触摸事件并且不会调用后续事件处理程序(包括我的钩子)?其他人也做出了类似的观察?谁能解释这种行为?

更新:触摸挂钩甚至可以在 Chrome 中使用,但仅限于上下文菜单区域(例如,在右键单击网站时出现的弹出窗口中)。这可能支持 Chrome 消耗触摸事件的理论

其他人强调,LowLevelMouseProc 回调必须位于单独的 DLL 中。此外,其他人说还要求外部应用程序和 DLL 具有相同的体系结构(x86、x64)。请参阅此处的相关帖子

  1. 在我的项目中,所有触摸事件处理方法都在一个单独的DLL中。此外,回调有自己的线程。如上所述,这对于某些应用程序(但不是全部)效果很好,与我的项目(*.exe + *.dll)是否编译为 x86/x64 应用程序无关。

有趣的是,在捕获鼠标事件时,该钩子适用于所有应用程序,包括 Google Chrome 。对于鼠标和触摸事件,使用相同的回调:

[StructLayout(LayoutKind.Sequential)]
public struct MSLLHOOKSTRUCT
{
    public POINT pt;
    public int mouseData;
    public int flags;
    public int time;
    public UIntPtr dwExtraInfo;
}
Run Code Online (Sandbox Code Playgroud)

...更多代码...

if (wParam == WM.MOUSEMOVE)
{
    var info = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
    var extraInfo = (uint)info.dwExtraInfo;
    if ((extraInfo & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH)
    {// Touch Move
        Console.WriteLine("Touch move");
    } else
    {
        Console.WriteLine("Mouse move");
    }
}
Run Code Online (Sandbox Code Playgroud)

这意味着,首先必须发生 WM.MOUSEMOVE (=WM_MOUSEMOVE) 事件。然后,代码通过查看 info.dwExtraInfo 来识别触摸/鼠标事件。

  1. 这一观察结果与问题(1)类似,可能意味着 Google Chrome 有自己的 touch hook,并且不会调用后续回调(也许是出于安全原因?)。有人可以验证这一点吗?

  2. 最终我感兴趣的是捕获所有触摸事件,独立于前台的应用程序。有人知道更可靠的方法吗?