Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

InjectTouchInput Windows 8 C# not working (returns false)

I've just recently started playing with the InjectTouchInput for Windows 8 Consumer Preview. I've gone round and round in circles trying to get the darn thing to work but just can't seem to get it to actually interact. I'm working in c# and at the moment am only creating a metro interface with x and y coordinates in two text boxes and buttons which call the functions below to touch on the screen at those coordinates. Is this the right way to go about doing this?

protected unsafe class TouchDriver
    {


        public struct POINTER_TOUCH_INFO {
            public POINTER_INFO pointerInfo;   // An embedded POINTER_INFO header structure.

            public TOUCH_FLAGS touchFlags;          // Currently none.

            public Rect rcContact;             // Pointer contact area in pixel screen coordinates. By default, if the device does not report a contact area, this field defaults to a 0-by-0 rectangle centered around the pointer location. 

            public UInt32 orientation;         // A pointer orientation, with a value between 0 and 359, where 0 indicates a touch pointer aligned with the x-axis and pointing from left to right; increasing values indicate degrees of rotation in the clockwise direction.
                                        // This field defaults to 0 if the device does not report orientation.

            public UInt32 pressure;            // Pointer pressure normalized in a range of 0 to 256.
                                        // This field defaults to 128 if the device does not report pressure.
                                        // Question: Can this go from 0 to 1024 to match pen pressure?

        }
        public enum TOUCH_FLAGS
        {
            TOUCH_FLAGS_NONE = 0x00000000
        }

        public POINTER_TOUCH_INFO create_pointer_touch_info(POINTER_INFO pointerInfo, TOUCH_FLAGS touchFlags, RECT rcContact, UInt32 orientation, UInt32 pressure)
        {
            POINTER_TOUCH_INFO mi = new POINTER_TOUCH_INFO();
            mi.pointerInfo = pointerInfo;
            mi.touchFlags = touchFlags;
            mi.rcContact = rcContact;
            mi.orientation = orientation;
            mi.pressure = pressure;
            return mi;
        }
        public enum POINTER_INPUT_TYPE
        {
          PT_POINTER   = 0x00000001,
          PT_TOUCH     = 0x00000002,
          PT_PEN       = 0x00000003,
          PT_MOUSE     = 0x00000004 
        }
        public struct POINTER_INFO
        {
          public POINTER_INPUT_TYPE pointerType;
          public UInt32 pointerId;
          public UInt32 frameId;
          public HANDLE sourceDevice;
          public HWND hwndTarget;
          public Point ptPixelLocation;
          public Point ptHimetricLocation;
          public Point ptPixelLocationPredicted;
          public Point ptHimetricLocationPredicted;
          public POINTER_FLAGS pointerFlags;
          public DWORD dwTime;
          public UInt32 historyCount;
          // public UInt32 inputData;
          public DWORD dwKeyStates;
          public ULONGLONG Reserved;
        }
        public POINTER_INFO create_pointer_info(
            POINTER_INPUT_TYPE pointerType,
            UInt32 pointerId,
            UInt32 frameId,
            HANDLE sourceDevice,
            HWND hwndTarget,
            Point ptPixelLocation,
            Point ptHimetricLocation,
            Point ptPixelLocationPredicted,
            Point ptHimetricLocationPredicted,
            POINTER_FLAGS pointerFlags,
            DWORD dwTime,
            UInt32 historyCount,
            // UInt32 inputData,
            DWORD dwKeyStates,
            ULONGLONG Reserved)
        {
            POINTER_INFO mi = new POINTER_INFO();
            mi.pointerType = pointerType;
            mi.pointerId = pointerId;
            mi.frameId = frameId;
            mi.sourceDevice = sourceDevice;
            mi.hwndTarget = hwndTarget;
            mi.ptPixelLocation = ptPixelLocation;
            mi.ptHimetricLocation = ptHimetricLocation;
            mi.ptPixelLocationPredicted = ptPixelLocationPredicted;
            mi.ptHimetricLocationPredicted = ptHimetricLocationPredicted;
            mi.pointerFlags = pointerFlags;
            mi.dwTime = dwTime;
            mi.historyCount = historyCount;
            // mi.inputData = inputData;
            mi.dwKeyStates = dwKeyStates;
            mi.Reserved = Reserved;
            return mi;
        }
        public enum POINTER_FLAGS
        {
          POINTER_FLAG_NONE           = 0x00000000,
          POINTER_FLAG_NEW            = 0x00000001,
          POINTER_FLAG_INRANGE        = 0x00000002,
          POINTER_FLAG_INCONTACT      = 0x00000004,
          POINTER_FLAG_FIRSTBUTTON    = 0x00000010,
          POINTER_FLAG_SECONDBUTTON   = 0x00000020,
          POINTER_FLAG_THIRDBUTTON    = 0x00000040,
          POINTER_FLAG_OTHERBUTTON    = 0x00000080,
          POINTER_FLAG_PRIMARY        = 0x00000100,
          POINTER_FLAG_CONFIDENCE     = 0x00000200,
          POINTER_FLAG_CANCELLED      = 0x00000400,
          POINTER_FLAG_DOWN           = 0x00010000,
          POINTER_FLAG_UPDATE         = 0x00020000,
          POINTER_FLAG_UP             = 0x00040000,
          POINTER_FLAG_WHEEL          = 0x00080000,
          POINTER_FLAG_HWHEEL         = 0x00100000 
        }

        [System.Runtime.InteropServices.DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
        private static extern Boolean InjectTouchInput(UInt32 count, POINTER_TOUCH_INFO* pntTchInfo);

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern Boolean InitializeTouchInjection(UInt32 maxCount, DWORD dwMode);


        private const UInt32 MAX_TOUCH_COUNT = 256; // Can be as high as 256
        private const UInt32 TOUCH_FEEDBACK_DEFAULT = 0x1;
        private const UInt32 TOUCH_FEEDBACK_INDIRECT = 0x2;
        private const UInt32 TOUCH_FEEDBACK_NONE = 0x3;

        public unsafe static void MouseTouch(int x, int y)
        {
            bool ret = false;
            ret = InitializeTouchInjection(1, TOUCH_FEEDBACK_DEFAULT);
            if (!ret)
            {
                throw new NotSupportedException();
            }
            Point point = new Point(x,y);

            POINTER_INFO ptrInfo = new POINTER_INFO();
            POINTER_TOUCH_INFO* ptrTchInfo;
            ptrInfo.pointerType = POINTER_INPUT_TYPE.PT_TOUCH;
            ptrInfo.pointerId = 1;
            ptrInfo.ptPixelLocation = point;
            ptrInfo.pointerFlags = POINTER_FLAGS.POINTER_FLAG_PRIMARY;
            POINTER_TOUCH_INFO ptrTchInfobase = new POINTER_TOUCH_INFO();
            ptrTchInfo = &ptrTchInfobase;
            ptrTchInfo->pointerInfo = ptrInfo;
            ptrTchInfo->touchFlags = TOUCH_FLAGS.TOUCH_FLAGS_NONE;
            ptrTchInfo->rcContact.X = x - 2;
            ptrTchInfo->rcContact.Y = y - 2;
            ptrTchInfo->rcContact.Width = 4;
            ptrTchInfo->rcContact.Height = 4;
            ptrTchInfo->pressure = 128;
            ptrTchInfo->orientation = 0;



            ret = InjectTouchInput(1, ptrTchInfo);
            if (!ret)
            {
                throw new NotImplementedException();
            }

        }


    }

Almost all of that I've tried to lift from the InjectTouchInput API I found online. I can InitializeTouchInject fine, its the Inject bit thats returning false and I have no idea why.

like image 733
user1333628 Avatar asked Apr 14 '12 18:04

user1333628


1 Answers

I went ahead and create some custom functions in c++ based on the sample Microsoft provided and then went and imported that into C# using alot of the same definitions as before but without farting about with all the type checking, pointers and arguments that were causing headaches before.

The DLL file that I've used is TouchInjectionDriver.dll and can be found here:

http://www.mediafire.com/file/do2h6m04omjweb3/TouchInjectionDriver.zip

Below is the C# code I used to implement it.

        public enum TOUCH_MASK : uint
        {
            TOUCH_MASK_NONE = 0x00000000,
            TOUCH_MASK_CONTACTAREA = 0x00000001,
            TOUCH_MASK_ORIENTATION = 0x00000002,
            TOUCH_MASK_PRESSURE = 0x00000004
        }
        public enum POINTER_INPUT_TYPE : uint
        {
            PT_POINTER = 0x00000001,
            PT_TOUCH = 0x00000002,
            PT_PEN = 0x00000003,
            PT_MOUSE = 0x00000004
        }

        public enum POINTER_FLAGS : uint
        {
            POINTER_FLAG_NONE = 0x00000000,
            POINTER_FLAG_NEW = 0x00000001,
            POINTER_FLAG_INRANGE = 0x00000002,
            POINTER_FLAG_INCONTACT = 0x00000004,
            POINTER_FLAG_FIRSTBUTTON = 0x00000010,
            POINTER_FLAG_SECONDBUTTON = 0x00000020,
            POINTER_FLAG_THIRDBUTTON = 0x00000040,
            POINTER_FLAG_OTHERBUTTON = 0x00000080,
            POINTER_FLAG_PRIMARY = 0x00000100,
            POINTER_FLAG_CONFIDENCE = 0x00000200,
            POINTER_FLAG_CANCELLED = 0x00000400,
            POINTER_FLAG_DOWN = 0x00010000,
            POINTER_FLAG_UPDATE = 0x00020000,
            POINTER_FLAG_UP = 0x00040000,
            POINTER_FLAG_WHEEL = 0x00080000,
            POINTER_FLAG_HWHEEL = 0x00100000
        }
        public enum TOUCH_FEEDBACK : uint
        {
            TOUCH_FEEDBACK_DEFAULT = 0x1,
            TOUCH_FEEDBACK_INDIRECT = 0x2,
            TOUCH_FEEDBACK_NONE = 0x3
        }

        [DllImport("TouchInjectionDriver.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern bool InjectTouch(int x, int y, POINTER_INPUT_TYPE pt_input, int pressure, int orientation, int id, int rcContactTop, int rcContactBottom, int rcContactLeft, int rcContactRight, POINTER_FLAGS pointerFlags, TOUCH_MASK touchMask);
        [DllImport("TouchInjectionDriver.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern void setTouchFeedback(TOUCH_FEEDBACK fb);
        [DllImport("TouchInjectionDriver.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern void setDefaultRectSize(int size);
        [DllImport("TouchInjectionDriver.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern void setDefaultPressure(int pres);
        [DllImport("TouchInjectionDriver.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern void setDefaultOrientation(int or);

        [DllImport("User32.dll")]
        static extern Boolean MessageBeep(UInt32 beepType);

        public static void mouseclick(int x, int y)
        {
            bool ret;
            setTouchFeedback(TOUCH_FEEDBACK.TOUCH_FEEDBACK_INDIRECT);
            ret = InjectTouch(x, y, POINTER_INPUT_TYPE.PT_TOUCH, 3200, 0, 0, x - 4, x + 4, y - 4, y + 4,POINTER_FLAGS.POINTER_FLAG_DOWN|POINTER_FLAGS.POINTER_FLAG_INCONTACT|POINTER_FLAGS.POINTER_FLAG_INRANGE,TOUCH_MASK.TOUCH_MASK_CONTACTAREA|TOUCH_MASK.TOUCH_MASK_ORIENTATION|TOUCH_MASK.TOUCH_MASK_PRESSURE);
            if (ret)
            {
                ret = InjectTouch(x, y, POINTER_INPUT_TYPE.PT_TOUCH, 3200, 0, 0, x - 4, x + 4, y - 4, y + 4, POINTER_FLAGS.POINTER_FLAG_UP, TOUCH_MASK.TOUCH_MASK_CONTACTAREA | TOUCH_MASK.TOUCH_MASK_ORIENTATION | TOUCH_MASK.TOUCH_MASK_PRESSURE);
            }
            else
            {
                MessageBeep(0);
            }
        }
like image 149
user1333628 Avatar answered Sep 29 '22 07:09

user1333628