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

2k Views Asked by At

I want to access touch input as directly as possible to avoid any lag that may be associated with normal event tunneling and bubbling, so I thought I'd try using messages instead of events. With the following code I can intercept any message that's sent to my 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;
    }
}

I'm getting three messages every time I touch the control: 585, 582, and 49413. And I'm getting two messages every time I stop touching the control: 583 and 586.

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?

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?

I've been trying to look up information about this, but I haven't been able to find anything that solves my issues. There seems to be a table of system messages here but I don't see it mention touch, and it still doesn't explain what type to pass to GetLParam() in C#.

EDIT: I forgot to mention that I'm using Windows 10. I didn't realize the messages would change between Windows versions.

2

There are 2 best solutions below

0
On BEST ANSWER

So the solution involves following lots of links (such as https://msdn.microsoft.com/en-us/library/windows/desktop/ms632654(v=vs.85).aspx) and then looking up the C++ header files to know how data is actually extracted from the wParam and lParam properties of the message, and then translating the C++ into C#. In order to interpret the WM_POINTER messages I was getting, I ended up writing code like this:

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

This gave me all the information I needed, which was the touch ID and the x and y values.

4
On

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?

Here is the MSDN Reference for TOUCH messages.

Here you can find the numerical declarations for TOUCH messages as well as the auxiliary data structures that are used while interpreting touch input.

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?

From the references I gave, find the type of parameter that is being passed on the message. If it is a pointer to a structure, you can find the Interop declaration for that structure at PInvoke.net. Copy the required struct declarations to your code and use their type when calling Message.GetLParam().