Ejemplo n.º 1
0
        private void InputDeviceEvents_PreProcessInput(object sender, PreProcessInputEventArgs e)
        {
            if (e.StagingItem.Input.Device is TouchDevice)
            {
                InputReportEventArgs irea = e.StagingItem.Input as InputReportEventArgs;
                if (irea != null)
                {
                    RawTouchInputReport rtir = irea.Report as RawTouchInputReport;
                    if (rtir != null)
                    {
                        // cancel any touch event that does not start within the modal window
                        //if (!this.ContainsPoint(rtir.Touches[0].X, rtir.Touches[0].Y))
                        //    e.Cancel();

                        int x = rtir.Touches[0].X;
                        int y = rtir.Touches[0].Y;
                        PointToClient(ref x, ref y);
                        if (!Utils.IsWithinRectangle(x, y, ActualWidth, ActualWidth))
                        {
                            e.Cancel();
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        internal override void Synchronize()
        {
            // Simulate a stylus move (if we are current stylus, inrange, visuals still valid to update
            // and has moved).
            if (InRange && _inputSource != null && _inputSource.Value != null &&
                _inputSource.Value.CompositionTarget != null && !_inputSource.Value.CompositionTarget.IsDisposed)
            {
                Point rawScreenPoint = new Point(_pointerData.Info.ptPixelLocationRaw.X, _pointerData.Info.ptPixelLocationRaw.Y);
                Point ptDevice       = PointUtil.ScreenToClient(rawScreenPoint, _inputSource.Value);

                // GlobalHitTest always returns an IInputElement, so we are sure to have one.
                IInputElement stylusOver     = Input.StylusDevice.GlobalHitTest(_inputSource.Value, ptDevice);
                bool          fOffsetChanged = false;

                if (_stylusOver == stylusOver)
                {
                    Point ptOffset = GetPosition(stylusOver);
                    fOffsetChanged = MS.Internal.DoubleUtil.AreClose(ptOffset.X, _rawElementRelativePosition.X) == false || MS.Internal.DoubleUtil.AreClose(ptOffset.Y, _rawElementRelativePosition.Y) == false;
                }

                if (fOffsetChanged || _stylusOver != stylusOver)
                {
                    int timeStamp = Environment.TickCount;

                    if (_currentStylusPoints != null &&
                        _currentStylusPoints.Count > 0 &&
                        StylusPointDescription.AreCompatible(PointerTabletDevice.StylusPointDescription, _currentStylusPoints.Description))
                    {
                        StylusPoint stylusPoint = _currentStylusPoints[_currentStylusPoints.Count - 1];
                        int[]       data        = stylusPoint.GetPacketData();

                        // get back to the correct coordinate system
                        Matrix m = _tabletDevice.TabletToScreen;
                        m.Invert();
                        Point ptTablet = ptDevice * m;

                        data[0] = (int)ptTablet.X;
                        data[1] = (int)ptTablet.Y;

                        RawStylusInputReport report = new RawStylusInputReport(InputMode.Foreground,
                                                                               timeStamp,
                                                                               _inputSource.Value,
                                                                               InAir ? RawStylusActions.InAirMove : RawStylusActions.Move,
                                                                               () => { return(PointerTabletDevice.StylusPointDescription); },
                                                                               TabletDevice.Id,
                                                                               Id,
                                                                               data);


                        report.Synchronized = true;

                        InputReportEventArgs inputReportEventArgs = new InputReportEventArgs(StylusDevice, report);
                        inputReportEventArgs.RoutedEvent = InputManager.PreviewInputReportEvent;

                        InputManager.Current.ProcessInput(inputReportEventArgs);
                    }
                }
            }
        }
Ejemplo n.º 3
0
        private void HandleInteraction(object clientData, RawStylusSystemGestureInputReport originalReport)
        {
            RawStylusSystemGestureInputReport report = new RawStylusSystemGestureInputReport(
                InputMode.Foreground,
                Environment.TickCount,
                CriticalActiveSource,
                () => { return(PointerTabletDevice.StylusPointDescription); },
                TabletDevice.Id,
                Id,
                originalReport.SystemGesture,
                originalReport.GestureX,
                originalReport.GestureY,
                originalReport.ButtonState)
            {
                StylusDevice = StylusDevice,
            };

            // For a flick, update the points in the stylus device to the flick location.
            // This forces processing of the stylus over to use the initial flick location
            // instead of the last WM_POINTER message location allowing command processing to
            // be done on the flick location itself.
            if (report.SystemGesture == SystemGesture.Flick)
            {
                StylusPoint flickPoint = _currentStylusPoints[_currentStylusPoints.Count - 1];

                flickPoint.X = report.GestureX;
                flickPoint.Y = report.GestureY;

                _currentStylusPoints = new StylusPointCollection(flickPoint.Description,
                                                                 flickPoint.GetPacketData(),
                                                                 GetTabletToElementTransform(null),
                                                                 Matrix.Identity);
            }

            InputReportEventArgs irea = new InputReportEventArgs(StylusDevice, report)
            {
                RoutedEvent = InputManager.PreviewInputReportEvent,
            };

            // Now send the input report
            InputManager.UnsecureCurrent.ProcessInput(irea);
        }
Ejemplo n.º 4
0
 private void InputDeviceEvents_PreProcessInput(object sender, PreProcessInputEventArgs e)
 {
     if (e.StagingItem.Input.Device is TouchDevice)
     {
         InputReportEventArgs irea = e.StagingItem.Input as InputReportEventArgs;
         if (irea != null)
         {
             RawTouchInputReport rtir = irea.Report as RawTouchInputReport;
             if (rtir != null)
             {
                 int x = rtir.Touches[0].X;
                 int y = rtir.Touches[0].Y;
                 PointToClient(ref x, ref y);
                 if (!Utils.IsWithinRectangle(x, y, ActualWidth, ActualWidth))
                 {
                     e.Cancel();
                 }
             }
         }
     }
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Processes the latest WM_POINTER message and forwards it to the WPF input stack.
        /// </summary>
        /// <param name="pointerId">The id of the pointer message</param>
        /// <param name="action">The stylus action being done</param>
        /// <param name="timestamp">The time (in ticks) the message arrived</param>
        /// <returns>True if successfully processed (handled), false otherwise</returns>
        private bool ProcessMessage(uint pointerId, RawStylusActions action, int timestamp)
        {
            bool handled = false;

            // Acquire all pointer data needed
            PointerData data = new PointerData(pointerId);

            // Only process touch or pen messages, do not process mouse or touchpad
            if (data.IsValid &&
                (data.Info.pointerType == UnsafeNativeMethods.POINTER_INPUT_TYPE.PT_TOUCH ||
                 data.Info.pointerType == UnsafeNativeMethods.POINTER_INPUT_TYPE.PT_PEN))
            {
                uint cursorId = 0;

                if (UnsafeNativeMethods.GetPointerCursorId(pointerId, ref cursorId))
                {
                    IntPtr deviceId = data.Info.sourceDevice;

                    // If we cannot acquire the latest tablet and stylus then wait for the
                    // next message.
                    if (!UpdateCurrentTabletAndStylus(deviceId, cursorId))
                    {
                        return(false);
                    }

                    // Convert move to InAirMove if applicable
                    if (action == RawStylusActions.Move &&
                        (!data.Info.pointerFlags.HasFlag(UnsafeNativeMethods.POINTER_FLAGS.POINTER_FLAG_INCONTACT) &&
                         data.Info.pointerFlags.HasFlag(UnsafeNativeMethods.POINTER_FLAGS.POINTER_FLAG_INRANGE)))
                    {
                        action = RawStylusActions.InAirMove;
                    }

                    // Generate a raw input to send to the input manager to start the event chain in PointerLogic
                    RawStylusInputReport rsir =
                        new RawStylusInputReport(
                            InputMode.Foreground,
                            timestamp,
                            _source.Value,
                            action,
                            () => { return(_currentTabletDevice.StylusPointDescription); },
                            _currentTabletDevice.Id,
                            _currentStylusDevice.Id,
                            GenerateRawStylusData(data, _currentTabletDevice))
                    {
                        StylusDevice = _currentStylusDevice.StylusDevice,
                    };

                    // Send the input report to the stylus plugins if we're not doing a drag and the window
                    // is currently enabled.
                    if (!_pointerLogic.Value.InDragDrop && IsWindowEnabled)
                    {
                        PointerStylusPlugInManager manager;

                        if (_pointerLogic.Value.PlugInManagers.TryGetValue(_source.Value, out manager))
                        {
                            manager.InvokeStylusPluginCollection(rsir);
                        }
                    }

                    // Update the data in the stylus device with the latest pointer data
                    _currentStylusDevice.Update(this, _source.Value, data, rsir);

                    // Call the StylusDevice to process and fire any interactions that
                    // might have resulted from the input.  If the originating inputs
                    // have been handled, we don't want to generate any gestures.
                    _currentStylusDevice.UpdateInteractions(rsir);

                    InputReportEventArgs irea = new InputReportEventArgs(_currentStylusDevice.StylusDevice, rsir)
                    {
                        RoutedEvent = InputManager.PreviewInputReportEvent,
                    };

                    // Now send the input report
                    InputManager.UnsecureCurrent.ProcessInput(irea);

                    // If this is not a primary pointer input, we don't want to
                    // allow it to go to DefWindowProc, so we should handle it.
                    // This ensures that primary pointer to mouse promotions
                    // will occur in multi-touch scenarios.
                    // We don't use the results of the input processing here as doing
                    // so could possibly cause some messages of a pointer chain as
                    // being handled, and some as being unhandled.  This results in
                    // undefined behavior in the WM_POINTER stack.
                    // <see cref="https://msdn.microsoft.com/en-us/library/windows/desktop/hh454923(v=vs.85).aspx"/>
                    handled = !_currentStylusDevice.IsPrimary;
                }
            }

            return(handled);
        }
Ejemplo n.º 6
0
 private void OnPostProcessInput(object sender, ProcessInputEventArgs e)
 {
     if (e.StagingItem.Input.RoutedEvent == InputManager.InputReportEvent)
     {
         InputReportEventArgs inputReportEventArgs = (InputReportEventArgs)e.StagingItem.Input;
         if (!inputReportEventArgs.Handled && inputReportEventArgs.Report.Type == InputType.Mouse)
         {
             RawMouseInputReport rawMouseInputReport = (RawMouseInputReport)inputReportEventArgs.Report;
             if ((rawMouseInputReport.Actions & RawMouseActions.AbsoluteMove) == RawMouseActions.AbsoluteMove)
             {
                 if (Mouse.LeftButton == MouseButtonState.Pressed || Mouse.RightButton == MouseButtonState.Pressed)
                 {
                     this.RaiseToolTipClosingEvent(true);
                     return;
                 }
                 IInputElement inputElement = Mouse.PrimaryDevice.RawDirectlyOver;
                 if (inputElement != null)
                 {
                     Point position = Mouse.PrimaryDevice.GetPosition(inputElement);
                     if (Mouse.CapturedMode != CaptureMode.None)
                     {
                         PresentationSource presentationSource = PresentationSource.CriticalFromVisual((DependencyObject)inputElement);
                         UIElement          uIElement          = (presentationSource != null) ? (presentationSource.RootVisual as UIElement) : null;
                         if (uIElement != null)
                         {
                             position = Mouse.PrimaryDevice.GetPosition(uIElement);
                             IInputElement inputElement2;
                             uIElement.InputHitTest(position, out inputElement2, out inputElement);
                             position = Mouse.PrimaryDevice.GetPosition(inputElement);
                         }
                         else
                         {
                             inputElement = null;
                         }
                     }
                     if (inputElement != null)
                     {
                         this.OnMouseMove(inputElement, position);
                         return;
                     }
                 }
             }
             else if ((rawMouseInputReport.Actions & RawMouseActions.Deactivate) == RawMouseActions.Deactivate && this.LastMouseDirectlyOver != null)
             {
                 this.LastMouseDirectlyOver = null;
                 if (this.LastMouseOverWithToolTip != null)
                 {
                     this.RaiseToolTipClosingEvent(true);
                     if (SafeNativeMethods.GetCapture() == IntPtr.Zero)
                     {
                         this.LastMouseOverWithToolTip = null;
                         return;
                     }
                 }
             }
         }
     }
     else
     {
         if (e.StagingItem.Input.RoutedEvent == Keyboard.KeyDownEvent)
         {
             this.ProcessKeyDown(sender, (KeyEventArgs)e.StagingItem.Input);
             return;
         }
         if (e.StagingItem.Input.RoutedEvent == Keyboard.KeyUpEvent)
         {
             this.ProcessKeyUp(sender, (KeyEventArgs)e.StagingItem.Input);
             return;
         }
         if (e.StagingItem.Input.RoutedEvent == Mouse.MouseUpEvent)
         {
             this.ProcessMouseUp(sender, (MouseButtonEventArgs)e.StagingItem.Input);
             return;
         }
         if (e.StagingItem.Input.RoutedEvent == Mouse.MouseDownEvent)
         {
             this.RaiseToolTipClosingEvent(true);
         }
     }
 }
Ejemplo n.º 7
0
        /////////////////////////////////////////////////////////////////////
        private void OnPostProcessInput(object sender, ProcessInputEventArgs e)
        {
            if (e.StagingItem.Input.RoutedEvent == InputManager.InputReportEvent)
            {
                InputReportEventArgs report = (InputReportEventArgs)e.StagingItem.Input;
                if (!report.Handled)
                {
                    if (report.Report.Type == InputType.Mouse)
                    {
                        RawMouseInputReport mouseReport = (RawMouseInputReport)report.Report;
                        if ((mouseReport.Actions & RawMouseActions.AbsoluteMove) == RawMouseActions.AbsoluteMove)
                        {
                            if ((Mouse.LeftButton == MouseButtonState.Pressed) ||
                                (Mouse.RightButton == MouseButtonState.Pressed))
                            {
                                RaiseToolTipClosingEvent(true /* reset */);
                            }
                            else
                            {
                                IInputElement directlyOver = Mouse.PrimaryDevice.RawDirectlyOver;
                                if (directlyOver != null)
                                {
                                    Point pt = Mouse.PrimaryDevice.GetPosition(directlyOver);

                                    // If possible, check that the mouse position is within the render bounds
                                    // (avoids mouse capture confusion).
                                    if (Mouse.CapturedMode != CaptureMode.None)
                                    {
                                        // Get the root visual
                                        PresentationSource source          = PresentationSource.CriticalFromVisual((DependencyObject)directlyOver);
                                        UIElement          rootAsUIElement = source != null ? source.RootVisual as UIElement : null;
                                        if (rootAsUIElement != null)
                                        {
                                            // Get mouse position wrt to root
                                            pt = Mouse.PrimaryDevice.GetPosition(rootAsUIElement);

                                            // Hittest to find the element the mouse is over
                                            IInputElement enabledHit;
                                            rootAsUIElement.InputHitTest(pt, out enabledHit, out directlyOver);

                                            // Find the position of the mouse relative the element that the mouse is over
                                            pt = Mouse.PrimaryDevice.GetPosition(directlyOver);
                                        }
                                        else
                                        {
                                            directlyOver = null;
                                        }
                                    }

                                    if (directlyOver != null)
                                    {
                                        // Process the mouse move
                                        OnMouseMove(directlyOver, pt);
                                    }
                                }
                            }
                        }
                        else if ((mouseReport.Actions & RawMouseActions.Deactivate) == RawMouseActions.Deactivate)
                        {
                            if (LastMouseDirectlyOver != null)
                            {
                                LastMouseDirectlyOver = null;
                                if (LastMouseOverWithToolTip != null)
                                {
                                    RaiseToolTipClosingEvent(true /* reset */);

                                    // When the user moves the cursor outside of the window,
                                    // clear the LastMouseOverWithToolTip property so if the user returns
                                    // the mouse to the same item, the tooltip will reappear.  If
                                    // the deactivation is coming from a window grabbing capture
                                    // (such as Drag and Drop) do not clear the property.
                                    if (MS.Win32.SafeNativeMethods.GetCapture() == IntPtr.Zero)
                                    {
                                        LastMouseOverWithToolTip = null;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else if (e.StagingItem.Input.RoutedEvent == Keyboard.KeyDownEvent)
            {
                ProcessKeyDown(sender, (KeyEventArgs)e.StagingItem.Input);
            }
            else if (e.StagingItem.Input.RoutedEvent == Keyboard.KeyUpEvent)
            {
                ProcessKeyUp(sender, (KeyEventArgs)e.StagingItem.Input);
            }
            else if (e.StagingItem.Input.RoutedEvent == Mouse.MouseUpEvent)
            {
                ProcessMouseUp(sender, (MouseButtonEventArgs)e.StagingItem.Input);
            }
            else if (e.StagingItem.Input.RoutedEvent == Mouse.MouseDownEvent)
            {
                RaiseToolTipClosingEvent(true /* reset */);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Used in order to allow StylusPlugins to affect mouse inputs as well as touch.
        /// </summary>
        internal static void InvokePlugInsForMouse(ProcessInputEventArgs e)
        {
            if (!e.StagingItem.Input.Handled)
            {
                // if we see a preview mouse event that is not generated by a stylus
                // then send on to plugin
                if ((e.StagingItem.Input.RoutedEvent != Mouse.PreviewMouseDownEvent) &&
                    (e.StagingItem.Input.RoutedEvent != Mouse.PreviewMouseUpEvent) &&
                    (e.StagingItem.Input.RoutedEvent != Mouse.PreviewMouseMoveEvent) &&
                    (e.StagingItem.Input.RoutedEvent != InputManager.InputReportEvent))
                {
                    return;
                }

                // record the mouse capture for later reference..
                MouseDevice        mouseDevice;
                PresentationSource source;
                bool             leftButtonDown;
                bool             rightButtonDown;
                RawStylusActions stylusActions = RawStylusActions.None;
                int timestamp;

                // See if we need to deal sending a leave due to this PresentationSource being Deactivated
                // If not then we just return and do nothing.
                if (e.StagingItem.Input.RoutedEvent == InputManager.InputReportEvent)
                {
                    if (_activeMousePlugInCollection?.Element == null)
                    {
                        return;
                    }

                    InputReportEventArgs input = e.StagingItem.Input as InputReportEventArgs;

                    if (input.Report.Type != InputType.Mouse)
                    {
                        return;
                    }

                    RawMouseInputReport mouseInputReport = (RawMouseInputReport)input.Report;

                    if ((mouseInputReport.Actions & RawMouseActions.Deactivate) != RawMouseActions.Deactivate)
                    {
                        return;
                    }

                    mouseDevice = InputManager.UnsecureCurrent.PrimaryMouseDevice;

                    // Mouse set directly over to null when truly deactivating.
                    if (mouseDevice == null || mouseDevice.DirectlyOver != null)
                    {
                        return;
                    }

                    leftButtonDown  = mouseDevice.LeftButton == MouseButtonState.Pressed;
                    rightButtonDown = mouseDevice.RightButton == MouseButtonState.Pressed;
                    timestamp       = mouseInputReport.Timestamp;

                    // Get presentationsource from element.
                    source = PresentationSource.CriticalFromVisual(_activeMousePlugInCollection.Element as Visual);
                }
                else
                {
                    MouseEventArgs mouseEventArgs = e.StagingItem.Input as MouseEventArgs;
                    mouseDevice     = mouseEventArgs.MouseDevice;
                    leftButtonDown  = mouseDevice.LeftButton == MouseButtonState.Pressed;
                    rightButtonDown = mouseDevice.RightButton == MouseButtonState.Pressed;

                    // Only look at mouse input reports that truly come from a mouse (and is not an up or deactivate) and it
                    // must be pressed state if a move (we don't fire stylus inair moves currently)
                    if (mouseEventArgs.StylusDevice != null &&
                        e.StagingItem.Input.RoutedEvent != Mouse.PreviewMouseUpEvent)
                    {
                        return;
                    }

                    if (e.StagingItem.Input.RoutedEvent == Mouse.PreviewMouseMoveEvent)
                    {
                        if (!leftButtonDown)
                        {
                            return;
                        }
                        stylusActions = RawStylusActions.Move;
                    }
                    if (e.StagingItem.Input.RoutedEvent == Mouse.PreviewMouseDownEvent)
                    {
                        MouseButtonEventArgs mouseButtonEventArgs = mouseEventArgs as MouseButtonEventArgs;
                        if (mouseButtonEventArgs.ChangedButton != MouseButton.Left)
                        {
                            return;
                        }
                        stylusActions = RawStylusActions.Down;
                    }
                    if (e.StagingItem.Input.RoutedEvent == Mouse.PreviewMouseUpEvent)
                    {
                        MouseButtonEventArgs mouseButtonEventArgs = mouseEventArgs as MouseButtonEventArgs;
                        if (mouseButtonEventArgs.ChangedButton != MouseButton.Left)
                        {
                            return;
                        }
                        stylusActions = RawStylusActions.Up;
                    }
                    timestamp = mouseEventArgs.Timestamp;

                    Visual directlyOverVisual = mouseDevice.DirectlyOver as Visual;
                    if (directlyOverVisual == null)
                    {
                        return;
                    }

                    //
                    // Take the presentation source which is associated to the directly over element.
                    source = PresentationSource.CriticalFromVisual(directlyOverVisual);
                }

                if ((source != null) &&
                    (source.CompositionTarget != null) &&
                    !source.CompositionTarget.IsDisposed)
                {
                    IInputElement directlyOver = mouseDevice.DirectlyOver;
                    int           packetStatus = (leftButtonDown ? 1 : 0) | (rightButtonDown ? 9 : 0); // pen tip down == 1, barrel = 8
                    Point         ptClient     = mouseDevice.GetPosition(source.RootVisual as IInputElement);
                    ptClient = source.CompositionTarget.TransformToDevice.Transform(ptClient);

                    int   buttons = (leftButtonDown ? 1 : 0) | (rightButtonDown ? 3 : 0);
                    int[] data    = { (int)ptClient.X, (int)ptClient.Y, packetStatus, buttons };
                    RawStylusInputReport inputReport = new RawStylusInputReport(
                        InputMode.Foreground,
                        timestamp,
                        source,
                        stylusActions,
                        () => { return(MousePointDescription); },
                        0, 0,
                        data);

                    PointerStylusPlugInManager manager =
                        StylusLogic.GetCurrentStylusLogicAs <PointerLogic>()?.GetManagerForSource(source);

                    // Avoid re-entrancy due to lock() being used.
                    using (Dispatcher.CurrentDispatcher.DisableProcessing())
                    {
                        // Call plugins (does enter/leave and FireCustomData as well)
                        _activeMousePlugInCollection = manager?.InvokeStylusPluginCollectionForMouse(inputReport, directlyOver, _activeMousePlugInCollection);
                    }
                }
            }
        }