如何模拟windows的touch操作,奋斗了几天终于出结果了,网上搜索了一个c#版本的,但是总是没有效果,并且c#要求的条件比较多,于是自己写了一个autoit轻量级的版本。autoit代码:
#RequireAdmin Local $retval = _SimulateTouch(10, 1000, 300, 300) MsgBox(0, "", $retval) ; #INDEX# ======================================================================================================================= ; Title .........: _SimulateTouch ; AutoIt Version : 3.3.6 ; Description ...: Simulate touch action. The function can work on minimum supported client: windows8[desktop apps only] and minimum supported server: windows server 2012[desktop apps only] ; Author(s) .....: qlplwh@163.com ; Dll(s) ........: user32.dll ; Parameters.....: $TouchTimes-----------Touch times; ; $TouchInterval--------Touch Interval; ; $TouchCoordinates_x---Touch coordinates x; ; $TouchCoordinates_y---Touch coordinates y ; returns........: int touch success times ; Requirements ..: ; =============================================================================================================================== Func _SimulateTouch($TouchTimes, $TouchInterval, $TouchCoordinates_x, $TouchCoordinates_y) Local $intRetVal = 0 ;record the touch success time If Not _IsConsistTouch() Then ;check if the pc support touch action Return $intRetVal EndIf Local $int_Touch_Count_MAX = 10 ;the fingercount Local $TOUCH_FEEDBACK_DEFAULT = 1 $TouchInit = DllCall("User32.dll", "BOOL", "InitializeTouchInjection", "int", $int_Touch_Count_MAX, "DWORD", $TOUCH_FEEDBACK_DEFAULT) Local $TOUCH_MASK_CONTACTAREA = 0x00000001 Local $TOUCH_MASK_ORIENTATION = 0x00000002 Local $TOUCH_MASK_PRESSURE = 0x00000004 Local $POINTER_FLAG_UP = 0x00040000 Local $POINTER_FLAG_DOWN = 0x00010000 Local $POINTER_FLAG_INRANGE = 0x00000002 Local $POINTER_FLAG_INCONTACT = 0x00000004 Local $POINTER_FLAG_UPDATE = 0X00020000 Local $tag_POINTER_INPUT_TYPE = 0x00000002 Local $tag_POINTER_FLAGS = BitOR($POINTER_FLAG_DOWN, $POINTER_FLAG_INRANGE , $POINTER_FLAG_INCONTACT) Local $tag_TOUCH_FLAGS_NONE = 0x00000000 Local $TOUCH_MASK = BitOR($TOUCH_MASK_CONTACTAREA , $TOUCH_MASK_ORIENTATION , $TOUCH_MASK_PRESSURE) Local $POINT_TOUCH_TYPE = 0x00000002 ;PT_TOUCH Local $ptPixelLocation_x = $TouchCoordinates_x Local $ptPixelLocation_y = $TouchCoordinates_y Local $tag_POINTER_INFO = "struct;struct;int pointerType;" & _ "int pointerId;" & _ "int frameId;" & _ "int pointerFlags;" & _ "hwnd sourceDevice;" & _ "hwnd hwndTarget;" & _ "struct;int ptPixelLocation_x;" & _ "int ptPixelLocation_y;endstruct;" & _ "struct;int ptHimetricLocation_x;" & _ "int ptHimetricLocation_y;endstruct;" & _ "struct;int ptPixelLocationRaw_x;" & _ "int ptPixelLocationRaw_y;endstruct;" & _ "struct;int ptHimetricLocationRaw_x;" & _ "int ptHimetricLocationRaw_y;endstruct;" & _ "dword dwTime;" & _ "int historyCount;" & _ "int inputData;" & _ "dword dwKeyStates;" & _ "UINT64 PerformanceCount;" & _ "int ButtonchangeType;endstruct;" Local Const $POINTER_TOUCH_INFO = $tag_POINTER_INFO & "int touchFlags;" & _ "int touchMask;" & _ "struct;int rcContact_left;" & _ "int rcContact_right;" & _ "int rcContact_top;" & _ "int rcContact_bottom;endstruct;" & _ "struct;int rcContactRaw_left;" & _ "int rcContactRaw_right;" & _ "int rcContactRaw_top;" & _ "int rcContactRaw_bottom;endstruct;" & _ "int orientation;" & _ "int pressure;endstruct;" Local $t_POINTER_TOUCH_INFO = DllStructCreate($POINTER_TOUCH_INFO) DllStructSetData($t_POINTER_TOUCH_INFO, "pointerType", $POINT_TOUCH_TYPE) ;pointerType DllStructSetData($t_POINTER_TOUCH_INFO, "pointerId", 0) ;pointerId DllStructSetData($t_POINTER_TOUCH_INFO, "ptPixelLocation_x", $ptPixelLocation_x) ;ptPixelLocation DllStructSetData($t_POINTER_TOUCH_INFO, "ptPixelLocation_y", $ptPixelLocation_y) ;ptPixelLocation DllStructSetData($t_POINTER_TOUCH_INFO, "touchFlags", $tag_TOUCH_FLAGS_NONE) ;touchFlags DllStructSetData($t_POINTER_TOUCH_INFO, "touchMask", $TOUCH_MASK) ;touchMask DllStructSetData($t_POINTER_TOUCH_INFO, "rcContact_left", $ptPixelLocation_x - 2) ;rcContact DllStructSetData($t_POINTER_TOUCH_INFO, "rcContact_right", $ptPixelLocation_x + 2) ;rcContact DllStructSetData($t_POINTER_TOUCH_INFO, "rcContact_top", $ptPixelLocation_y - 2) ;rcContact DllStructSetData($t_POINTER_TOUCH_INFO, "rcContact_bottom", $ptPixelLocation_y + 2) ;rcContact DllStructSetData($t_POINTER_TOUCH_INFO, "orientation", 90) ;orientation DllStructSetData($t_POINTER_TOUCH_INFO, "pressure", 32000) ;pressure For $i = 1 To $TouchTimes Step 1 DllStructSetData($t_POINTER_TOUCH_INFO, "pointerFlags", $tag_POINTER_FLAGS) ;pinterFlags ;DllStructSetData($t_POINTER_TOUCH_INFO, "ptPixelLocation_y", 300-$i) ;ptPixelLocation draw a line $aRet = DllCall(‘User32.dll‘, ‘BOOL‘, ‘InjectTouchInput‘, ‘int‘, 1, ‘ptr‘, DllStructGetPtr($t_POINTER_TOUCH_INFO)) If $aRet <> 0 Then DllStructSetData($t_POINTER_TOUCH_INFO, "pointerFlags", $POINTER_FLAG_UP) ;pinterFlags DllCall(‘User32.dll‘, ‘BOOL‘, ‘InjectTouchInput‘, ‘int‘, 1, ‘ptr‘, DllStructGetPtr($t_POINTER_TOUCH_INFO)) $intRetVal += 1 Sleep($TouchInterval) EndIf Next Return $intRetVal EndFunc ;check if the pc support touch action ;returns:1----yes;0----no Func _IsConsistTouch() Dim $IsConsistTouch = GetSystemMetrics(94) ;94 means SM_DIGITIZER Return $IsConsistTouch > 0 ? 1 : 0 EndFunc Func GetSystemMetrics($iIndex) Local $aResult = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $iIndex) If @error Then Return SetError(@error, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetSystemMetrics
C#代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace WindowsFormsApplication1 { [StructLayout(LayoutKind.Explicit)] public struct Rect { [FieldOffset(0)] public int left; [FieldOffset(4)] public int top; [FieldOffset(8)] public int right; [FieldOffset(12)] public int bottom; } public enum TOUCH_FLAGS { TOUCH_FLAGS_NONE = 0x00000000/*Indicates that no flags are set.*/ } 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 } [StructLayout(LayoutKind.Sequential)] public struct POINT { public int x; public int y; } public enum POINTER_INPUT_TYPE { PT_POINTER = 0x00000001, PT_TOUCH = 0x00000002, PT_PEN = 0x00000003, PT_MOUSE = 0x00000004 }; [StructLayout(LayoutKind.Sequential)] public struct POINTER_INFO { public POINTER_INPUT_TYPE pointerType; public uint pointerId; public uint frameId; public IntPtr sourceDevice; public IntPtr hwndTarget; public POINT ptPixelLocation; public POINT ptHimetricLocation; public POINT ptPixelLocationPredicted; public POINT ptHimetricLocationPredicted; public POINTER_FLAGS pointerFlags; public uint dwTime; public uint historyCount; public uint inputData; public uint dwKeyStates; public ulong Reserved; } [StructLayout(LayoutKind.Sequential)] public struct POINTER_TOUCH_INFO { /* * Contains basic pointer information common to all pointer types. */ public POINTER_INFO pointerInfo; /* * Lists the touch flags. */ public TOUCH_FLAGS touchFlags; public uint touchMasks; /* * 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 Rect rcContact; /* * 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 uint orientation; /* * Pointer pressure normalized in a range of 0 to 256. */ public uint pressure; } public partial class Form1 : Form { const int MAX_TOUCH_COUNT = 256; //Specifies default touch visualizations. const int TOUCH_FEEDBACK_DEFAULT = 0x1; //Specifies indirect touch visualizations. const int TOUCH_FEEDBACK_INDIRECT = 0x2; //Specifies no touch visualizations. const int TOUCH_FEEDBACK_NONE = 0x3; [DllImport("User32.dll")] static extern bool InitializeTouchInjection(uint maxCount, int dwMode); [DllImport("User32.dll")] static extern bool InjectTouchInput(int count, ref POINTER_TOUCH_INFO contacts); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { bool flag = false; flag = InitializeTouchInjection(10, TOUCH_FEEDBACK_NONE); POINTER_TOUCH_INFO contacts = new POINTER_TOUCH_INFO(); Rect touchArea = new Rect(); touchArea.left = 200 - 2; touchArea.right = 200 + 2; touchArea.top = 200 + 2; touchArea.bottom = 200 - 2; contacts.pointerInfo.pointerType = POINTER_INPUT_TYPE.PT_TOUCH; contacts.touchFlags = TOUCH_FLAGS.TOUCH_FLAGS_NONE; contacts.rcContact = touchArea; contacts.orientation = 90; contacts.pressure = 32000; contacts.pointerInfo.pointerFlags = POINTER_FLAGS.POINTER_FLAG_UP | POINTER_FLAGS.POINTER_FLAG_INRANGE | POINTER_FLAGS.POINTER_FLAG_INCONTACT; contacts.pointerInfo.ptPixelLocation.x = 200; contacts.pointerInfo.ptPixelLocation.y = 200; contacts.pointerInfo.pointerId = 1; flag = InjectTouchInput(1, ref contacts);//returned flag is false which means the injection fails! contacts.pressure = 0; if (flag) { contacts.pointerInfo.pointerFlags = POINTER_FLAGS.POINTER_FLAG_UP; InjectTouchInput(1, ref contacts); } } } }