Search code examples
c++windows-10touchpen

How to inject pen inputs from a digitiser using InjectTouchInput() with PT_PEN on Windows 10


I am using the InjectTouchInput() API on Windows 10 to inject touch events from a separate digitiser. That works well (multi-touch etc.). There are quite a few examples out there of using the API for that, i.e. using a pointer type of PT_TOUCH, including one from Microsoft, so it wasn't too difficult to customise them to my needs.

However, I have not found any example of using other pointer types, especially PT_PEN - which I need when the digitiser gives me pen inputs. (I'd also be interested in PT_MOUSE, mainly to avoid having to use SendInput() or mouse_event().)

Whenever I call InjectTouchInput() with PT_PEN, it fails with ERROR_INVALID_PARAMETER. I've tried quite a few combinations of fields to set, but nothing (so far) works. The MSDN documentation doesn't describe what to do for PT_PEN (it doesn't describe much for PT_TOUCH, but at least there's one sample), so it's quite difficult to know what fields should be set, which ones should be ignored, any specific sequence of operations, etc. I've been scouring the net, but couldn't find any example of PT_PEN use.

Does anybody have sample code or know where to find any, knowledge of where useful documentation is located, or knows how InjectTouchInput() is supposed to be used for PT_PEN (and PT_MOUSE)?


Solution

  • It turns out that InjectTouchInput() is indeed only for touch inputs - not pen, mouse, or generic pointer.

    You might say that it's obvious, since you pass an array of POINTER_TOUCH_INFO entries to the API, but confusion arises because the documentation for POINTER_TOUCH_INFO (and all subsequent documentation) is describing the contents mostly as seen from someone who interprets contents he is given, and not content he is trying to set, and POINTER_INFO (the first element in POINTER_TOUCH_INFO) can specify a pointer type of PT_POINTER, PT_TOUCH, PT_PEN, PT_MOUSE, or PT_TOUCHPAD, so it feels kinda natural to think "wait, I can inject all these different types of pointers!"

    Of course, all the pointer types, despite having POINTER_INFO in common, takes slightly different parameters. For instance, there is orientation and pressure for PT_TOUCH (in POINTER_TOUCH_INFO), but tiltX, tiltY, rotation, and pressure for PT_PEN (in POINTER_PEN_INFO); but it would be easy to determine which info is relevant given that the pointer type is always the first field in the structures.

    Can InjectTouchInput() take POINTER_PEN_INFO entries instead of POINTER_TOUCH_INFO ones? No, it can't - I tried, just in case it would work.

    It seems like a missed opportunity by Microsoft to make the API more generic from the start and accept all the supported types of pointers, rather than be limited to touch inputs. At the very least, pen injection should have been straightforward, given that there is a POINTER_PEN_INFO structure (I haven't found structures for the other pointer types besides POINTER_TOUCH_INFO).

    Half-way through this thread from 2014 is the mention that "there is no [...] API for pen injection", and things haven't improved since then, so a driver for pen injection is still required. Having said that, the Windows UI Automation API can apparently inject all pointer types (and a game pad to boot), but that's only supported from Windows 10 Anniversary Edition (and I haven't tried it).