public static void Touch(int x, int y) { bool flag = false; flag = InitializeTouchInjection(10, TOUCH_FEEDBACK_DEFAULT); POINTER_TOUCH_INFO contacts = new POINTER_TOUCH_INFO(); contacts.pointerInfo.pointerType = POINTER_INPUT_TYPE.PT_TOUCH; contacts.touchFlags = TOUCH_FLAGS.TOUCH_FLAGS_NONE; contacts.orientation = 90; contacts.pressure = 32000; contacts.pointerInfo.pointerFlags = POINTER_FLAGS.POINTER_FLAG_DOWN | POINTER_FLAGS.POINTER_FLAG_INRANGE | POINTER_FLAGS.POINTER_FLAG_INCONTACT; contacts.touchMasks = TOUCH_MASK.TOUCH_MASK_CONTACTAREA | TOUCH_MASK.TOUCH_MASK_ORIENTATION | TOUCH_MASK.TOUCH_MASK_PRESSURE; contacts.pointerInfo.ptPixelLocation.x = x; contacts.pointerInfo.ptPixelLocation.y = y; contacts.pointerInfo.pointerId = 1; Rect touchArea = new Rect(); touchArea.left = x - 2; touchArea.right = x + 2; touchArea.top = y - 2; touchArea.bottom = y + 2; contacts.rcContact = touchArea; flag = InjectTouchInput(1, ref contacts); contacts.pressure = 0; if (flag) { contacts.pointerInfo.pointerFlags = POINTER_FLAGS.POINTER_FLAG_UP; InjectTouchInput(1, ref contacts); } }
/// <summary> /// Helper method to create the most used <see cref="POINTER_TOUCH_INFO"/> structure. /// </summary> /// <param name="point">The point where the touch action occurs.</param> /// <param name="flags">The flags used for the touch action</param> /// <param name="id">The id of the point, only needed when more than one.</param> /// <returns>A <see cref="POINTER_TOUCH_INFO"/> structure.</returns> private static POINTER_TOUCH_INFO CreatePointerTouch(Point point, PointerFlags flags, uint id = 0) { var touchPoint = point.ToPOINT(); var contact = new POINTER_TOUCH_INFO { pointerInfo = { pointerType = PointerInputType.PT_TOUCH, pointerFlags = flags, ptPixelLocation = touchPoint, pointerId = id, }, touchFlags = TouchFlags.NONE, touchMask = TouchMask.NONE, rcContact = new RECT { left = touchPoint.X, right = touchPoint.X, top = touchPoint.Y, bottom = touchPoint.Y } }; return(contact); }
/// <summary> /// Simulate touch down. /// </summary> /// <param name="point">The position.</param> /// <returns>A disposable that calls Up when disposed.</returns> public static IDisposable Hold(Point point) { contacts = new[] { POINTER_TOUCH_INFO.Create(point, POINTER_FLAG.DOWN | POINTER_FLAG.INRANGE | POINTER_FLAG.INCONTACT) }; InjectTouchInput(contacts); return(new ActionDisposable(() => { contacts[0].PointerInfo.PointerFlags = POINTER_FLAG.UP; InjectTouchInput(contacts); contacts = null; Wait.UntilInputIsProcessed(); })); }
public static void Tap(int x, int y) { var contacts = new POINTER_TOUCH_INFO[1] { new POINTER_TOUCH_INFO { pointerInfo = { pointerType = POINTER_INPUT_TYPE.PT_TOUCH, pointerFlags = POINTER_FLAGS.POINTER_FLAG_DOWN | POINTER_FLAGS.POINTER_FLAG_INRANGE | POINTER_FLAGS.POINTER_FLAG_INCONTACT, ptPixelLocation = new POINT { x = x, y = y, }, pointerId = 1, }, touchFlags = TOUCH_FLAGS.TOUCH_FLAGS_NONE, touchMasks = TOUCH_MASK.TOUCH_MASK_CONTACTAREA | TOUCH_MASK.TOUCH_MASK_ORIENTATION | TOUCH_MASK.TOUCH_MASK_PRESSURE, orientation = 90, pressure = 32000, rcContact = new Rect { left = x - 2, right = x + 2, top = y - 2, bottom = y + 2 }, } }; if (!InjectTouchInput(1, contacts)) { throw new Win32Exception(); } //contacts.pressure = 0; contacts[0].pointerInfo.pointerFlags = POINTER_FLAGS.POINTER_FLAG_UP; if (!InjectTouchInput(1, contacts)) { throw new Win32Exception(); } }
/// <summary> /// Create a Touch emulator instance /// </summary> /// <param name="touchPoints">Number of concurrent touch points</param> /// <param name="mode">Feedback mode</param> public Touch(int touchPoints, FeedbackMode mode) { if (!IsSupported) { throw new ExternalException("Not Supported on your OS."); } _contact = new POINTER_TOUCH_INFO(); _contact.pointerInfo.pointerType = TouchApi.PT_TOUCH; _contact.pointerInfo.pointerId = 0; //contact 0 _contact.orientation = 90; // Orientation of 90 means touching perpendicular to screen. _contact.pressure = 32000; _contact.touchFlags = TouchApi.POINTER_FLAG_NONE; _contact.touchMask = TouchApi.TOUCH_MASK_CONTACTAREA | TouchApi.TOUCH_MASK_ORIENTATION | TouchApi.TOUCH_MASK_PRESSURE; if (!TouchApi.InitializeTouchInjection((uint)touchPoints, (uint)mode)) { throw new ExternalException("Initialisation failed. Code: " + Marshal.GetLastWin32Error()); } }
/// <summary> /// Simulate touch down. /// </summary> /// <param name="fingers">The position.</param> /// <returns>A disposable that calls Up when disposed.</returns> public static IDisposable Hold(TwoFingers fingers) { contacts = new[] { POINTER_TOUCH_INFO.Create(fingers.First, POINTER_FLAG.DOWN | POINTER_FLAG.INRANGE | POINTER_FLAG.INCONTACT, 0), POINTER_TOUCH_INFO.Create(fingers.Second, POINTER_FLAG.DOWN | POINTER_FLAG.INRANGE | POINTER_FLAG.INCONTACT, 1), }; InjectTouchInput(contacts); return(new ActionDisposable(() => { contacts[0].PointerInfo.PointerFlags = POINTER_FLAG.UP; contacts[1].PointerInfo.PointerFlags = POINTER_FLAG.UP; InjectTouchInput(contacts); contacts = null; Wait.UntilInputIsProcessed(); })); }
/// <summary> /// Simulate touch down. /// </summary> /// <param name="point">The position.</param> /// <returns>A disposable that calls Up when disposed.</returns> public static IDisposable Down(Point point) { contacts = new[] { POINTER_TOUCH_INFO.Create(point, 0) }; if (!User32.InjectTouchInput(1, contacts)) { throw new Win32Exception(); } return(new ActionDisposable(() => { contacts[0].PointerInfo.PointerFlags = POINTER_FLAG.UP; if (!User32.InjectTouchInput(1, contacts)) { throw new Win32Exception(); } contacts = null; })); }
private List <POINTER_TOUCH_INFO> GenerateInput(POINTER_INFO[] pointerInfos) { List <POINTER_TOUCH_INFO> ptis = new List <POINTER_TOUCH_INFO>(pointerInfos.Length); int upFlagCount = 0; foreach (var currentPointerInfo in pointerInfos) { POINTER_TOUCH_INFO pti = new POINTER_TOUCH_INFO { TouchFlags = TOUCH_FLAGS.NONE, PointerInfo = new POINTER_INFO { pointerType = POINTER_INPUT_TYPE.TOUCH, PtPixelLocation = currentPointerInfo.PtPixelLocation, } }; if (currentPointerInfo.PointerFlags.HasFlag(POINTER_FLAGS.UPDATE)) { pti.PointerInfo.PointerFlags = POINTER_FLAGS.INCONTACT | POINTER_FLAGS.INRANGE | POINTER_FLAGS.UPDATE; if (_pointerIdList.ContainsKey(currentPointerInfo.PointerID)) { pti.PointerInfo.PointerID = _pointerIdList[currentPointerInfo.PointerID]; } else { continue; } } else if (currentPointerInfo.PointerFlags.HasFlag(POINTER_FLAGS.UP)) { pti.PointerInfo.PointerFlags = POINTER_FLAGS.UP; upFlagCount++; if (_pointerIdList.ContainsKey(currentPointerInfo.PointerID)) { int id = _pointerIdList[currentPointerInfo.PointerID]; pti.PointerInfo.PointerID = id; _idPool.Enqueue(id); _pointerIdList.Remove(currentPointerInfo.PointerID); } else { continue; } } else if (currentPointerInfo.PointerFlags.HasFlag(POINTER_FLAGS.DOWN)) { pti.PointerInfo.PointerFlags = POINTER_FLAGS.DOWN | POINTER_FLAGS.INRANGE | POINTER_FLAGS.INCONTACT; if (_pointerIdList.ContainsKey(currentPointerInfo.PointerID)) { continue; } if (_idPool.Count > 0) { pti.PointerInfo.PointerID = _idPool.Dequeue(); _pointerIdList.Add(currentPointerInfo.PointerID, pti.PointerInfo.PointerID); } } else { continue; } ptis.Add(pti); } if (upFlagCount == pointerInfos.Length) { _pointerIdList.Clear(); ResetIdPool(); } return(ptis); }
public static extern bool GetPointerTouchInfo(int pointerId, out POINTER_TOUCH_INFO pointerType);
internal static extern bool GetPointerTouchInfo(int pointerID, ref POINTER_TOUCH_INFO touchInfo);
static extern bool InjectTouchInput(int count, ref POINTER_TOUCH_INFO contacts);
internal static extern bool GetPointerTouchInfo([In] UInt32 pointerId, [In, Out] ref POINTER_TOUCH_INFO touchInfo);
private bool ProcessPointerMessage(Message message) { bool pointChanged = false; int pointerId = (int)(message.WParam.ToInt64() & 0xffff); int pCount = 0; try { if (!NativeMethods.GetPointerFrameInfo(pointerId, ref pCount, null)) { CheckLastError(); } POINTER_INFO[] pointerInfos = new POINTER_INFO[pCount]; if (!NativeMethods.GetPointerFrameInfo(pointerId, ref pCount, pointerInfos)) { CheckLastError(); } if (pCount == 1) { if (_lastPoint.X == 0 && _lastPoint.Y == 0) { _lastPoint = pointerInfos[0].PtPixelLocation; } else { int screenWidth = Screen.PrimaryScreen.Bounds.Width; int screenHeight = Screen.PrimaryScreen.Bounds.Height; pointChanged = Math.Abs(pointerInfos[0].PtPixelLocation.X - _lastPoint.X) > screenWidth / 100 || Math.Abs(pointerInfos[0].PtPixelLocation.Y - _lastPoint.Y) > screenHeight / 100; _lastPoint = pointerInfos[0].PtPixelLocation; } //Allow single-finger slide POINTER_TOUCH_INFO[] ptis = new POINTER_TOUCH_INFO[pCount]; for (int i = 0; i < ptis.Length; i++) { ptis[i].TouchFlags = TOUCH_FLAGS.NONE; ptis[i].PointerInfo = new POINTER_INFO { pointerType = POINTER_INPUT_TYPE.TOUCH, PointerFlags = pointerInfos[i].PointerFlags.HasFlag(POINTER_FLAGS.UPDATE) ? POINTER_FLAGS.INCONTACT | POINTER_FLAGS.INRANGE | POINTER_FLAGS.UPDATE : pointerInfos[i].PointerFlags.HasFlag(POINTER_FLAGS.UP) ? POINTER_FLAGS.UP : POINTER_FLAGS.DOWN | POINTER_FLAGS.INRANGE | POINTER_FLAGS.INCONTACT, PtPixelLocation = pointerInfos[i].PtPixelLocation, }; } NativeMethods.InjectTouchInput(1, ptis); } else { pointChanged = true; } } catch (Win32Exception) { } return(pointChanged); }