Search code examples
c#winformstouchwindows-messagesimessagefilter

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


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.


Solution

  • 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.