InjectTouchInput Windows 8 C#不工作(返回false)
我刚刚开始使用InjectTouchInput for Windows 8 Consumer Preview。我一直在绕圈转圈试图让这件事情起作用,但似乎无法让它实际上互动。我正在使用C#,目前我只是在两个文本框和按钮中创建一个带有x和y坐标的地铁界面,它们调用下面的函数在这些坐标处触摸屏幕。这是做这件事的正确方法吗?InjectTouchInput Windows 8 C#不工作(返回false)
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罚款,其注入位返回false,我不知道为什么。
我继续在C++中基于Microsoft提供的示例创建一些自定义函数,然后使用与之前相同的定义将其导入到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);
}
}
太棒了!你是如何将TouchInjectionDriver.dll引用到你的C#项目中的?对于我来说,当我尝试在Visual Studio中添加引用时,我得到“无法添加引用...请确保该文件是可访问的,并且它是有效的程序集或COM组件”。任何想法? 我也在命令提示符下尝试过“regsvr32 TouchInjectionDriver.dll”,但得到了类似的错误! 谢谢! – ala 2012-04-16 12:10:15
您不需要在项目中包含.dll作为参考。 (事实上,除非你正在构建一个C++项目,否则你不能) 尽管如此,你可以将它包含在资源中,所以你知道它将与你的信息一起打包和部署。 只要你的可执行文件可以找到dll,包装代码应该可以运行 – 2013-04-11 21:48:44
我得到了这个运行,但是托管的InjectTouch也为我返回false,两者都连接了真实的触摸屏。 – 2013-12-21 00:14:26
调用InjectTouchInput后GetLastError返回什么? InjectTouchInput对于它的输入参数很挑剔,可能有些东西并不完美。 – 2012-04-14 22:26:59