none
How can I use Touch Injection to simulate touch points at set time in the future ?

    Question

  • Hi,

    I am using TCD.System.TouchInjection which has worked correctly for my simulation purposes so far.  I have been able to control touches at set times by using Task.Delay but this is not accurate enough for my purposes.  The PointerInfo struct has two fields Time and PerformanceCount that I believe should serve my needs, unfortunately neither do and I am receiving error message 87 "ERROR_INVALID_PARAMETER" after calling InjectTouchInput ( initialising is successful ).  Please can someone advise if it is possible and what is incorrect with the code below.

    public static PointerTouchInfo GetDownPointerInfo(int x, int y, int radius, uint id, uint orientation = 90, uint pressure = 32000) { 
            
                PointerTouchInfo contact = new PointerTouchInfo();
                contact.PointerInfo.pointerType = PointerInputType.TOUCH;
                contact.TouchFlags = TouchFlags.NONE;
                contact.Orientation = orientation;
                contact.Pressure = pressure;
                contact.PointerInfo.PointerFlags = PointerFlags.DOWN | PointerFlags.INRANGE | PointerFlags.INCONTACT;
                contact.TouchMasks = TouchMask.CONTACTAREA | TouchMask.ORIENTATION | TouchMask.PRESSURE;
                contact.PointerInfo.PointerId = id;

                contact.PointerInfo.PtPixelLocation.X = x;
                contact.PointerInfo.PtPixelLocation.Y = y;

                contact.ContactArea.left = x - radius;
                contact.ContactArea.right = x + radius;
                contact.ContactArea.top = y - radius;
                contact.ContactArea.bottom = y + radius;
                return contact;
            }
        
            public void Test_Inject_Down_Second_In_Future()
            {
                var downPointer = GetDownPointerInfo(100, 100, 10, 0);
                var initSuccess = TouchInjector.InitializeTouchInjection(1, TouchFeedback.INDIRECT);
                bool success = true;
                if (initSuccess)
                {
                    var highRes = Stopwatch.IsHighResolution;//true
                    var freq = Stopwatch.Frequency;//2742187
                    var pc = Stopwatch.GetTimestamp();
                    var oneSecondInFuture = (ulong)(pc + TimeSpan.TicksPerSecond);
                    downPointer.PointerInfo.PerformanceCount = oneSecondInFuture;
                    var injectSuccess = TouchInjector.InjectTouchInput(1, new PointerTouchInfo[] { downPointer });
                    if (!injectSuccess)
                    {
                        success = false;
                    }
                }
                else
                {
                    success = false;
                }
                if (!success)
                {
                    var lastError = GetLastError();//87 ERROR_INVALID_PARAMETER
                }
            }

    Many thanks

    Tony Hallett


    • Edited by T Hallett Friday, September 2, 2016 7:41 AM additional info
    Thursday, September 1, 2016 2:29 PM

All replies

  • Hi Tony,

    According to the documentation a ERROR_INVALID_PARAMETER is raised when both dwTime and PerformanceCount are specified. In your code you only set PerformanceCount, but maybe dwTime is initialized with a default value? I could also imagine that the delay is too long: try to decrease it to something like 200 ms.

    Also make sure that you don't try to inject other points while the first one is still active. If I remember correctly this also leads to problems.

    cheers

    Michael

    Sunday, September 4, 2016 11:26 AM
  • Hi Michael, 

    Thanks for your response.  If dwTime is initialized with a default value and this results in both dwTime and PerformanceCount to be specified how else are you supposed to set the PerformanceCount field and not dwTime ?! Also the documentation does not specify any limitations on dwTime and PerformanceCount other than "The value cannot be more recent than the current tick count or QueryPerformanceCounter value of the injection thread." So I think it should work the same for 200ms or 1 second.  It seems like a reasonable use case to be specific about the time that the pointer is simulated and dwTime/PerformanceCount read like that they serve this purpose.

    Perhaps you have a suggestion of how I might be able to get a response to this question from the providers of the C++ API ?  I have  posted a question on StackOverflow, a community addition on the Touch Injection Reference API page and Sanjay Kumar Sinha's post https://social.technet.microsoft.com/wiki/contents/articles/6460.simulating-touch-input-in-windows-8-using-touch-injection-api.aspx

    Many thanks

    Tony 

    Monday, September 5, 2016 10:36 AM