Question

I am creating a game in XNA and am looking to implement proper input-handling, which XNA lacks to a ridiculous degree. I have a class that implements IMessageFilter to intercept Window Messages and pass them along to TranslateMessage as a normal message pump would (but not XNA's, of course).

The part where I am stuck/unsure is how to to go from the System.Windows.Forms.Message that IMessageFilter.PreFilterMessage(ref Message) gives, to the struct tagMSG {...} that Windows API uses.

Now I can use P/Invoke as such:

    [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);

But the thing is that Message does not contain a definition for either time or POINT as required for the Windows Message.

My questions are the following:

  1. Can I fill in 0 for time, pointX and pointY and have TranslateMessage still working properly?
  2. I have seen other code that uses Marshal.StructureToPtr to copy the Message structure and pass that directly to TranslateMessage. Does Message contain hidden fields in the correct layout order? Because MSDN and Object Browser only give me the properties, and from those I should conclude that it is missing time and POINT and that the order is wrong.

So, what is the best way to pass the message to TranslateMessage so it can create those much wanted WM_CHAR's for me?

Was it helpful?

Solution

I decided to test question 2 by writing a simple program and these are the results:

On Win32 struct MSG is 28 bytes and Message is 20 bytes. Message adds a field result which is an IntPtr, but lacks the time and POINT fields.

Using either struct MSG or Message with Marshal.StructureToPtr + zeroing out the remaining 8 bytes yields the same results. Both have same hwnd, message, wparam and lparam and for both the rest of the properties are 0.

The conclusion is that Message does contain the first few members in the correct order, but since it is too small it is not safe to directly be used. However, the lack of crashing of a test program using the naive implementation seems to suggest that TranslateMessage does not look at the missing fields, but this is conjecture.

As for question 1, it seems to work without issue: TranslateMessage generates the correct WM_CHAR messages. I assume as long as the application doesn't use the time or POINT fields it should work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top