我最近才开始使用 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,我不知道为什么。