Search code examples
visual-c++windows-8touch

Why is only one touch being injected when using Touch Injection API with WIN8?


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

Solution

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