/// <summary> /// Create new touch event argument instance /// </summary> /// <param name="hWndWrapper">The target control</param> /// <param name="touchInput">one of the inner touch input in the message</param> internal TouchEventArgs(IHwndWrapper hWndWrapper, float dpiX, float dpiY, ref TOUCHINPUT touchInput) { _hWndWrapper = hWndWrapper; _dpiXFactor = 96F / dpiX; _dpiYFactor = 96F / dpiY; DecodeTouch(ref touchInput); }
/// <summary> /// Decode the message and create a collection of event arguments /// </summary> /// <remarks> /// One Windows message can result a group of events /// </remarks> /// <returns>An enumerator of thr resuting events</returns> /// <param name="hWnd">the WndProc hWnd</param> /// <param name="msg">the WndProc msg</param> /// <param name="wParam">the WndProc wParam</param> /// <param name="lParam">the WndProc lParam</param> private IEnumerable <TouchEventArgs> DecodeMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, float dpiX, float dpiY) { // More than one touchinput may be associated with a touch message, // so an array is needed to get all event information. int inputCount = User32.LoWord(wParam.ToInt32()); // Number of touch inputs, actual per-contact messages TOUCHINPUT[] inputs; // Array of TOUCHINPUT structures inputs = new TOUCHINPUT[inputCount]; // Allocate the storage for the parameters of the per-contact messages try { // Unpack message parameters into the array of TOUCHINPUT structures, each // representing a message for one single contact. if (!User32.GetTouchInputInfo(lParam, inputCount, inputs, Marshal.SizeOf(inputs[0]))) { // Get touch info failed. throw new Exception("Error calling GetTouchInputInfo API"); } // For each contact, dispatch the message to the appropriate message // handler. // Note that for WM_TOUCHDOWN you can get down & move notifications // and for WM_TOUCHUP you can get up & move notifications // WM_TOUCHMOVE will only contain move notifications // and up & down notifications will never come in the same message for (int i = 0; i < inputCount; i++) { TouchEventArgs touchEventArgs = new TouchEventArgs(HWndWrapper, dpiX, dpiY, ref inputs[i]); yield return(touchEventArgs); } } finally { User32.CloseTouchInputHandle(lParam); } }
public POINT getClientPoint(TOUCHINPUT WM_T) { POINT p = new POINT(); p.X = WM_T.x / 100; p.Y = WM_T.y / 100; ScreenToClient(hMainWindow, ref p); return(p); }
public static TOUCHINPUT[] GetTouchInputFromParam(IntPtr wParam, IntPtr lParam) { int inputCount = (int)(wParam.ToInt32() & 0xFFFF); TOUCHINPUT[] inputs = new TOUCHINPUT[inputCount]; bool result = NativeMethod.GetTouchInputInfo(lParam, inputCount, inputs, Marshal.SizeOf(inputs[0])); return(inputs); }
private bool DecodeTouch(ref Message m) { int inputCount = LoWord(m.WParam.ToInt32()); TOUCHINPUT[] inputs; inputs = new TOUCHINPUT[inputCount]; if (!GetTouchInputInfo(m.LParam, inputCount, inputs, touchInputSize)) { return(false); } bool handled = false; for (int i = 0; i < inputCount; i++) { TOUCHINPUT ti = inputs[i]; EventHandler <WMTouchEventArgs> handler = null; if ((ti.dwFlags & TOUCHEVENTF_DOWN) != 0) { handler = Touchdown; } else if ((ti.dwFlags & TOUCHEVENTF_UP) != 0) { handler = Touchup; } else if ((ti.dwFlags & TOUCHEVENTF_MOVE) != 0) { handler = TouchMove; } if (handler != null) { WMTouchEventArgs te = new WMTouchEventArgs(); te.ContactY = ti.cyContact / 100; te.ContactX = ti.cxContact / 100; te.Id = ti.dwID; { Point pt = PointToClient(new Point(ti.x / 100, ti.y / 100)); te.LocationX = pt.X; te.LocationY = pt.Y; } te.Time = ti.dwTime; te.Mask = ti.dwMask; te.Flags = ti.dwFlags; handler(this, te); handled = true; } } CloseTouchInputHandle(m.LParam); return(handled); }
/// <summary> /// Decodes a single touch point and creates from it the <see cref="PointerPoint"/> class. /// </summary> /// <param name="input">The touch point input structure.</param> private void DecodeAndDispatchTouchPoint(TOUCHINPUT input) { var p = control.PointToClient(new System.Drawing.Point(AdjustX(input.x), AdjustY(input.y))); var mask = input.dwMask; var flags = input.dwFlags; var isPrimary = (flags & User32.TOUCHEVENTF_PRIMARY) != 0; PointerUpdateKind pointerUpdateKind; PointerEventType eventType; if ((flags & User32.TOUCHEVENTF_DOWN) != 0) { pointerUpdateKind = PointerUpdateKind.LeftButtonPressed; eventType = PointerEventType.Pressed; } else if ((flags & User32.TOUCHEVENTF_DOWN) != 0) { pointerUpdateKind = PointerUpdateKind.LeftButtonReleased; eventType = PointerEventType.Released; } else { pointerUpdateKind = PointerUpdateKind.Other; eventType = PointerEventType.Moved; } var clientSize = control.ClientSize; var position = new Vector2((float)p.X / clientSize.Width, (float)p.Y / clientSize.Height); position.Saturate(); var point = new PointerPoint { EventType = eventType, DeviceType = ((flags & User32.TOUCHEVENTF_PEN) != 0) ? PointerDeviceType.Pen : PointerDeviceType.Touch, PointerId = (uint)input.dwID, Timestamp = (ulong)input.dwTime, Position = position, KeyModifiers = GetCurrentKeyModifiers(), IsPrimary = isPrimary, IsInRange = (flags & User32.TOUCHEVENTF_INRANGE) != 0, TouchConfidence = (flags & User32.TOUCHEVENTF_PALM) != 0, PointerUpdateKind = pointerUpdateKind, }; if ((mask & User32.TOUCHINPUTMASKF_CONTACTAREA) != 0) { point.ContactRect = new RectangleF(position.X, position.Y, (float)AdjustX(input.cxContact) / clientSize.Width, (float)AdjustY(input.cyContact) / clientSize.Height); } manager.AddPointerEvent(ref point); }
private void decodeTouches(IntPtr wParam, IntPtr lParam) { lock ( tracking ) { int inputCount = LOWORD(wParam.ToInt32()); TOUCHINPUT[] inputs = new TOUCHINPUT[inputCount]; if (!GetTouchInputInfo(lParam, inputCount, inputs, touchInputSize)) { return; } for (int i = 0; i < inputCount; i++) { TOUCHINPUT touch = inputs[i]; if ((touch.dwFlags & (int)TouchEvent.TOUCHEVENTF_DOWN) != 0) { POINT p = new POINT(); p.X = touch.x / 100; p.Y = touch.y / 100; ScreenToClient(hMainWindow, ref p); winToInternalId.Add(touch.dwID, beginTouch(new Vector2(p.X, Screen.height - p.Y))); } else if ((touch.dwFlags & (int)TouchEvent.TOUCHEVENTF_UP) != 0) { int existingId; if (winToInternalId.TryGetValue(touch.dwID, out existingId)) { winToInternalId.Remove(touch.dwID); endTouch(existingId); } } else if ((touch.dwFlags & (int)TouchEvent.TOUCHEVENTF_MOVE) != 0) { int existingId; if (winToInternalId.TryGetValue(touch.dwID, out existingId)) { POINT p = new POINT(); p.X = touch.x / 100; p.Y = touch.y / 100; ScreenToClient(hMainWindow, ref p); moveTouch(existingId, new Vector2(p.X, Screen.height - p.Y)); } } } CloseTouchInputHandle(lParam); } }
private IEnumerable <TouchNotification> GenerateTouchNotifications(EventPattern <WMEventArgs> e) { var a = e.EventArgs; var touchPointCount = a.WParam.LoWord(); if (touchPointCount > 0) { var touchPoints = new TOUCHINPUT[touchPointCount]; if (User32.GetTouchInputInfo(a.LParam, touchPointCount, touchPoints, Marshal.SizeOf(typeof(TOUCHINPUT)))) { a.Handled = true; try { RECT cr; if (User32.GetClientRect(a.HWnd, out cr)) { foreach (var touchPoint in touchPoints) { var position = new Point(touchPoint.x / 100, touchPoint.y / 100); User32.ScreenToClient(a.HWnd, ref position); var clientArea = new Size(cr.Width, cr.Height); var id = touchPoint.dwID; var primary = (touchPoint.dwFlags & Const.TOUCHEVENTF_PRIMARY) > 0; var contactArea = (touchPoint.dwMask & Const.TOUCHINPUTMASKF_CONTACTAREA) > 0 ? new Size(touchPoint.cxContact / 100, touchPoint.cyContact / 100) : Size.Empty; if ((touchPoint.dwFlags & Const.TOUCHEVENTF_DOWN) > 0) { yield return(new TouchDownNotification(position, clientArea, id, primary, contactArea, touchPoint.hSource.ToInt64(), e.Sender)); } if ((touchPoint.dwFlags & Const.TOUCHEVENTF_MOVE) > 0) { yield return(new TouchMoveNotification(position, clientArea, id, primary, contactArea, touchPoint.hSource.ToInt64(), e.Sender)); } if ((touchPoint.dwFlags & Const.TOUCHEVENTF_UP) > 0) { yield return(new TouchUpNotification(position, clientArea, id, primary, contactArea, touchPoint.hSource.ToInt64(), e.Sender)); } } } } finally { User32.CloseTouchInputHandle(a.LParam); } } } yield break; }
public static void WndProc(Window window, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == NativeMethods.WM_TOUCH) { var inputCount = wParam.ToInt32() & 0xffff; var inputs = new TOUCHINPUT[inputCount]; if (NativeMethods.GetTouchInputInfo(lParam, inputCount, inputs, NativeMethods.TouchInputSize)) { for (int i = 0; i < inputCount; i++) { var input = inputs[i]; var position = GraphicsHelper.DivideByDpi(new Point(input.x * 0.01, input.y * 0.01)); position.Offset(-(double)_actualLeft.GetValue(window), -(double)_actualTop.GetValue(window)); MessageTouchDevice device; if (!_devices.TryGetValue(input.dwID, out device)) { device = new MessageTouchDevice(input.dwID); _devices.Add(input.dwID, device); } if (!device.IsActive && input.dwFlags.HasFlag(TOUCHEVENTF.TOUCHEVENTF_DOWN)) { device.SetActiveSource(PresentationSource.FromVisual(window)); device.Position = position; device.Activate(); device.ReportDown(); } else if (device.IsActive && input.dwFlags.HasFlag(TOUCHEVENTF.TOUCHEVENTF_UP)) { device.Position = position; device.ReportUp(); device.Deactivate(); _devices.Remove(input.dwID); } else if (device.IsActive && input.dwFlags.HasFlag(TOUCHEVENTF.TOUCHEVENTF_MOVE) && device.Position != position) { device.Position = position; device.ReportMove(); } _lastTouch = DateTime.Now; } } NativeMethods.CloseTouchInputHandle(lParam); handled = true; } }
protected override void WndProc(ref Message m) { switch (m.Msg) { case (int)WM.WM_TOUCH: { int inputCount = (int)(m.WParam.ToInt32() & 0xFFFF); TOUCHINPUT[] inputs = new TOUCHINPUT[inputCount]; bool result = NativeMethod.GetTouchInputInfo(m.LParam, inputCount, inputs, Marshal.SizeOf(inputs[0])); this.TouchChanged?.Invoke(this.Handle, inputCount, inputs); } break; } base.WndProc(ref m); }
private bool HandleTouch(IntPtr wParam, IntPtr lParam) { bool handled = false; var inputCount = wParam.ToInt32() & 0xffff; var inputs = new TOUCHINPUT[inputCount]; if (GetTouchInputInfo(lParam, inputCount, inputs, Marshal.SizeOf(inputs[0]))) { for (int i = 0; i < inputCount; i++) { var input = inputs[i]; var position = PointFromScreen(new System.Windows.Point((input.x * 0.01), (input.y * 0.01))); TouchDeviceEmulator device; if (!_devices.TryGetValue(input.dwID, out device)) { device = new TouchDeviceEmulator(input.dwID); _devices.Add(input.dwID, device); } device.Position = position; if ((input.dwFlags & TOUCHEVENTF_DOWN) > 0) { device.SetActiveSource(PresentationSource.FromVisual(this)); device.Activate(); device.ReportDown(); } else if (device.IsActive && (input.dwFlags & TOUCHEVENTF_UP) > 0) { device.ReportUp(); device.Deactivate(); _devices.Remove(input.dwID); } else if (device.IsActive && (input.dwFlags & TOUCHEVENTF_MOVE) > 0) { device.ReportMove(); } } CloseTouchInputHandle(lParam); handled = true; } return(handled); }
private bool DecodeTouch(ref Message m) { int touchInputCount = m.WParam.ToInt32() & 0xffff; TOUCHINPUT[] inputs = new TOUCHINPUT[touchInputCount]; if (!GetTouchInputInfo(m.LParam, touchInputCount, inputs, touchInputSize)) { return(false); } bool handled = false; for (int i = 0; i < touchInputCount; i++) { var tochInput = inputs[i]; EventHandler <TouchEventArgs> handler = null; if ((tochInput.dwFlags & TOUCHEVENTF_DOWN) != 0) { handler = Touchdown; } else if ((tochInput.dwFlags & TOUCHEVENTF_UP) != 0) { handler = Touchup; } else if ((tochInput.dwFlags & TOUCHEVENTF_MOVE) != 0) { handler = TouchMove; } if (handler != null) { // TOUCHINFO point coordinates size is in 1/100 of a pixel // convert screen to client coordinates. var te = new TouchEventArgs { Location = PointToClient(new Point(tochInput.x / 100, tochInput.y / 100)), ID = tochInput.dwID, Flags = tochInput.dwFlags }; handler(this, te); handled = true; } } CloseTouchInputHandle(m.LParam); return(handled); }
void updateTouchFromWM(TOUCHINPUT WM_T) { lock (m_lock) { if ((WM_T.dwFlags & (int)TouchEvent.TOUCHEVENTF_MOVE) != 0) { current[WM_T.dwID] = WM_T; } if ((WM_T.dwFlags & (int)TouchEvent.TOUCHEVENTF_DOWN) != 0) { current.Add(WM_T.dwID, WM_T); } if ((WM_T.dwFlags & (int)TouchEvent.TOUCHEVENTF_UP) != 0) { current.Remove(WM_T.dwID); } } }
void processTouches(IntPtr wParam, IntPtr lParam) { int inputCount = LOWORD(wParam.ToInt32()); TOUCHINPUT[] inputs = new TOUCHINPUT[inputCount]; if (!GetTouchInputInfo(lParam, inputCount, inputs, touchInputSize)) { return; } for (int i = 0; i < inputCount; i++) { TOUCHINPUT touch = inputs[i]; updateTouchFromWM(touch); } CloseTouchInputHandle(lParam); }
/// <summary> /// Decodes touch messages and calls corresponding methods on <see cref="PointerManager"/> class /// </summary> /// <param name="wParam">wParam</param> /// <param name="lParam">lParam</param> private void DecodeAndDispatchTouchMessages(IntPtr wParam, IntPtr lParam) { var inputsCount = User32.LoWord(wParam.ToInt32()); var inputs = new TOUCHINPUT[inputsCount]; try { if (!User32.GetTouchInputInfo(lParam, inputsCount, inputs, Marshal.SizeOf(typeof(TOUCHINPUT)))) { throw new InvalidOperationException("Error calling GetTouchInfo API"); } for (var i = 0; i < inputsCount; i++) { DecodeAndDispatchTouchPoint(inputs[i]); } } finally { User32.CloseTouchInputHandle(lParam); } }
// Decodes and handles WM_TOUCH* messages. private void DecodeTouch(ref TOUCHINPUT touchInput) { // TOUCHINFO point coordinates and contact size is in 1/100 of a pixel; convert it to pixels. // Also convert screen to client coordinates. if ((touchInput.dwMask & User32.TOUCHINPUTMASKF_CONTACTAREA) != 0) { ContactSize = new Size(AdjustDpiX(touchInput.cyContact / 100), AdjustDpiY(touchInput.cyContact / 100)); } Id = touchInput.dwID; Point p = _hWndWrapper.PointToClient(new Point(touchInput.x / 100, touchInput.y / 100)); Location = new Point(AdjustDpiX(p.X), AdjustDpiY(p.Y)); Time = touchInput.dwTime; TimeSpan ellapse = TimeSpan.FromMilliseconds(Environment.TickCount - touchInput.dwTime); AbsoluteTime = DateTime.Now - ellapse; Mask = touchInput.dwMask; Flags = touchInput.dwFlags; }
protected virtual IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { bool unicode = UnmanagedMethods.IsWindowUnicode(hWnd); const double wheelDelta = 120.0; uint timestamp = unchecked ((uint)UnmanagedMethods.GetMessageTime()); RawInputEventArgs e = null; WindowsMouseDevice.Instance.CurrentWindow = this; switch ((UnmanagedMethods.WindowsMessage)msg) { case UnmanagedMethods.WindowsMessage.WM_ACTIVATE: var wa = (UnmanagedMethods.WindowActivate)(ToInt32(wParam) & 0xffff); switch (wa) { case UnmanagedMethods.WindowActivate.WA_ACTIVE: case UnmanagedMethods.WindowActivate.WA_CLICKACTIVE: Activated?.Invoke(); break; case UnmanagedMethods.WindowActivate.WA_INACTIVE: Deactivated?.Invoke(); break; } return(IntPtr.Zero); case WindowsMessage.WM_NCCALCSIZE: if (ToInt32(wParam) == 1 && !_decorated) { return(IntPtr.Zero); } break; case UnmanagedMethods.WindowsMessage.WM_CLOSE: bool?preventClosing = Closing?.Invoke(); if (preventClosing == true) { return(IntPtr.Zero); } break; case UnmanagedMethods.WindowsMessage.WM_DESTROY: //Window doesn't exist anymore _hwnd = IntPtr.Zero; //Remove root reference to this class, so unmanaged delegate can be collected s_instances.Remove(this); Closed?.Invoke(); if (_parent != null) { _parent._disabledBy.Remove(this); _parent.UpdateEnabled(); } //Free other resources Dispose(); return(IntPtr.Zero); case UnmanagedMethods.WindowsMessage.WM_DPICHANGED: var dpi = ToInt32(wParam) & 0xffff; var newDisplayRect = Marshal.PtrToStructure <UnmanagedMethods.RECT>(lParam); _scaling = dpi / 96.0; ScalingChanged?.Invoke(_scaling); SetWindowPos(hWnd, IntPtr.Zero, newDisplayRect.left, newDisplayRect.top, newDisplayRect.right - newDisplayRect.left, newDisplayRect.bottom - newDisplayRect.top, SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE); return(IntPtr.Zero); case UnmanagedMethods.WindowsMessage.WM_KEYDOWN: case UnmanagedMethods.WindowsMessage.WM_SYSKEYDOWN: e = new RawKeyEventArgs( WindowsKeyboardDevice.Instance, timestamp, RawKeyEventType.KeyDown, KeyInterop.KeyFromVirtualKey(ToInt32(wParam)), WindowsKeyboardDevice.Instance.Modifiers); break; case UnmanagedMethods.WindowsMessage.WM_KEYUP: case UnmanagedMethods.WindowsMessage.WM_SYSKEYUP: e = new RawKeyEventArgs( WindowsKeyboardDevice.Instance, timestamp, RawKeyEventType.KeyUp, KeyInterop.KeyFromVirtualKey(ToInt32(wParam)), WindowsKeyboardDevice.Instance.Modifiers); break; case UnmanagedMethods.WindowsMessage.WM_CHAR: // Ignore control chars if (ToInt32(wParam) >= 32) { e = new RawTextInputEventArgs(WindowsKeyboardDevice.Instance, timestamp, new string((char)ToInt32(wParam), 1)); } break; case UnmanagedMethods.WindowsMessage.WM_LBUTTONDOWN: case UnmanagedMethods.WindowsMessage.WM_RBUTTONDOWN: case UnmanagedMethods.WindowsMessage.WM_MBUTTONDOWN: if (ShouldIgnoreTouchEmulatedMessage()) { break; } e = new RawPointerEventArgs( WindowsMouseDevice.Instance, timestamp, _owner, msg == (int)UnmanagedMethods.WindowsMessage.WM_LBUTTONDOWN ? RawPointerEventType.LeftButtonDown : msg == (int)UnmanagedMethods.WindowsMessage.WM_RBUTTONDOWN ? RawPointerEventType.RightButtonDown : RawPointerEventType.MiddleButtonDown, DipFromLParam(lParam), GetMouseModifiers(wParam)); break; case UnmanagedMethods.WindowsMessage.WM_LBUTTONUP: case UnmanagedMethods.WindowsMessage.WM_RBUTTONUP: case UnmanagedMethods.WindowsMessage.WM_MBUTTONUP: if (ShouldIgnoreTouchEmulatedMessage()) { break; } e = new RawPointerEventArgs( WindowsMouseDevice.Instance, timestamp, _owner, msg == (int)UnmanagedMethods.WindowsMessage.WM_LBUTTONUP ? RawPointerEventType.LeftButtonUp : msg == (int)UnmanagedMethods.WindowsMessage.WM_RBUTTONUP ? RawPointerEventType.RightButtonUp : RawPointerEventType.MiddleButtonUp, DipFromLParam(lParam), GetMouseModifiers(wParam)); break; case UnmanagedMethods.WindowsMessage.WM_MOUSEMOVE: if (ShouldIgnoreTouchEmulatedMessage()) { break; } if (!_trackingMouse) { var tm = new UnmanagedMethods.TRACKMOUSEEVENT { cbSize = Marshal.SizeOf <UnmanagedMethods.TRACKMOUSEEVENT>(), dwFlags = 2, hwndTrack = _hwnd, dwHoverTime = 0, }; UnmanagedMethods.TrackMouseEvent(ref tm); } e = new RawPointerEventArgs( WindowsMouseDevice.Instance, timestamp, _owner, RawPointerEventType.Move, DipFromLParam(lParam), GetMouseModifiers(wParam)); break; case UnmanagedMethods.WindowsMessage.WM_MOUSEWHEEL: e = new RawMouseWheelEventArgs( WindowsMouseDevice.Instance, timestamp, _owner, PointToClient(PointFromLParam(lParam)), new Vector(0, (ToInt32(wParam) >> 16) / wheelDelta), GetMouseModifiers(wParam)); break; case UnmanagedMethods.WindowsMessage.WM_MOUSEHWHEEL: e = new RawMouseWheelEventArgs( WindowsMouseDevice.Instance, timestamp, _owner, PointToClient(PointFromLParam(lParam)), new Vector(-(ToInt32(wParam) >> 16) / wheelDelta, 0), GetMouseModifiers(wParam)); break; case UnmanagedMethods.WindowsMessage.WM_MOUSELEAVE: _trackingMouse = false; e = new RawPointerEventArgs( WindowsMouseDevice.Instance, timestamp, _owner, RawPointerEventType.LeaveWindow, new Point(), WindowsKeyboardDevice.Instance.Modifiers); break; case UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN: case UnmanagedMethods.WindowsMessage.WM_NCRBUTTONDOWN: case UnmanagedMethods.WindowsMessage.WM_NCMBUTTONDOWN: e = new RawPointerEventArgs( WindowsMouseDevice.Instance, timestamp, _owner, msg == (int)UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN ? RawPointerEventType.NonClientLeftButtonDown : msg == (int)UnmanagedMethods.WindowsMessage.WM_NCRBUTTONDOWN ? RawPointerEventType.RightButtonDown : RawPointerEventType.MiddleButtonDown, new Point(0, 0), GetMouseModifiers(wParam)); break; case WindowsMessage.WM_TOUCH: var touchInputs = new TOUCHINPUT[wParam.ToInt32()]; if (GetTouchInputInfo(lParam, (uint)wParam.ToInt32(), touchInputs, Marshal.SizeOf <TOUCHINPUT>())) { foreach (var touchInput in touchInputs) { var pt = new POINT { X = touchInput.X / 100, Y = touchInput.Y / 100 }; UnmanagedMethods.ScreenToClient(_hwnd, ref pt); Input?.Invoke(new RawTouchEventArgs(_touchDevice, touchInput.Time, _owner, touchInput.Flags.HasFlag(TouchInputFlags.TOUCHEVENTF_UP) ? RawPointerEventType.TouchEnd : touchInput.Flags.HasFlag(TouchInputFlags.TOUCHEVENTF_DOWN) ? RawPointerEventType.TouchBegin : RawPointerEventType.TouchUpdate, new Point(pt.X, pt.Y), WindowsKeyboardDevice.Instance.Modifiers, touchInput.Id)); } CloseTouchInputHandle(lParam); return(IntPtr.Zero); } break; case WindowsMessage.WM_NCPAINT: if (!_decorated) { return(IntPtr.Zero); } break; case WindowsMessage.WM_NCACTIVATE: if (!_decorated) { return(new IntPtr(1)); } break; case UnmanagedMethods.WindowsMessage.WM_PAINT: UnmanagedMethods.PAINTSTRUCT ps; if (UnmanagedMethods.BeginPaint(_hwnd, out ps) != IntPtr.Zero) { var f = Scaling; var r = ps.rcPaint; Paint?.Invoke(new Rect(r.left / f, r.top / f, (r.right - r.left) / f, (r.bottom - r.top) / f)); UnmanagedMethods.EndPaint(_hwnd, ref ps); } return(IntPtr.Zero); case UnmanagedMethods.WindowsMessage.WM_SIZE: var size = (UnmanagedMethods.SizeCommand)wParam; if (Resized != null && (size == UnmanagedMethods.SizeCommand.Restored || size == UnmanagedMethods.SizeCommand.Maximized)) { var clientSize = new Size(ToInt32(lParam) & 0xffff, ToInt32(lParam) >> 16); Resized(clientSize / Scaling); } var windowState = size == SizeCommand.Maximized ? WindowState.Maximized : (size == SizeCommand.Minimized ? WindowState.Minimized : WindowState.Normal); if (windowState != _lastWindowState) { _lastWindowState = windowState; WindowStateChanged?.Invoke(windowState); } return(IntPtr.Zero); case UnmanagedMethods.WindowsMessage.WM_MOVE: PositionChanged?.Invoke(new PixelPoint((short)(ToInt32(lParam) & 0xffff), (short)(ToInt32(lParam) >> 16))); return(IntPtr.Zero); case UnmanagedMethods.WindowsMessage.WM_GETMINMAXINFO: MINMAXINFO mmi = Marshal.PtrToStructure <UnmanagedMethods.MINMAXINFO>(lParam); if (_minSize.Width > 0) { mmi.ptMinTrackSize.X = (int)((_minSize.Width * Scaling) + BorderThickness.Left + BorderThickness.Right); } if (_minSize.Height > 0) { mmi.ptMinTrackSize.Y = (int)((_minSize.Height * Scaling) + BorderThickness.Top + BorderThickness.Bottom); } if (!Double.IsInfinity(_maxSize.Width) && _maxSize.Width > 0) { mmi.ptMaxTrackSize.X = (int)((_maxSize.Width * Scaling) + BorderThickness.Left + BorderThickness.Right); } if (!Double.IsInfinity(_maxSize.Height) && _maxSize.Height > 0) { mmi.ptMaxTrackSize.Y = (int)((_maxSize.Height * Scaling) + BorderThickness.Top + BorderThickness.Bottom); } Marshal.StructureToPtr(mmi, lParam, true); return(IntPtr.Zero); case UnmanagedMethods.WindowsMessage.WM_DISPLAYCHANGE: (Screen as ScreenImpl)?.InvalidateScreensCache(); return(IntPtr.Zero); } #if USE_MANAGED_DRAG if (_managedDrag.PreprocessInputEvent(ref e)) { return(UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam)); } #endif if (e != null && Input != null) { Input(e); if (e.Handled) { return(IntPtr.Zero); } } return(UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam)); }
private void decodeTouches(IntPtr wParam, IntPtr lParam) { int inputCount = LOWORD(wParam.ToInt32()); TOUCHINPUT[] inputs = new TOUCHINPUT[inputCount]; if (!GetTouchInputInfo(lParam, inputCount, inputs, touchInputSize)) { return; } for (int i = 0; i < inputCount; i++) { TOUCHINPUT touch = inputs[i]; if ((touch.dwFlags & (int)TouchEvent.TOUCHEVENTF_DOWN) != 0) { POINT p = new POINT(); p.X = touch.x/100; p.Y = touch.y/100; ScreenToClient(hMainWindow, ref p); winToInternalId.Add(touch.dwID, beginTouch(new Vector2(p.X, Screen.height - p.Y))); } else if ((touch.dwFlags & (int)TouchEvent.TOUCHEVENTF_UP) != 0) { int existingId; if (winToInternalId.TryGetValue(touch.dwID, out existingId)) { winToInternalId.Remove(touch.dwID); endTouch(existingId); } } else if ((touch.dwFlags & (int)TouchEvent.TOUCHEVENTF_MOVE) != 0) { int existingId; if (winToInternalId.TryGetValue(touch.dwID, out existingId)) { POINT p = new POINT(); p.X = touch.x/100; p.Y = touch.y/100; ScreenToClient(hMainWindow, ref p); moveTouch(existingId, new Vector2(p.X, Screen.height - p.Y)); } } } CloseTouchInputHandle(lParam); }
/// <summary> /// WM_TOUCHメッセージをデコードする /// </summary> /// <param name="m">ウィンドウメッセージ</param> private bool DecodeTouch(ref Message m) { // タッチ回数 int inputCount = LoWord(m.WParam.ToInt32()); TOUCHINPUT[] inputs; inputs = new TOUCHINPUT[inputCount]; // タッチ操作を取り出して構造体の配列に入れる if (!GetTouchInputInfo(m.LParam, inputCount, inputs, touchInputSize)) { // タッチ情報取得失敗 return(false); } // タッチ操作をハンドラにディスパッチする bool handled = false; for (int i = 0; i < inputCount; i++) { TOUCHINPUT ti = inputs[i]; // タッチイベントをハンドラにアサインする EventHandler <WMTouchEventArgs> handler = null; if ((ti.dwFlags & TOUCHEVENTF_DOWN) != 0) { handler = TouchDown; } else if ((ti.dwFlags & TOUCHEVENTF_UP) != 0) { handler = TouchUp; } else if ((ti.dwFlags & TOUCHEVENTF_MOVE) != 0) { handler = TouchMove; } // メッセージパラメータをタッチイベント引数に変換してイベントを処理する if (handler != null) { // raw touchinputメッセージをタッチイベントに変換する WMTouchEventArgs te = new WMTouchEventArgs(); // タッチイベントが発生した画面のXY位置を取得する te.ContactY = ti.cyContact / 100; te.ContactX = ti.cxContact / 100; te.Id = ti.dwID; Point pt = PointToClient(new Point(ti.x / 100, ti.y / 100)); te.LocationX = pt.X; te.LocationY = pt.Y; te.Time = ti.dwTime; te.Mask = ti.dwMask; te.Flags = ti.dwFlags; // イベントハンドラを呼び出す handler(this, te); // このイベントを処理済としてマークする handled = true; } } CloseTouchInputHandle(m.LParam); return(handled); }
private bool DecodeTouch(ref Message m) { // More than one touchinput may be associated with a touch message, int inputCount = (m.WParam.ToInt32() & 0xffff); // Number of touch inputs, actual per-contact messages TOUCHINPUT[] inputs = new TOUCHINPUT[inputCount]; if (!TouchConstants.GetTouchInputInfo(m.LParam, inputCount, inputs, Marshal.SizeOf(new TOUCHINPUT()))) { return(false); } bool handled = false; for (int i = 0; i < inputCount; i++) { TOUCHINPUT ti = inputs[i]; EventHandler <WMTouchEventArgs> handler = null; if ((ti.dwFlags & TouchConstants.TOUCHEVENTF_DOWN) != 0) { handler = Touchdown; } else if ((ti.dwFlags & TouchConstants.TOUCHEVENTF_UP) != 0) { handler = Touchup; } else if ((ti.dwFlags & TouchConstants.TOUCHEVENTF_MOVE) != 0) { handler = TouchMove; } // Convert message parameters into touch event arguments and handle the event. if (handler != null) { WMTouchEventArgs te = new WMTouchEventArgs(); // TOUCHINFO point coordinates and contact size is in 1/100 of a pixel; convert it to pixels. // Also convert screen to client coordinates. te.ContactY = ti.cyContact / 100; te.ContactX = ti.cxContact / 100; te.Id = ti.dwID; { Point pt = PointToClient(new Point(ti.x / 100, ti.y / 100)); te.LocationX = pt.X; te.LocationY = pt.Y; } te.Time = ti.dwTime; te.Mask = ti.dwMask; te.Flags = ti.dwFlags; handler(this, te); // Mark this event as handled. handled = true; } } TouchConstants.CloseTouchInputHandle(m.LParam); return(handled); }
// Decodes and handles WM_TOUCH message. // Unpacks message arguments and invokes appropriate touch events. // in: // m window message // returns: // whether the message has been handled private bool DecodeTouch(ref Message m) { // More than one touchinput may be associated with a touch message, // so an array is needed to get all event information. int inputCount = LoWord(m.WParam.ToInt32()); // Number of touch inputs, actual per-contact messages TOUCHINPUT[] inputs; // Array of TOUCHINPUT structures inputs = new TOUCHINPUT[inputCount]; // Allocate the storage for the parameters of the per-contact messages // Unpack message parameters into the array of TOUCHINPUT structures, each // representing a message for one single contact. if (!GetTouchInputInfo(m.LParam, inputCount, inputs, touchInputSize)) { // Get touch info failed. return false; } // For each contact, dispatch the message to the appropriate message // handler. bool handled = false; // Boolean, is message handled for (int i = 0; i < inputCount; i++) { TOUCHINPUT ti = inputs[i]; // Assign a handler to this message. EventHandler<WMTouchEventArgs> handler = null; // Touch event handler if ((ti.dwFlags & TOUCHEVENTF_DOWN) != 0) { handler = Touchdown; } else if ((ti.dwFlags & TOUCHEVENTF_UP) != 0) { handler = Touchup; } else if ((ti.dwFlags & TOUCHEVENTF_MOVE) != 0) { handler = TouchMove; } // Convert message parameters into touch event arguments and handle the event. if (handler != null) { // Convert the raw touchinput message into a touchevent. WMTouchEventArgs te = new WMTouchEventArgs(); // Touch event arguments // TOUCHINFO point coordinates and contact size is in 1/100 of a pixel; convert it to pixels. // Also convert screen to client coordinates. te.ContactY = ti.cyContact/100; te.ContactX = ti.cxContact/100; te.Id = ti.dwID; { Point pt = PointToClient(new Point(ti.x/100, ti.y/100)); te.LocationX = pt.X; te.LocationY = pt.Y; } te.Time = ti.dwTime; te.Mask = ti.dwMask; te.Flags = ti.dwFlags; // Invoke the event handler. handler(this, te); // Mark this event as handled. handled = true; } } CloseTouchInputHandle(m.LParam); return handled; }
// Decodes and handles WM_TOUCH* messages. // Unpacks message arguments and invokes appropriate touch events. // in: // m window message // returns: // flag whether the message has been handled public bool DecodeTouch(ref Message m) { // More than one touchinput may be associated with a touch message, // so an array is needed to get all event information. int inputCount = LoWord(m.WParam.ToInt32()); // Number of touch inputs, actual per-contact messages TOUCHINPUT[] inputs; // Array of TOUCHINPUT structures try { inputs = new TOUCHINPUT[inputCount]; // Allocate the storage for the parameters of the per-contact messages } catch (Exception exception) { Debug.Print("ERROR: Could not allocate inputs array"); Debug.Print(exception.ToString()); return false; } Debug.Print("Inputs: " + inputs.Length.ToString()); // Unpack message parameters into the array of TOUCHINPUT structures, each // representing a message for one single contact. //Exercise2-Task1-Step3 if (!GetTouchInputInfo(m.LParam, inputCount, inputs, touchInputSize)) { // Get touch info failed. return false; } // For each contact, dispatch the message to the appropriate message // handler. // Note that for WM_TOUCHDOWN you can get down & move notifications // and for WM_TOUCHUP you can get up & move notifications // WM_TOUCHMOVE will only contain move notifications // and up & down notifications will never come in the same message bool handled = false; // // Flag, is message handled //Exercise2-Task1-Step4 for (int i = 0; i < inputCount; i++) { TOUCHINPUT ti = inputs[i]; // Assign a handler to this message. EventHandler<WMTouchEventArgs> handler = null; // Touch event handler if ((ti.dwFlags & TOUCHEVENTF_DOWN) != 0) { handler = Touchdown; } else if ((ti.dwFlags & TOUCHEVENTF_UP) != 0) { handler = Touchup; } else if ((ti.dwFlags & TOUCHEVENTF_MOVE) != 0) { handler = TouchMove; } Debug.Print("Inputs: " + inputs.Length.ToString() + "\r\nCoordinates: " + ti.x.ToString() + "," + ti.y.ToString()); // Convert message parameters into touch event arguments and handle the event. if (handler != null) { // Convert the raw touchinput message into a touchevent. WMTouchEventArgs te; // Touch event arguments try { te = new WMTouchEventArgs(); } catch (Exception excep) { Debug.Print("Could not allocate WMTouchEventArgs"); Debug.Print(excep.ToString()); continue; } // TOUCHINFO point coordinates and contact size is in 1/100 of a pixel; convert it to pixels. // Also convert screen to client coordinates. te.ContactY = ti.cyContact / 100; te.ContactX = ti.cxContact / 100; te.Id = ti.dwID; { Point pt = PointToClient(new Point(ti.x / 100, ti.y / 100)); te.LocationX = pt.X; te.LocationY = pt.Y; } te.Time = ti.dwTime; te.Mask = ti.dwMask; te.Flags = ti.dwFlags; // Invoke the event handler. handler(this, te); // Mark this event as handled. handled = true; } } CloseTouchInputHandle(m.LParam); return handled; }
private bool DecodeTouch(ref System.Windows.Forms.Message m) { TOUCHINPUT[] touchinputArray; int cInputs = LoWord(m.WParam.ToInt32()); try { touchinputArray = new TOUCHINPUT[cInputs]; } catch (Exception exception) { Debug.Print("ERROR: Could not allocate inputs array"); Debug.Print(exception.ToString()); return(false); } if (!GetTouchInputInfo(m.LParam, cInputs, touchinputArray, this.touchInputSize)) { return(false); } bool flag = false; for (int i = 0; i < cInputs; i++) { TOUCHINPUT touchinput = touchinputArray[i]; EventHandler <EventArgs> handler = null; if ((touchinput.dwFlags & 2) != 0) { handler = new EventHandler <EventArgs>(this.Touchdown); } else if ((touchinput.dwFlags & 4) != 0) { handler = new EventHandler <EventArgs>(this.Touchup); } else if ((touchinput.dwFlags & 1) != 0) { handler = new EventHandler <EventArgs>(this.TouchMove); } if (handler != null) { EventArgs args; try { args = new EventArgs(); } catch (Exception exception2) { Debug.Print("Could not allocate WMTouchEventArgs"); Debug.Print(exception2.ToString()); continue; } args.ContactY = touchinput.cyContact / 100; args.ContactX = touchinput.cxContact / 100; args.Id = touchinput.dwID; Microsoft.Xna.Framework.Point point = new Microsoft.Xna.Framework.Point(touchinput.x / 100, touchinput.y / 100); args.LocationX = point.X; args.LocationY = point.Y; args.Time = touchinput.dwTime; args.Mask = touchinput.dwMask; args.Flags = touchinput.dwFlags; handler(this, args); flag = true; } } CloseTouchInputHandle(m.LParam); return(flag); }
private bool DecodeTouch(ref System.Windows.Forms.Message m) { TOUCHINPUT[] touchinputArray; int cInputs = LoWord(m.WParam.ToInt32()); try { touchinputArray = new TOUCHINPUT[cInputs]; } catch (Exception exception) { Debug.Print("ERROR: Could not allocate inputs array"); Debug.Print(exception.ToString()); return false; } if (!GetTouchInputInfo(m.LParam, cInputs, touchinputArray, this.touchInputSize)) { return false; } bool flag = false; for (int i = 0; i < cInputs; i++) { TOUCHINPUT touchinput = touchinputArray[i]; EventHandler<EventArgs> handler = null; if ((touchinput.dwFlags & 2) != 0) { handler = new EventHandler<EventArgs>(this.Touchdown); } else if ((touchinput.dwFlags & 4) != 0) { handler = new EventHandler<EventArgs>(this.Touchup); } else if ((touchinput.dwFlags & 1) != 0) { handler = new EventHandler<EventArgs>(this.TouchMove); } if (handler != null) { EventArgs args; try { args = new EventArgs(); } catch (Exception exception2) { Debug.Print("Could not allocate WMTouchEventArgs"); Debug.Print(exception2.ToString()); continue; } args.ContactY = touchinput.cyContact / 100; args.ContactX = touchinput.cxContact / 100; args.Id = touchinput.dwID; Microsoft.Xna.Framework.Point point = new Microsoft.Xna.Framework.Point(touchinput.x / 100, touchinput.y / 100); args.LocationX = point.X; args.LocationY = point.Y; args.Time = touchinput.dwTime; args.Mask = touchinput.dwMask; args.Flags = touchinput.dwFlags; handler(this, args); flag = true; } } CloseTouchInputHandle(m.LParam); return flag; }
/// <summary> /// Decodes a single touch point and creates from it the <see cref="PointerPoint"/> class. /// </summary> /// <param name="input">The touch point input structure.</param> private void DecodeAndDispatchTouchPoint(TOUCHINPUT input) { var p = control.PointToClient(new System.Drawing.Point(AdjustX(input.x), AdjustY(input.y))); var mask = input.dwMask; var flags = input.dwFlags; var isPrimary = (flags & User32.TOUCHEVENTF_PRIMARY) != 0; PointerUpdateKind pointerUpdateKind; PointerEventType eventType; if ((flags & User32.TOUCHEVENTF_DOWN) != 0) { pointerUpdateKind = PointerUpdateKind.LeftButtonPressed; eventType = PointerEventType.Pressed; } else if ((flags & User32.TOUCHEVENTF_DOWN) != 0) { pointerUpdateKind = PointerUpdateKind.LeftButtonReleased; eventType = PointerEventType.Released; } else { pointerUpdateKind = PointerUpdateKind.Other; eventType = PointerEventType.Moved; } var clientSize = control.ClientSize; var position = new Vector2((float)p.X / clientSize.Width, (float)p.Y / clientSize.Height); position.Saturate(); var point = new PointerPoint { EventType = eventType, DeviceType = ((flags & User32.TOUCHEVENTF_PEN) != 0) ? PointerDeviceType.Pen : PointerDeviceType.Touch, PointerId = (uint)input.dwID, Timestamp = (ulong)input.dwTime, Position = position, KeyModifiers = GetCurrentKeyModifiers(), IsPrimary = isPrimary, IsInRange = (flags & User32.TOUCHEVENTF_INRANGE) != 0, TouchConfidence = (flags & User32.TOUCHEVENTF_PALM) != 0, PointerUpdateKind = pointerUpdateKind, }; if ((mask & User32.TOUCHINPUTMASKF_CONTACTAREA) != 0) point.ContactRect = new RectangleF(position.X, position.Y, (float)AdjustX(input.cxContact) / clientSize.Width, (float)AdjustY(input.cyContact) / clientSize.Height); manager.AddPointerEvent(ref point); }
/// <summary> /// Decodes touch messages and calls corresponding methods on <see cref="PointerManager"/> class /// </summary> /// <param name="wParam">wParam</param> /// <param name="lParam">lParam</param> private void DecodeAndDispatchTouchMessages(IntPtr wParam, IntPtr lParam) { var inputsCount = User32.LoWord(wParam.ToInt32()); var inputs = new TOUCHINPUT[inputsCount]; try { if (!User32.GetTouchInputInfo(lParam, inputsCount, inputs, Marshal.SizeOf(typeof(TOUCHINPUT)))) throw new InvalidOperationException("Error calling GetTouchInfo API"); for (var i = 0; i < inputsCount; i++) DecodeAndDispatchTouchPoint(inputs[i]); } finally { User32.CloseTouchInputHandle(lParam); } }
void updateTouchFromWM(TOUCHINPUT WM_T) { lock(m_lock) { if ((WM_T.dwFlags & (int)TouchEvent.TOUCHEVENTF_MOVE) != 0) { current[WM_T.dwID] = WM_T; } if ((WM_T.dwFlags & (int)TouchEvent.TOUCHEVENTF_DOWN) != 0) { current.Add(WM_T.dwID, WM_T); } if ((WM_T.dwFlags & (int)TouchEvent.TOUCHEVENTF_UP) != 0) { current.Remove(WM_T.dwID); } } }
public int TouchHookProc(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode < 0) { return CallNextHookEx(0, nCode, wParam, lParam); } switch (nCode) { case HC_ACTION: MSG msg = (MSG)Marshal.PtrToStructure(lParam, typeof(MSG)); // It's ok to call this several times RegisterTouchWindow(msg.hwnd, TWF_WANTPALM); //RegisterPointerInputTarget(msg.hwnd, (int)POINTER_INPUT_TYPE.PT_TOUCH); switch (msg.message) { case WM_TOUCH: int inputCount = LoWord(msg.wParam.ToInt32()); inputs = new TOUCHINPUT[inputCount]; if (GetTouchInputInfo(msg.lParam, inputCount, inputs, Marshal.SizeOf(typeof(TOUCHINPUT)))) { lock (rawTouchesQueue) { rawTouchesQueue.Enqueue(inputs); } CloseTouchInputHandle(msg.lParam); } break; case WM_NCPOINTERDOWN: case WM_NCPOINTERUP: case WM_NCPOINTERUPDATE: case WM_POINTERACTIVATE: case WM_POINTERCAPTURECHANGED: case WM_POINTERDOWN: case WM_POINTERENTER: case WM_POINTERLEAVE: case WM_POINTERUP: case WM_POINTERUPDATE: uint pointerID = (uint)LoWord(msg.wParam.ToInt32()); POINTER_INFO pointerInfo = new POINTER_INFO(); if (GetPointerInfo(pointerID, ref pointerInfo)) { inputs = new TOUCHINPUT[1]; inputs[0] = new TOUCHINPUT(); inputs[0].dwID = pointerInfo.pointerID; inputs[0].x = (uint)pointerInfo.ptPixelLocation.X * 100; inputs[0].y = (uint)pointerInfo.ptPixelLocation.Y * 100; inputs[0].dwFlags = 0; if ((pointerInfo.pointerFlags & POINTER_FLAG_DOWN) == POINTER_FLAG_DOWN) { inputs[0].dwFlags |= TOUCHEVENTF_DOWN; } if ((pointerInfo.pointerFlags & POINTER_FLAG_UPDATE) == POINTER_FLAG_UPDATE) { inputs[0].dwFlags |= TOUCHEVENTF_MOVE; } if ((pointerInfo.pointerFlags & POINTER_FLAG_UP) == POINTER_FLAG_UP) { inputs[0].dwFlags |= TOUCHEVENTF_UP; } lock (rawTouchesQueue) { rawTouchesQueue.Enqueue(inputs); } } break; } break; } return CallNextHookEx(0, nCode, wParam, lParam); }
// Decodes and handles WM_TOUCH message. // Unpacks message arguments and invokes appropriate touch events. // in: // m window message // returns: // whether the message has been handled private bool DecodeTouch(ref Message m) { // More than one touchinput may be associated with a touch message, // so an array is needed to get all event information. int inputCount = LoWord(m.WParam.ToInt32()); // Number of touch inputs, actual per-contact messages TOUCHINPUT[] inputs; // Array of TOUCHINPUT structures inputs = new TOUCHINPUT[inputCount]; // Allocate the storage for the parameters of the per-contact messages // Unpack message parameters into the array of TOUCHINPUT structures, each // representing a message for one single contact. if (!GetTouchInputInfo(m.LParam, inputCount, inputs, touchInputSize)) { // Get touch info failed. return(false); } // For each contact, dispatch the message to the appropriate message // handler. bool handled = false; // Boolean, is message handled for (int i = 0; i < inputCount; i++) { TOUCHINPUT ti = inputs[i]; // Assign a handler to this message. EventHandler <WMTouchEventArgs> handler = null; // Touch event handler if ((ti.dwFlags & TOUCHEVENTF_DOWN) != 0) { handler = Touchdown; } else if ((ti.dwFlags & TOUCHEVENTF_UP) != 0) { handler = Touchup; } else if ((ti.dwFlags & TOUCHEVENTF_MOVE) != 0) { handler = TouchMove; } // Convert message parameters into touch event arguments and handle the event. if (handler != null) { // Convert the raw touchinput message into a touchevent. WMTouchEventArgs te = new WMTouchEventArgs(); // Touch event arguments // TOUCHINFO point coordinates and contact size is in 1/100 of a pixel; convert it to pixels. // Also convert screen to client coordinates. te.ContactY = ti.cyContact / 100; te.ContactX = ti.cxContact / 100; te.Id = ti.dwID; { Point pt = PointToClient(new Point(ti.x / 100, ti.y / 100)); te.LocationX = pt.X; te.LocationY = pt.Y; } te.Time = ti.dwTime; te.Mask = ti.dwMask; te.Flags = ti.dwFlags; // Invoke the event handler. handler(this, te); // Mark this event as handled. handled = true; } } CloseTouchInputHandle(m.LParam); return(handled); }
public POINT getClientPoint(TOUCHINPUT WM_T) { POINT p = new POINT(); p.X = WM_T.x / 100; p.Y = WM_T.y / 100; ScreenToClient(hMainWindow, ref p); return p; }