Пример #1
0
 /// <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);
 }
Пример #2
0
        /// <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);
            }
        }
Пример #3
0
    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);
    }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        /// <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);
        }
    }
Пример #8
0
        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;
        }
Пример #9
0
        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;
            }
        }
Пример #10
0
            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);
            }
Пример #11
0
        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);
        }
Пример #12
0
        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);
        }
Пример #13
0
 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);
         }
     }
 }
Пример #14
0
    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);
    }
Пример #15
0
        /// <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);
            }
        }
Пример #16
0
        // 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;
        }
Пример #17
0
        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));
        }
Пример #18
0
        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);
        }
Пример #19
0
    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);
    }
Пример #20
0
        /// <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);
        }
Пример #21
0
        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;
        }
Пример #23
0
        // 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;
        }
Пример #24
0
        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);
        }
Пример #25
0
 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);
            }
        }
Пример #28
0
	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);
			}
		}
	}
Пример #29
0
    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);
        }
Пример #31
0
	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;
	}