C#

Windows 8 TouchInjection with C#

The Windows 8 platform provides an API to inject touch events (WM_TOUCH..) via a C++ API. The API is relatively easy to use, but not available in C#, unless you do DllImport/PInvoke.

I found this to be kind of tricky, but finally I succeeded to make a C# library that can be used to use the TouchInjection API from C#. You can find TCD.System.TouchInjection on NuGet, or have a look at the TouchInjection.cs file itself.

You may notice that I renamed all the strucs, enums and classes to look nicer than their C++ counterparts. The IntelliSense descriptions are available for almost everything! (I got them from the documentation on msdn..)

I’ve made a sample application for the MSDN Code Gallery as well.

Here’s a small collection of useful resources regarding the TouchInjection API:

C++ sample application

C++ TouchInjection API walkthrough

15 comments

  1. Regard

    Thank you very much for this, I was on the border of having to rewrite a 6 month C# application into a C++ application because i could not get the touchinject function to work, but fortunately thanks to your dll i wont need to do that. Thank you very VERY much for the code example.

  2. Josh Santangelo (@endquote)

    Thanks for this — I am trying to use it to make something like Surface Stress for Windows 8. I have it working with basic touches, but am finding that InjectTouchInput returns false when given arguments that seem valid. When this happens, there are errors in the Windows event log like this:

    A pointer device did not report a valid unit of angular measurement.
    A pointer device reported a bad angular physical range.
    A pointer device reported a bad angular logical range.

    I do not see anything in the documentation or in the API regarding anything “angular”, so I’m unsure how to work around this.
    http://msdn.microsoft.com/en-us/library/windows/desktop/hh454916.aspx

    Looks like there is a similar question here:
    http://stackoverflow.com/questions/18348725/

    Any insight would be useful!

    1. thecake

      Hello,
      Interesting project you have there!
      I remember that there’s a way to send angular information using the API. I believe it is in the PointerInfo class.. Do you use c# or C++?
      Take a look at http://touchinjector.codeplex.com – in the source code you can see how the implementation should work.

      I’ll also take look if there’s a C# TouchInjection sample and, if not make one.

      Let me know when you finish your tool, then I will test my apps – though I’m sure that all of them will crash =p

      1. Josh Santangelo (@endquote)

        Thanks for replying. You can follow along with the progress here. The PointerInfo objects are created here and actually injected here. I think I’m creating the objects very similarly to your C# sample and the TouchInjector sample (thanks for that link, I’ll probably have a use for it). The strange thing is that InjectTouchInput returns true for a few frames, but then false with the angular error later. I’ll keep playing with it, but it’s very mysterious.

        1. thecake

          I tested your code and can reproduce the problem. I think it is related to the PointerInfo.PointerId value. When you PointerFlags.UP something, it must have the same PointerId as something already in contact..

          Take a look at this snippet:
          // Inject the active touches.
          PointerTouchInfo[] pointerInfo = pointers.Take(1).Select(p => p.Info).ToArray();
          pointerInfo[0].PointerInfo.PointerFlags = PointerFlags.DOWN | PointerFlags.INRANGE | PointerFlags.INCONTACT;// : PointerFlags.UP;
          bool result = TouchInjector.InjectTouchInput(pointerInfo.Length, pointerInfo);
          System.Diagnostics.Debug.WriteLine(string.Format("{0}:Injected ID:{1} with result {2}", DateTime.Now, pointerInfo[0].PointerInfo.PointerId, result));
          Debug.WriteLine(result);
          if (!result)
          {
          //Debugger.Break();
          }

          To test it, I also increased the interval to 1000 ms and reduced the number of simultaneous touch points to 1. When I ran your code first, there were all 256 touch points injected at the same time in the first frame. For this one frame I saw a lot of touch bubbles on the screen.
          The code above can inject multiple PointerFlags.DOWN points and I think that by fixing the PointerId thing, you can successfully release them^^

  3. Josh Santangelo (@endquote)

    Thanks for trying it out, that’s a huge help! I don’t think the IDs are the issue (I was persisting those), but you pointed me in the right direction. It seems that the PtPixelLocation of the UP injection needs to be the same as the last DOWN or it freaks out. I changed the behavior and it looks like it works much better now.

    I’m going to do some more testing and cleanup over the next little while and then post a preliminary release. I think if you star/watch the github repo it will notify you. I’d welcome your feedback.

    And yes, it probably will crash your apps. 🙂 We use Surface Stress at Stimulant for our touch kiosks and it always finds crazy issues that we wouldn’t find otherwise.

  4. Michael

    nice, exactly what i was looking for

  5. Isabella

    Hi, I have some questions regarding TouchInjection. When I simulate touch injection messages, I see some small rectangles and rounds on my screen, how can I define these to be invisible? Thanks,
    Isabella.

  6. Esneyder

    Hi, I know this is an a little bit old post, but I hope get an answer to my question 😛
    I’m using c++ but with the same library to inject touches, and I have a lot of problems trying to inject two points but with different events (FLAGS) each other.. My goal is be able to inject two points, with individual events each one, and if first contact[0] has an UP event, the second contact should still running without stop the process…So, how can I inject individual contacts (touches) with different events each one?

    Thank you so much 🙂

  7. kuchenzeit Post author

    As far as I remember it’s perfectly fine to have different flags for different contacts. I am not sure if you can independently update them too, but to be on the safe side, you can update both contacts simultaneously.
    To achieve what you described you can then simply not change the other contact.

  8. Karl

    Hi,

    I’m having trouble injecting multiple touch points. I’m following the source of TouchInjector 1.0 as an example. When I pass in a 2nd touch point it doesn’t show on the screen as the 1st one does, and when the 2nd touch flag is passed as “UP”, it makes the 1st disappear. Any help on this would be very much appreciated. I’ve also noticed that if the coordinates for one of the contact variables remains unchanged, it does not cancel the other one out.

    1. Karl

      Hello,

      Please disregard my comment. It turned out to be an error on my part. 😉

  9. Tony Hallett

    Hi Michael,

    I need to be able to simulate touch events at a precise point in time and I think that the API should allow for this but I am not succeeding. It would be greatly appreciated if you could look at the small demo code for a single down point a second in to the future.

    https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/01f07728-f401-45e0-9c91-e4337ac7b26d/how-can-i-use-touch-injection-to-simulate-touch-points-at-set-time-in-the-future-?forum=tabletandtouch

    Many Thanks,

    Tony

Leave a Reply to thecake Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.