如何确定如何在 Windows Forms 控件中使用 IMessageFilter 处理消息?

How do I determine how to handle messages using IMessageFilter in a Windows Forms control?

我想尽可能直接地访问触摸输入以避免可能与正常事件隧道和冒泡相关的任何延迟,所以我想我会尝试使用消息而不是事件。使用以下代码,我可以拦截发送到我的 WindowsFormsHost:

的任何消息
class FlashFormHost : WindowsFormsHost, IMessageFilter
{
    public FlashFormHost()
    {
        Application.AddMessageFilter(this);
    }
    public bool PreFilterMessage(ref Message m)
    {

        switch (m.Msg)
        {
            // These four messages should be ignored because they're on every frame.
            case 49783:
            case 275:
            case 512:
            case 581:
                break;
            default:
                MainWindow.Print(m.Msg + ": " + m.LParam + ", " + m.WParam);
                break;
        }
        return false;
    }
}

我每次触摸控件时都会收到三条消息:585、582 和 49413。每次我停止触摸控件时都会收到两条消息:583 和 586。

那么首先,我如何知道每条消息的含义?有没有地方可以查询这些留言号码?

此外,我猜我应该使用 Message.GetLParam() 来获取有关触摸的所需信息:x、y 和 ID。但是我怎么知道要传递给该方法的类型呢?

我一直在尝试查找有关此的信息,但一直未能找到任何可以解决我的问题的信息。似乎有一个 table 的系统消息 here 但我没有看到它提到触摸,它仍然没有解释在 C# 中传递给 GetLParam() 的类型。

编辑:我忘了说我正在使用 Windows 10。我没有意识到消息会在 Windows 版本之间发生变化。

So first of all, how do I know what each message is supposed to mean? Is there a place where I can look up these message numbers?

这里是 MSDN Reference TOUCH 消息。

在这里您可以找到解释触摸输入时使用的numerical declarations for TOUCH messages as well as the auxiliary data structures

Also, I'm guessing I should use Message.GetLParam() to get the needed information about the touches: x, y, and ID. But how do I know what type to pass to that method?

从我提供的参考资料中,找到在消息上传递的参数类型。如果它是指向结构的指针,您可以找到该结构的 Interop 声明 at PInvoke.net。将所需的结构声明复制到您的代码中,并在调用 Message.GetLParam().

时使用它们的类型

因此解决方案涉及跟踪大量链接(例如 https://msdn.microsoft.com/en-us/library/windows/desktop/ms632654(v=vs.85).aspx),然后查找 C++ 头文件以了解数据实际上是如何从消息的 wParam 和 lParam 属性中提取的,然后翻译C++ 变成 C#。为了解释我收到的 WM_POINTER 消息,我最终编写了如下代码:

    public static ushort LOWORD(ulong l) { return (ushort)(l & 0xFFFF); }
    public static ushort HIWORD(ulong l) { return (ushort)((l >> 16) & 0xFFFF); }
    public static ushort GET_POINTERID_WPARAM(ulong wParam) { return LOWORD(wParam); }
    public static ushort GET_X_LPARAM(ulong lp) { return LOWORD(lp); }
    public static ushort GET_Y_LPARAM(ulong lp) { return HIWORD(lp); }

这为我提供了我需要的所有信息,即触摸 ID 以及 x 和 y 值。