I am trying to test out the Touch Injection API for injecting multiple touches while using Windows 8. To do this I am creating 5 contacts and then simulating hover and then drag and release.
This works fine for one touch contact. However nothing changes when I add 4 more contacts i.e. it produces the same as if there was only one contact. (I test by opening Paint on the right side of the screen and visual studio on the left. Then when the program runs a line gets drawn diagonally in the paint window). When I run GetLastError() after InitializeTouchInjection it gives me 5 which is an invalid access error.
Is there a flag I should be using? Does my computer need to have a certain driver installed? Whats wrong here?
Here is the code:
#include <windows.h>
void Drag(int x, int y){
POINTER_TOUCH_INFO contact_[5];
BOOL bRet = TRUE;
InitializeTouchInjection(5, TOUCH_FEEDBACK_DEFAULT);
for (int c=0;c<5;c++)
{
POINTER_TOUCH_INFO &contact=contact_[c];
memset(&contact, 0, sizeof(POINTER_TOUCH_INFO));
contact.pointerInfo.pointerType = PT_TOUCH;
contact.pointerInfo.pointerId = c; //contact 0
contact.pointerInfo.ptPixelLocation.y = y; // Y co-ordinate of touch on screen
contact.pointerInfo.ptPixelLocation.x = x+50*c; // X co-ordinate of touch on screen
contact.touchFlags = TOUCH_FLAG_NONE;
contact.touchMask = TOUCH_MASK_CONTACTAREA | TOUCH_MASK_ORIENTATION | TOUCH_MASK_PRESSURE;
contact.orientation = 90; // Orientation of 90 means touching perpendicular to screen.
contact.pressure = 32000;
// defining contact area (I have taken area of 4 x 4 pixel)
contact.rcContact.top = contact.pointerInfo.ptPixelLocation.y - 2;
contact.rcContact.bottom = contact.pointerInfo.ptPixelLocation.y + 2;
contact.rcContact.left = contact.pointerInfo.ptPixelLocation.x - 2;
contact.rcContact.right = contact.pointerInfo.ptPixelLocation.x + 2;
//contact.pointerInfo.pointerFlags = POINTER_FLAG_DOWN | POINTER_FLAG_INRANGE | POINTER_FLAG_INCONTACT;
contact.pointerInfo.pointerFlags = POINTER_FLAG_UPDATE | POINTER_FLAG_INRANGE ;//| POINTER_FLAG_INCONTACT;
}
InjectTouchInput(5, contact_); // Injecting the touch down on screen
Sleep(20);
for(int i=0;i<200;i++)
{
for (int c=0;c<5;c++)
{
POINTER_TOUCH_INFO &contact=contact_[c];
contact.pointerInfo.ptPixelLocation.x--; // updating the X Co-ordinate to x-100 pixels
contact.pointerInfo.ptPixelLocation.y++;
contact.rcContact.top = contact.pointerInfo.ptPixelLocation.y - 2;
contact.rcContact.bottom = contact.pointerInfo.ptPixelLocation.y + 2;
contact.rcContact.left = contact.pointerInfo.ptPixelLocation.x - 2;
contact.rcContact.right = contact.pointerInfo.ptPixelLocation.x + 2;
if (i==100)
contact.pointerInfo.pointerFlags = POINTER_FLAG_INCONTACT | POINTER_FLAG_INRANGE | POINTER_FLAG_DOWN;
if (i>100)
contact.pointerInfo.pointerFlags = POINTER_FLAG_INCONTACT | POINTER_FLAG_INRANGE | POINTER_FLAG_UPDATE;
}
InjectTouchInput(5, contact_); // Injecting the touch down on screen
Sleep(20);
}
// Lifts the touch input UP
for (int c=0;c<5;c++)
{
POINTER_TOUCH_INFO &contact=contact_[c];
contact.pointerInfo.pointerFlags = POINTER_FLAG_INRANGE | POINTER_FLAG_UP;
}
InjectTouchInput(5, contact_); // Injecting the touch down on screen
Sleep(10);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
Drag(1300,500);
}
A couple of points:
Make sure that InitializeTouchInjection
returned TRUE
.
Note that TOUCH_FEEDBACK_DEFAULT
is affected by the settings in the Pen and Touch control panel, so use TOUCH_FEEDBACK_INDIRECT
instead because this overrides those options.