在IMessageFilter中从.NET调用TranslateMessage

时间:2014-04-22 22:29:56

标签: c# winapi xna pinvoke

我正在XNA中创建一个游戏,我正在寻求实现正确的输入处理,XNA缺乏这种程度。我有一个实现IMessageFilter的类来拦截Window Messages并将它们传递给TranslateMessage作为普通的消息泵(当然不是XNA)。

我遇到/不确定的部分是如何从System.Windows.Forms.Message提供的IMessageFilter.PreFilterMessage(ref Message)转到Windows API使用的struct tagMSG {...}

现在我可以使用P / Invoke:

    [StructLayout(LayoutKind.Sequential)]
    private struct MSG
    {
        public IntPtr   hwnd;
        public int      message;
        public IntPtr   wParam;
        public IntPtr   lParam;
        public uint     time;
        public int      pointX;
        public int      pointY;
    }

    [DllImport("user32.dll")]
    private static extern bool TranslateMessage([In] ref MSG m);

但问题是Message不包含Windows消息所需的timePOINT定义。

我的问题如下:

  1. 我可以为timepointXpointY填写0并让TranslateMessage仍能正常使用吗?
  2. 我见过其他使用Marshal.StructureToPtr复制Message结构并将其直接传递给TranslateMessage的代码。 Message是否包含正确布局顺序中的隐藏字段?因为MSDN和对象浏览器只向我提供属性,因此我应该得出结论,它缺少timePOINT并且订单错误。
  3. 那么,将消息传递给TranslateMessage的最佳方法是什么,以便它可以为我创建那些非常需要的WM_CHAR

1 个答案:

答案 0 :(得分:1)

我决定通过编写一个简单的程序来测试问题2,结果如下:

On Win32 struct MSG为28个字节,Message为20个字节。 Message添加了result字段IntPtr,但缺少timePOINT字段。

使用struct MSGMessage Marshal.StructureToPtr +将剩余的8个字节归零会产生相同的结果。两者都具有相同的hwndmessagewparamlparam,其余属性均为0。

结论是Message确实包含正确顺序的前几个成员,但由于它太小,因此直接使用是不安全的。但是,使用朴素实现的测试程序没有崩溃似乎表明TranslateMessage没有查看缺少的字段,但这是猜想。

对于问题1,它似乎没有问题:TranslateMessage生成正确的WM_CHAR消息。我假设只要应用程序不使用它应该有效的timePOINT字段。