Simulating touch into a WPF application is success only for 1st user action and the application doesn't recognize any further touch inputs

0

We are developing a touch simulating application which needs to simulate user actions read from a log file and automate over a WPF application. When using InjectTouchInput API we are able to simulate the first gesture action and rest of the actions are seen but it is not recognized as touch by the WPF application. InjectTouchInput API does not fail in these cases. If we replay the simulator, again first action alone is recognized as touch.

After using this simulator, it seems that the WPF application does not recognize any further touch inputs when we perform manually. The user has to restart the WPF application to perform touch actions. We are using Windows-10 machine. We have tried InitializeTouchInjection API before invoking the InjectTouchInput() too as per MSDN.. Any input to solve the issue is appreciated.

The code snippet is as below:-

bool HOOKDLL_API PlayMouseRecord()
{
    if( 0 != fopen_s( &g_RecordTextStreamFile, RECORD_FILE_NAME, "r" ))
    {
        MessageBox( NULL, TEXT( "Could not open RecordStreamFile Text format " ), TEXT( "Error hooking" ), MB_APPLMODAL );
        CloseFiles();
        return false;
    }

    if( 0 != fopen_s( &g_PlayerLogStreamFile, PLAYER_LOG_FILE_NAME , "w" ))
    {
        MessageBox( NULL, TEXT( "Could not open Player Log File" ), TEXT( "Error hooking" ), MB_APPLMODAL );
    }
    WPARAM wMouseMessage = WM_TOUCH;
    WPARAM wTouchMessage = WM_TOUCH;
    DWORD dwTickCount = 0;
    ULONG_PTR ulExtraInfo = 0;
    DWORD dwMouseData = 0;
    LONG lCoordinateX = 0;
    LONG lCoordinateY = 0;
    LONG lMask = 0;
    LONG lFlag = 0;
    LONG lID = 0;
    char szFormat[25] = {0};
    bool bStatus = true;
    bool bInitial = true;

    DWORD dwPrevTickCount = 0;
    DWORD dwTimeOut = 0;
    DWORD Errostatus = 0;

    InitializeTouchInjection( 50, TOUCH_FEEDBACK_INDIRECT );
    POINTER_TOUCH_INFO contact;
    memset( &contact, 0, sizeof( POINTER_TOUCH_INFO ));
    contact.pointerInfo.pointerType = PT_TOUCH;
    contact.orientation = 90; // Orientation of 90 means touching perpendicular to screen.
    contact.pressure = 32000;
    contact.touchMask = TOUCH_MASK_CONTACTAREA | TOUCH_MASK_ORIENTATION | TOUCH_MASK_PRESSURE;
    contact.touchFlags = TOUCH_FLAG_NONE;
    contact.pointerInfo.pointerId = 0;          //contact 0

    while( true )
    {
        fscanf_s( g_RecordTextStreamFile, "%lu", &dwTickCount );
        if( bInitial )
        {
            dwPrevTickCount = dwTickCount;
            bInitial = false;
        }
        fscanf_s( g_RecordTextStreamFile, "%s", szFormat, 15 );
        fscanf_s( g_RecordTextStreamFile, "%ld", &lCoordinateX );
        fscanf_s( g_RecordTextStreamFile, "%s", szFormat, 15 );
        fscanf_s( g_RecordTextStreamFile, "%ld", &lCoordinateY );
        fscanf_s( g_RecordTextStreamFile, "%s", szFormat, 15 );
        fscanf_s( g_RecordTextStreamFile, "%ld", &lMask );

        fscanf_s( g_RecordTextStreamFile, "%s", szFormat, 15 );
        fscanf_s( g_RecordTextStreamFile, "%ld", &lFlag );

        fscanf_s( g_RecordTextStreamFile, "%s", szFormat, 15 );
        fscanf_s( g_RecordTextStreamFile, "%ld", &lID );

        fscanf_s( g_RecordTextStreamFile, "%s", szFormat, 15 );
        if( EOF == fscanf_s( g_RecordTextStreamFile, "%llu", &ulExtraInfo ))
        {
            break;
        }

        contact.pointerInfo.ptPixelLocation.y = lCoordinateY;
        contact.pointerInfo.ptPixelLocation.x = lCoordinateX;
        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;
        switch( wMouseMessage )
        {
            case WM_TOUCH:
            {
                if (( lFlag & TOUCHEVENTF_DOWN) != 0)
                {
                    wTouchMessage = TOUCHEVENTF_DOWN;
                    contact.pointerInfo.pointerFlags = POINTER_FLAG_DOWN | POINTER_FLAG_INRANGE | POINTER_FLAG_INCONTACT;
                }
                else if (( lFlag & TOUCHEVENTF_UP) != 0 )
                {
                    wTouchMessage = TOUCHEVENTF_UP;
                    contact.pointerInfo.pointerFlags = POINTER_FLAG_UP;
                }
                else if (( lFlag & TOUCHEVENTF_MOVE) != 0 )
                {
                    wTouchMessage = TOUCHEVENTF_MOVE;
                    contact.pointerInfo.pointerFlags =  POINTER_FLAG_UPDATE | POINTER_FLAG_INRANGE | POINTER_FLAG_INCONTACT;
                }
                break;
            }
        default:
            break;
        }
        dwTimeOut = ( dwTickCount >= dwPrevTickCount ) ? ( dwTickCount - dwPrevTickCount ) :
                    ( dwTickCount + ( 0xffffffff - dwPrevTickCount));
        Sleep( dwTimeOut );
        dwPrevTickCount = dwTickCount;
        if( 0 == ::InjectTouchInput( 1, &contact ))
        {
            Errostatus = GetLastError();
            bStatus = false;
        }
        fprintf( g_PlayerLogStreamFile, "Tickcount: %lu Wparam: %llu Coordinate_x: %ld Coordinate_y: %ld ExtraInfo: %llu MouseData: %lu ErrorStatus: %lu\n",dwTickCount, wTouchMessage, lCoordinateX, lCoordinateY, ulExtraInfo, dwMouseData, Errostatus );
        Errostatus = 0;
    }
    dwTimeOut = ( dwTickCount >= dwPrevTickCount ) ? ( dwTickCount - dwPrevTickCount ) :
                ( dwTickCount + ( 0xffffffff - dwPrevTickCount));
    dwPrevTickCount = dwTickCount;
    Sleep( dwTimeOut );

    fclose( g_PlayerLogStreamFile);
    g_PlayerLogStreamFile = NULL;
    fclose( g_RecordTextStreamFile);
    g_RecordTextStreamFile = NULL;

    return bStatus;
}
c#
asked on Stack Overflow Jan 20, 2021 by Arun M G

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0