5

我最近才开始使用 Windows 8 Consumer Preview 的 InjectTouchInput。我一直在兜圈子,试图让这该死的东西发挥作用,但似乎无法让它真正互动。我在 c# 中工作,目前只在两个文本框和按钮中创建一个带有 x 和 y 坐标的 Metro 界面,这些按钮调用下面的函数以在这些坐标处触摸屏幕。这是做这件事的正确方法吗?

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

        }


    }

我尝试从网上找到的 InjectTouchInput API 中提取的几乎所有内容。我可以很好地 InitializeTouchInject,它的 Inject 位返回 false,我不知道为什么。

4

1 回答 1

5

我继续并根据微软提供的示例在 C++ 中创建了一些自定义函数,然后使用许多与以前相同的定义将其导入 C#,但没有放屁之前导致头痛的所有类型检查、指针和参数.

我使用的 DLL 文件是 TouchInjectionDriver.dll,可以在这里找到:

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

下面是我用来实现它的 C# 代码。

        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);
            }
        }
于 2012-04-15T21:39:28.787 回答