Example #1
0
        // IsValid Method for RawMouseActions. Relies on the enum being flags.
        internal static bool IsValidRawMouseActions(RawMouseActions actions)
        {
            if (actions == RawMouseActions.None)
            {
                return(true);
            }

            if (((RawMouseActions.AttributesChanged | RawMouseActions.Activate | RawMouseActions.Deactivate |
                  RawMouseActions.RelativeMove | RawMouseActions.AbsoluteMove | RawMouseActions.VirtualDesktopMove |
                  RawMouseActions.Button1Press | RawMouseActions.Button1Release |
                  RawMouseActions.Button2Press | RawMouseActions.Button2Release |
                  RawMouseActions.Button3Press | RawMouseActions.Button3Release |
                  RawMouseActions.Button4Press | RawMouseActions.Button4Release |
                  RawMouseActions.Button5Press | RawMouseActions.Button5Release |
                  RawMouseActions.VerticalWheelRotate | RawMouseActions.HorizontalWheelRotate |
                  RawMouseActions.CancelCapture |
                  RawMouseActions.QueryCursor) & actions) == actions)
            {
                if (!(((RawMouseActions.Deactivate & actions) == actions && RawMouseActions.Deactivate != actions) ||
                      (((RawMouseActions.Button1Press | RawMouseActions.Button1Release) & actions) == (RawMouseActions.Button1Press | RawMouseActions.Button1Release)) ||
                      (((RawMouseActions.Button2Press | RawMouseActions.Button2Release) & actions) == (RawMouseActions.Button2Press | RawMouseActions.Button2Release)) ||
                      (((RawMouseActions.Button3Press | RawMouseActions.Button3Release) & actions) == (RawMouseActions.Button3Press | RawMouseActions.Button3Release)) ||
                      (((RawMouseActions.Button4Press | RawMouseActions.Button4Release) & actions) == (RawMouseActions.Button4Press | RawMouseActions.Button4Release)) ||
                      (((RawMouseActions.Button5Press | RawMouseActions.Button5Release) & actions) == (RawMouseActions.Button5Press | RawMouseActions.Button5Release))))
                {
                    return(true);
                }
            }
            return(false);
        }
