/// <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); } }
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; }
/// <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); } }