2

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.

Kyle Delaney
  • 11,616
  • 6
  • 39
  • 66

2 Answers2

2

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().

BlueStrat
  • 2,202
  • 17
  • 27
  • Getting Started with Windows Touch only seems to apply to C++ (which I suppose should be expected). It mentions WM_TOUCH which I've discovered to be 0x0240 or 576, which isn't a message I'm receiving. It also mentions WM_GESTURE, 0x0119, 281, also not a message I'm receiving. The relevant messages I'm receiving are 582 (0x0246), 583 (0x0247), 585 (0x0249), and 586 (0x024A).I can't seem to find these messages referenced in any of your links, not even here: http://www.pinvoke.net/default.aspx/Constants.WM – Kyle Delaney Jun 23 '17 at 18:56
  • And I'm terribly sorry for my mistake, but I forgot to mention that I'm using Windows 10. I just assumed the messages would be the same. I just tested on Windows 7 and I am indeed getting WM_GESTURE messages and not any of the messages I'm getting in Windows 10.I suppose if I go this route I'll need to account for the messages being OS-specific. – Kyle Delaney Jun 23 '17 at 18:59
  • 1
    The messages you're receiving seem to be WM_POINTER messages - https://msdn.microsoft.com/en-us/library/windows/desktop/hh454903(v=vs.85).aspx – Cody Maust Jun 23 '17 at 22:31
  • Thank you, Cody! I'm looking into it now. – Kyle Delaney Jun 23 '17 at 23:40
0

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.

Kyle Delaney
  • 11,616
  • 6
  • 39
  • 66