Example #2
0
        /// <summary>
        ///     Constructs ad instance of the RawMouseInputReport class.
        /// </summary>
        /// <param name="mode">
        ///     The mode in which the input is being provided.
        /// </param>
        /// <param name="timestamp">
        ///     The time when the input occured.
        /// </param>
        /// <param name="inputSource">
        ///     The PresentationSource over which the mouse is moved.
        /// </param>
        /// <param name="actions">
        ///     The set of actions being reported.
        /// </param>
        /// <param name="x">
        ///     If horizontal position being reported.
        /// </param>
        /// <param name="y">
        ///     If vertical position being reported.
        /// </param>
        /// <param name="wheel">
        ///     If wheel delta being reported.
        /// </param>
        /// <param name="extraInformation">
        ///     Any extra information being provided along with the input.
        /// </param>
        /// <SecurityNote>
        ///     Critical:This handles critical data in the form of PresentationSource and ExtraInformation
        ///     TreatAsSafe:There are demands on the  critical data(PresentationSource/ExtraInformation)
        /// </SecurityNote>
        private void RaisePreviewMouseMoveEvent(InputMode mode, RawMouseActions actions, PresentationSource inputSource, RoutedEvent @event, int timestamp, int pointX, int pointY, int wheel)
        {
            Assembly targetAssembly       = Assembly.GetAssembly(typeof(InputEventArgs));
            Type     mouseInputReportType = targetAssembly.GetType("System.Windows.Input.RawMouseInputReport");

            // RawMouseInputReport mouseInputReport = new RawMouseInputReport(...);
            Object mouseInputReport = mouseInputReportType.GetConstructors()[0].Invoke(new Object[] {
                mode,
                timestamp,
                inputSource,
                actions,
                pointX,
                pointY,
                wheel,
                IntPtr.Zero
            });

            // mouseInputReport._isSynchronize = true;
            mouseInputReportType
            .GetField("_isSynchronize", BindingFlags.NonPublic | BindingFlags.Instance)
            .SetValue(mouseInputReport, true);

            // InputReportEventArgs inputReportEventArgs = new InputReportEventArgs(...);
            InputEventArgs inputReportEventArgs = (InputEventArgs)targetAssembly
                                                  .GetType("System.Windows.Input.InputReportEventArgs")
                                                  .GetConstructors()[0]
                                                  .Invoke(new Object[] { Mouse.PrimaryDevice, mouseInputReport });

            inputReportEventArgs.RoutedEvent = (RoutedEvent)typeof(InputManager)
                                               .GetField("PreviewInputReportEvent", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
                                               .GetValue(null);

            //this.RaiseEvent((InputEventArgs)inputReportEventArgs);
            InputManager.Current.ProcessInput((InputEventArgs)inputReportEventArgs);
        }
        public RawMouseInputReport(
            InputMode mode,
            int timestamp, 
            PresentationSource inputSource,
            RawMouseActions actions, 
            int x, 
            int y, 
            int wheel, 
            IntPtr extraInformation) : base(inputSource, InputType.Mouse, mode, timestamp)
        {
            if (!IsValidRawMouseActions(actions))
                throw new System.ComponentModel.InvalidEnumArgumentException("actions", (int)actions, typeof(RawMouseActions));

            /* we pass a null state from MouseDevice.PreProcessorInput, so null is valid value for state */
            _actions = actions;
            _x = x;
            _y = y;
            _wheel = wheel;
            _extraInformation = new SecurityCriticalData<IntPtr>(extraInformation);
        }
Example #4
0
        /// <summary>
        ///     Constructs ad instance of the RawMouseInputReport class.
        /// </summary>
        /// <param name="mode">
        ///     The mode in which the input is being provided.
        /// </param>
        /// <param name="timestamp">
        ///     The time when the input occured.
        /// </param>
        /// <param name="inputSource">
        ///     The PresentationSource over which the mouse is moved.
        /// </param>
        /// <param name="actions">
        ///     The set of actions being reported.
        /// </param>
        /// <param name="x">
        ///     If horizontal position being reported.
        /// </param>
        /// <param name="y">
        ///     If vertical position being reported.
        /// </param>
        /// <param name="wheel">
        ///     If wheel delta being reported.
        /// </param>
        /// <param name="extraInformation">
        ///     Any extra information being provided along with the input.
        /// </param>
        public RawMouseInputReport(
            InputMode mode,
            int timestamp,
            PresentationSource inputSource,
            RawMouseActions actions,
            int x,
            int y,
            int wheel,
            IntPtr extraInformation) : base(inputSource, InputType.Mouse, mode, timestamp)
        {
            if (!IsValidRawMouseActions(actions))
            {
                throw new System.ComponentModel.InvalidEnumArgumentException("actions", (int)actions, typeof(RawMouseActions));
            }

            /* we pass a null state from MouseDevice.PreProcessorInput, so null is valid value for state */
            _actions          = actions;
            _x                = x;
            _y                = y;
            _wheel            = wheel;
            _extraInformation = new SecurityCriticalData <IntPtr>(extraInformation);
        }
Example #5
0
 /// <summary>
 /// Construct RawMouseInputReportWrapper with mouse state.
 /// </summary>
 /// <param name="mode">mode</param>
 /// <param name="timestamp">timestamp</param>
 /// <param name="inputSource">inputSource</param>
 /// <param name="actions">actions</param>
 /// <param name="x">x</param>
 /// <param name="y">y</param>
 /// <param name="wheel">wheel</param>
 /// <param name="extraInformation">extraInformation</param>
 /// <param name="state">state</param>
 public RawMouseInputReportWrapper(InputMode mode, int timestamp, PresentationSource inputSource, RawMouseActions actions, int x, int y, int wheel, IntPtr extraInformation, RawMouseState state)
     : base()
 {
     object[] objArrayInputReportConstructor = new object[] { mode, timestamp, inputSource, actions, x, y, wheel, extraInformation, state };
     this.InnerObject = Activator.CreateInstance(ReportType, objArrayInputReportConstructor);
     Trace.Assert(this.InnerObject != null, "Uh oh, not an input report");
 }
Example #6
0
        private bool ReportInput(
            IntPtr hwnd,
            InputMode mode,
            int timestamp,
            RawMouseActions actions,
            int x,
            int y,
            int wheel)
        {
            // if there's no HwndSource, we shouldn't get here.  But just in case...
            Debug.Assert(null != _source && null != _source.Value);
            if (_source == null || _source.Value == null)
            {
                return false;
            }

            PresentationSource source = _source.Value;
            CompositionTarget ct = source.CompositionTarget;

            // Input reports should only be generated if the window is still valid.
            if(_site == null || source.IsDisposed || ct == null )
            {
                if(_active)
                {
                    // We are still active, but the window is dead.  Force a deactivate.
                    actions = RawMouseActions.Deactivate;
                }
                else
                {
                    return false;
                }
            }

            if((actions & RawMouseActions.Deactivate) == RawMouseActions.Deactivate)
            {
                // Stop tracking the mouse since we are deactivating.
                StopTracking(hwnd);

                _active = false;
            }
            else if((actions & RawMouseActions.CancelCapture) == RawMouseActions.CancelCapture)
            {
                // We have lost capture, but don't do anything else.
            }
            else if(!_active && (actions & RawMouseActions.VerticalWheelRotate) == RawMouseActions.VerticalWheelRotate)
            {
                // report mouse wheel events as if they came from the window that
                // is under the mouse (even though they are reported to the window
                // with keyboard focus)
                MouseDevice mouse = _site.Value.CriticalInputManager.PrimaryMouseDevice;
                if (mouse != null && mouse.CriticalActiveSource != null)
                {
                    source = mouse.CriticalActiveSource;
                }
            }
            else
            {
                // If we are not active, we need to activate first.
                if(!_active)
                {
                    // But first, check for "spurious" mouse events...
                    //
                    // Sometimes we get a mouse move for window "A" AFTER another
                    // window ("B") has become active.  This would cause "A" to think
                    // that it is active, and to tell Avalon. Now both "A" and "B" think
                    // they are active, and Avalon thinks "A" is, but REALLY, "B" is.
                    //
                    // Confused yet?
                    //
                    // To avoid this, if this window ("A") gets a mouse move,
                    // we verify that either "A" has capture, or the mouse is over "A"

                    IntPtr hwndToCheck = SafeNativeMethods.GetCapture();
                    if(hwnd != hwndToCheck)
                    {
                        // If we get this far, "A" does NOT have capture
                        // - now ensure mouse is over "A"
                        NativeMethods.POINT ptCursor = new NativeMethods.POINT();
                        try
                        {
                            UnsafeNativeMethods.GetCursorPos(ptCursor);
                        }
                        catch(System.ComponentModel.Win32Exception)
                        {
                            // Sometimes Win32 will fail this call, such as if you are
                            // not running in the interactive desktop.  For example,
                            // a secure screen saver may be running.
                            System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: GetCursorPos failed!");
                        }

                        try
                        {
                            hwndToCheck = UnsafeNativeMethods.WindowFromPoint(ptCursor.x, ptCursor.y);
                        }
                        catch(System.ComponentModel.Win32Exception)
                        {
                            System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: WindowFromPoint failed!");
                        }

                        if(hwnd != hwndToCheck)
                        {
                            // If we get this far:
                            // - the mouse is NOT over "A"
                            // - "A" does NOT have capture
                            // We consider this a "spurious" mouse move and ignore it. (Win32 bug?)
                            System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: Spurious mouse event received!");
                            return false;
                        }
                    }


                    // We need to collect the current state of the mouse.
                    // Include the activation action.
                    actions |= RawMouseActions.Activate;

                    // Remember that we are active.
                    _active = true;
                    _lastX = x;
                    _lastY = y;

                    //Console.WriteLine("Activating the mouse.");
                }

                // Make sure we are tracking the mouse so we know when it
                // leaves the window.
                StartTracking(hwnd);

                // Even if a move isn't explicitly reported, we still may need to
                // report one if the coordinates are different.  This is to cover
                // some ugly edge cases with context menus and such.
                if((actions & RawMouseActions.AbsoluteMove) == 0)
                {
                    if(x != _lastX || y != _lastY)
                    {
                        actions |= RawMouseActions.AbsoluteMove;
                    }
                }
                else
                {
                    _lastX = x;
                    _lastY = y;
                }

                // record mouse motion so that GetIntermediatePoints has the
                // information it needs
                if ((actions & RawMouseActions.AbsoluteMove) != 0)
                {
                    RecordMouseMove(x, y, _msgTime);
                }

                // MITIGATION: WIN32_AND_AVALON_RTL
                //
                // When a window is marked with the WS_EX_LAYOUTRTL style, Win32
                // mirrors the coordinates received for mouse movement as well as
                // mirroring the output of drawing to a GDI DC.
                //
                // Avalon also sets up mirroring transforms so that we properly
                // mirror the output since we render to DirectX, not a GDI DC.
                //
                // Unfortunately, this means that our input is already mirrored
                // by Win32, and Avalon mirrors it again.  To work around this
                // problem, we un-mirror the input from Win32 before passing
                // it into Avalon.
                //
                if((actions & (RawMouseActions.AbsoluteMove | RawMouseActions.Activate)) != 0)
                {
                    try
                    {
                        //This has a SUC on it and accesses CriticalHandle
                        int windowStyle = SafeNativeMethods.GetWindowStyle(new HandleRef(this, _source.Value.CriticalHandle), true);

                        if((windowStyle & NativeMethods.WS_EX_LAYOUTRTL) == NativeMethods.WS_EX_LAYOUTRTL)
                        {
                            NativeMethods.RECT rcClient = new NativeMethods.RECT();
                            SafeNativeMethods.GetClientRect(new HandleRef(this,_source.Value.Handle), ref rcClient);
                            x = rcClient.right - x;
                        }
                    }
                    catch(System.ComponentModel.Win32Exception)
                    {
                        System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: GetWindowStyle or GetClientRect failed!");
                    }
                }
            }


            // Get the extra information sent along with the message.
            //There exists a SUC for this native method call
            IntPtr extraInformation = IntPtr.Zero;
            try
            {
                extraInformation = UnsafeNativeMethods.GetMessageExtraInfo();
            }
            catch(System.ComponentModel.Win32Exception)
            {
                System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: GetMessageExtraInfo failed!");
            }


            RawMouseInputReport report = new RawMouseInputReport(mode,
                                                                 timestamp,
                                                                 source,
                                                                 actions,
                                                                 x,
                                                                 y,
                                                                 wheel,
                                                                 extraInformation);


            bool handled = _site.Value.ReportInput(report);

            return handled;
        }
        // IsValid Method for RawMouseActions. Relies on the enum being flags.
        internal static bool IsValidRawMouseActions(RawMouseActions actions)
        {
            if (actions == RawMouseActions.None)
                return true;

            if ((( RawMouseActions.AttributesChanged | RawMouseActions.Activate | RawMouseActions.Deactivate |
                  RawMouseActions.RelativeMove | RawMouseActions.AbsoluteMove | RawMouseActions.VirtualDesktopMove |
                  RawMouseActions.Button1Press | RawMouseActions.Button1Release |
                  RawMouseActions.Button2Press | RawMouseActions.Button2Release |
                  RawMouseActions.Button3Press | RawMouseActions.Button3Release |
                  RawMouseActions.Button4Press | RawMouseActions.Button4Release |
                  RawMouseActions.Button5Press | RawMouseActions.Button5Release |
                  RawMouseActions.VerticalWheelRotate | RawMouseActions.HorizontalWheelRotate |
                  RawMouseActions.CancelCapture |
                  RawMouseActions.QueryCursor) & actions) == actions)
            {
                if (!(((RawMouseActions.Deactivate & actions) == actions && RawMouseActions.Deactivate != actions ) ||
                      (((RawMouseActions.Button1Press | RawMouseActions.Button1Release) & actions) == (RawMouseActions.Button1Press | RawMouseActions.Button1Release)) ||
                      (((RawMouseActions.Button2Press | RawMouseActions.Button2Release) & actions) == (RawMouseActions.Button2Press | RawMouseActions.Button2Release)) ||
                      (((RawMouseActions.Button3Press | RawMouseActions.Button3Release) & actions) == (RawMouseActions.Button3Press | RawMouseActions.Button3Release)) ||
                      (((RawMouseActions.Button4Press | RawMouseActions.Button4Release) & actions) == (RawMouseActions.Button4Press | RawMouseActions.Button4Release)) ||
                      (((RawMouseActions.Button5Press | RawMouseActions.Button5Release) & actions) == (RawMouseActions.Button5Press | RawMouseActions.Button5Release))))
                {
                    return true;
                }
            }
            return false;
        }
Example #8
0
        private RawMouseActions GetNonRedundantActions(NotifyInputEventArgs e)
        {
            RawMouseActions actions = new RawMouseActions();

            // The CLR throws a null-ref exception if it tries to unbox a
            // null.  So we have to special case that.
            object o = e.StagingItem.GetData(_tagNonRedundantActions);
            if (o != null)
            {
                actions = (RawMouseActions) o;
            }

            return actions;
        }
Example #9
0
 // This is used to determine whether we postpone promoting mouse move events 
 // from stylus events.
 internal void SetLastRawMouseActions(RawMouseActions actions) 
 { 
     _lastRawMouseAction = actions;
 } 
Example #10
0
        internal bool UpdateMouseButtonState(RawMouseActions actions) 
        { 
            bool updated = false;
 
            switch (actions)
            {
                case RawMouseActions.Button1Press:
                    if (_mouseLeftButtonState != MouseButtonState.Pressed) 
                    {
                        updated = true; 
                        _mouseLeftButtonState = MouseButtonState.Pressed; 
                    }
                    break; 

                case RawMouseActions.Button1Release:
                    if (_mouseLeftButtonState != MouseButtonState.Released)
                    { 
                        updated = true;
                        _mouseLeftButtonState = MouseButtonState.Released; 
                    } 
                    break;
 
                case RawMouseActions.Button2Press:
                    if (_mouseRightButtonState != MouseButtonState.Pressed)
                    {
                        updated = true; 
                        _mouseRightButtonState = MouseButtonState.Pressed;
                    } 
                    break; 

                case RawMouseActions.Button2Release: 
                    if (_mouseRightButtonState != MouseButtonState.Released)
                    {
                        updated = true;
                        _mouseRightButtonState = MouseButtonState.Released; 
                    }
                    break; 
            } 

            return updated; 
        }
Example #11
0
        protected override IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            switch ((WindowMessage)msg)
            {
            case WindowMessage.LeftButtonDown:
                Interop.SetFocus(hWnd);
                RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left)
                {
                    RoutedEvent = Mouse.MouseDownEvent,
                    Source      = this,
                });
                break;

            case WindowMessage.LeftButtonUp:
                RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left)
                {
                    RoutedEvent = Mouse.MouseUpEvent,
                    Source      = this,
                });
                break;

            case WindowMessage.RightButtonDown:
                RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Right)
                {
                    RoutedEvent = Mouse.MouseDownEvent,
                    Source      = this,
                });
                break;

            case WindowMessage.RightButtonUp:
                RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Right)
                {
                    RoutedEvent = Mouse.MouseUpEvent,
                    Source      = this,
                });
                break;

            case WindowMessage.MouseMove: {
                int   x = LOWORD(lParam.ToInt32());
                int   y = HIWORD(lParam.ToInt32());
                Point p = this.TransformToAncestor(Application.Current.MainWindow).Transform(new Point(0, 0));

                RawMouseActions actions = RawMouseActions.Activate | RawMouseActions.AbsoluteMove;
                RaisePreviewMouseMoveEvent(
                    InputMode.Foreground,
                    actions,
                    PresentationSource.FromVisual(this),
                    Mouse.MouseMoveEvent,
                    Environment.TickCount, (int)(x + p.X), (int)(y + p.Y), 0);

                RaiseEvent(new MouseEventArgs(Mouse.PrimaryDevice, 0)
                    {
                        RoutedEvent = Mouse.MouseMoveEvent,
                        Source      = this
                    });
            }
            break;

            case WindowMessage.MouseWheel:
                short delta;
                switch (IntPtr.Size)
                {
                case 8:
                    delta = (short)(wParam.ToInt64() >> 16);
                    break;

                case 4:
                    delta = (short)(wParam.ToInt32() >> 16);
                    break;

                default:
                    delta = 0;
                    break;
                }
                RaiseEvent(new MouseWheelEventArgs(Mouse.PrimaryDevice, 0, delta)
                {
                    RoutedEvent = Mouse.MouseWheelEvent,
                    Source      = this
                });
                break;

            case WindowMessage.LeftButtonDoubleClick: {
                RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left)
                    {
                        RoutedEvent = Control.MouseDoubleClickEvent,
                        Source      = doubleClickControl,
                    });
            }

            break;

            case WindowMessage.RightButtonDoubleClick:
                RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Right)
                {
                    RoutedEvent = Control.MouseDoubleClickEvent,
                    Source      = this,
                });
                break;

            case WindowMessage.MiddleButtonDoubleClick:
                RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Middle)
                {
                    RoutedEvent = Control.MouseDoubleClickEvent,
                    Source      = this,
                });
                break;

            default:
                return(base.WndProc(hWnd, msg, wParam, lParam, ref handled));
            }

            //handled = true;
            return(IntPtr.Zero);
        }