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