Example #1
0
        /// <summary>
        /// Determines if this mouse event is a promoted event based on the extra information
        /// given from the WM_MOUSE message.  Windows guarantees that any promotions have this
        /// extra information and legacy engines (such as WISP in Windows 7) set the precedent
        /// for this, so it has been and can be relied on.
        /// </summary>
        /// <param name="mouseInputReport">The raw mouse input to check</param>
        /// <returns>True if this is a promoted mouse event, false otherwise.</returns>
        internal static bool IsPromotedMouseEvent(RawMouseInputReport mouseInputReport)
        {
            int mouseExtraInfo = NativeMethods.IntPtrToInt32(mouseInputReport.ExtraInformation);

            return((mouseExtraInfo & PromotedMouseEventMask) == PromotedMouseEventTag); // MI_WP_SIGNATURE
        }
Example #2
0
        /// <summary>
        /// Retrieves the cursor id from a promoted mouse message
        /// </summary>
        /// <param name="mouseInputReport">THe input report</param>
        /// <returns>THe cursor id if promoted, 0 if pure mouse (by definition)</returns>
        internal static uint GetCursorIdFromMouseEvent(RawMouseInputReport mouseInputReport)
        {
            int mouseExtraInfo = NativeMethods.IntPtrToInt32(mouseInputReport.ExtraInformation);

            return((uint)(mouseExtraInfo & PromotedMouseEventCursorIdMask));
        }
Example #3
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;
        }
        internal void PlayBackCachedDownInputReport(int timestamp)
        {
            if (_needToSendMouseDown)
            {
                // if we have marked this as handled we need to play the down otherwise we can ignore the down
                // as it will be process anyway and either way we need to clean up the cached down
                PresentationSource mouseInputSource = GetMousePresentationSource();

                if (mouseInputSource != null)
                {
                    Point pt = PointUtil.ScreenToClient(_lastMouseScreenLocation, mouseInputSource);

                    _needToSendMouseDown = false; // We've sent down, don't send again.

                    // Update the state we report to the mouse (GetButtonState).
                    _promotedMouseState = MouseButtonState.Pressed;

                    RawMouseActions actions = _fLeftButtonDownTrigger?RawMouseActions.Button1Press:RawMouseActions.Button2Press;

                    // StylusLogic manages the mouse state reported to the MouseDevice to deal with multiple stylusdevice input.
                    if (_stylusLogic.UpdateMouseButtonState(actions))
                    {
                        // See if we need to set the Mouse Activate flag.
                        InputManager inputManager = (InputManager)Dispatcher.InputManager;

                        if (inputManager != null)
                        {
                            if (inputManager.PrimaryMouseDevice.CriticalActiveSource != mouseInputSource)
                            {
                                actions |= RawMouseActions.Activate;
                            }               
                        }

                        // Update the last event we've sent through.
                        _stylusLogic.SetLastRawMouseActions(actions);
                        
                        RawMouseInputReport mouseInputReport = new RawMouseInputReport(
                                                     InputMode.Foreground, timestamp, mouseInputSource,
                                                     actions, 
                                                     (int)pt.X, (int)pt.Y, 0, IntPtr.Zero);

                        InputReportEventArgs inputReportArgs = new InputReportEventArgs(this, mouseInputReport);
                        inputReportArgs.RoutedEvent=InputManager.PreviewInputReportEvent;
                        _stylusLogic.InputManagerProcessInputEventArgs(inputReportArgs);
                    }
                }
                    
                _needToSendMouseDown = false; // so we don't try and resend it later.
                
            }
        }
Example #5
0
        private void PreProcessInput(object sender, PreProcessInputEventArgs e)
        {
            if (e.StagingItem.Input.RoutedEvent == InputManager.PreviewInputReportEvent)
            {
                InputReportEventArgs inputReportEventArgs = e.StagingItem.Input as InputReportEventArgs;

                if (!inputReportEventArgs.Handled && inputReportEventArgs.Report.Type == InputType.Mouse)
                {
                    RawMouseInputReport rawMouseInputReport = (RawMouseInputReport)inputReportEventArgs.Report;


                    // Normally we only process mouse input that is from our
                    // active visual manager.  The only exception to this is
                    // the activate report, which is how we change the visual
                    // manager that is active.
                    if ((rawMouseInputReport.Actions & RawMouseActions.Activate) == RawMouseActions.Activate)
                    {
                        // Console.WriteLine("RawMouseActions.Activate");

                        // If other actions are being reported besides the
                        // activate, separate them into different events.
                        if ((rawMouseInputReport.Actions & ~RawMouseActions.Activate) != 0)
                        {
                            // Cancel this event.  We'll push a new event for the activate.
                            e.Cancel();

                            // Push a new RawMouseInputReport for the non-activate actions.
                            RawMouseInputReport reportActions = new RawMouseInputReport(rawMouseInputReport.Mode,
                                                                                        rawMouseInputReport.Timestamp,
                                                                                        rawMouseInputReport.InputSource,
                                                                                        rawMouseInputReport.Actions & ~RawMouseActions.Activate,
                                                                                        rawMouseInputReport.X,
                                                                                        rawMouseInputReport.Y,
                                                                                        rawMouseInputReport.Wheel,
                                                                                        rawMouseInputReport.ExtraInformation);
                            InputReportEventArgs actionsArgs = new InputReportEventArgs(inputReportEventArgs.Device, reportActions);
                            actionsArgs.RoutedEvent=InputManager.PreviewInputReportEvent;
                            e.PushInput(actionsArgs, null);

                            // Create a new RawMouseInputReport for the activate.
                            RawMouseInputReport reportActivate = new RawMouseInputReport(rawMouseInputReport.Mode,
                                                                                         rawMouseInputReport.Timestamp,
                                                                                         rawMouseInputReport.InputSource,
                                                                                         RawMouseActions.Activate,
                                                                                         rawMouseInputReport.X,
                                                                                         rawMouseInputReport.Y,
                                                                                         rawMouseInputReport.Wheel,
                                                                                         rawMouseInputReport.ExtraInformation);

                            // Push a new RawMouseInputReport for the activate.
                            InputReportEventArgs activateArgs = new InputReportEventArgs(inputReportEventArgs.Device, reportActivate);
                            activateArgs.RoutedEvent=InputManager.PreviewInputReportEvent;
                            e.PushInput(activateArgs, null);
                        }
                    }
                    // Only process mouse input that is from our active PresentationSource.
                    else if ((_inputSource != null) && (rawMouseInputReport.InputSource == _inputSource.Value))
                    {
                        // We need to remember the StylusDevice that generated this input.  Use the _tagStylusDevice
                        // to store this in before we take over the inputReport Device and loose it.  Any
                        // input reports we re-push need to preserve this too.  This is used to set the StylusDevice
                        // property on MouseEventArgs.
                        InputDevice inputDevice = e.StagingItem.GetData(_tagStylusDevice) as StylusDevice;

                        if (inputDevice == null)
                        {
                            inputDevice = inputReportEventArgs.Device as StylusDevice;
                            if (inputDevice != null)
                            {
                                e.StagingItem.SetData(_tagStylusDevice, inputDevice);
                            }
                        }

                        // Claim the input for the mouse.
                        inputReportEventArgs.Device = this;

                        // If the input is reporting mouse deactivation, we need
                        // to ensure that the element receives a final leave.
                        // Note that activation could have been moved to another
                        // visual manager in our app, which means that the leave
                        // was already sent.  So only do this if the deactivate
                        // event is from the visual manager that we think is active.
                        if ((rawMouseInputReport.Actions & RawMouseActions.Deactivate) == RawMouseActions.Deactivate)
                        {
                            if (_mouseOver != null)
                            {
                                // Push back this event, and cancel the current processing.
                                e.PushInput(e.StagingItem);
                                e.Cancel();
                                _isPhysicallyOver = false;
                                ChangeMouseOver(null, e.StagingItem.Input.Timestamp);
                            }
                        }

                        // If the input is reporting mouse movement, we need to check
                        // if we need to update our sense of "mouse over".
                        // 
                        if ((rawMouseInputReport.Actions & RawMouseActions.AbsoluteMove) == RawMouseActions.AbsoluteMove)
                        {
                            // If other actions are being reported besides the
                            // move, separate them into different events.
                            if ((rawMouseInputReport.Actions & ~(RawMouseActions.AbsoluteMove | RawMouseActions.QueryCursor)) != 0)
                            {
                                // Cancel this event.  We'll push a new event for the move.
                                e.Cancel();

                                // Push a new RawMouseInputReport for the non-move actions.
                                RawMouseInputReport reportActions = new RawMouseInputReport(rawMouseInputReport.Mode,
                                                                                            rawMouseInputReport.Timestamp,
                                                                                            rawMouseInputReport.InputSource,
                                                                                            rawMouseInputReport.Actions & ~(RawMouseActions.AbsoluteMove | RawMouseActions.QueryCursor),
                                                                                            0,
                                                                                            0,
                                                                                            rawMouseInputReport.Wheel,
                                                                                            rawMouseInputReport.ExtraInformation);
                                InputReportEventArgs actionsArgs = new InputReportEventArgs(inputDevice, reportActions);
                                actionsArgs.RoutedEvent=InputManager.PreviewInputReportEvent;
                                e.PushInput(actionsArgs, null);

                                // Push a new RawMouseInputReport for the AbsoluteMove.
                                RawMouseInputReport reportMove = new RawMouseInputReport(rawMouseInputReport.Mode,
                                                                                         rawMouseInputReport.Timestamp,
                                                                                         rawMouseInputReport.InputSource,
                                                                                         rawMouseInputReport.Actions & (RawMouseActions.AbsoluteMove | RawMouseActions.QueryCursor),
                                                                                         rawMouseInputReport.X,
                                                                                         rawMouseInputReport.Y,
                                                                                         0,
                                                                                         IntPtr.Zero);
                                InputReportEventArgs moveArgs = new InputReportEventArgs(inputDevice, reportMove);
                                moveArgs.RoutedEvent=InputManager.PreviewInputReportEvent;
                                e.PushInput(moveArgs, null);
                            }
                            else
                            {
                                // Convert the point from client coordinates into "root" coordinates.
                                // We do this in the pre-process stage because it is possible that
                                // this conversion will fail, in which case we want to cancel the
                                // mouse move event.
                                bool success = true;
                                Point ptClient = new Point(rawMouseInputReport.X, rawMouseInputReport.Y);
                                Point ptRoot = PointUtil.TryClientToRoot(ptClient, rawMouseInputReport.InputSource, false, out success);
                                if(success)
                                {
                                    e.StagingItem.SetData(_tagRootPoint, ptRoot);
                                }
                                else
                                {
                                    e.Cancel();
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                // All mouse event processing should only happen if we still have an active input source.

                if (_inputSource != null)
                {
                    if (e.StagingItem.Input.RoutedEvent == Mouse.PreviewMouseDownEvent)
                    {
                        MouseButtonEventArgs mouseButtonEventArgs = e.StagingItem.Input as MouseButtonEventArgs;

                        if (_mouseCapture != null && !_isPhysicallyOver)
                        {
                            // The mouse is not physically over the capture point (or
                            // subtree), so raise the PreviewMouseDownOutsideCapturedElement
                            // event first.
                            MouseButtonEventArgs clickThrough = new MouseButtonEventArgs(this, mouseButtonEventArgs.Timestamp, mouseButtonEventArgs.ChangedButton, GetStylusDevice(e.StagingItem));
                            clickThrough.RoutedEvent=Mouse.PreviewMouseDownOutsideCapturedElementEvent;
                            //ProcessInput has a linkdemand
                            _inputManager.Value.ProcessInput(clickThrough);
                        }
                    }

                    else if (e.StagingItem.Input.RoutedEvent == Mouse.PreviewMouseUpEvent)
                    {
                        MouseButtonEventArgs mouseButtonEventArgs = e.StagingItem.Input as MouseButtonEventArgs;

                        if (_mouseCapture != null && !_isPhysicallyOver)
                        {
                            // The mouse is not physically over the capture point (or
                            // subtree), so raise the PreviewMouseUpOutsideCapturedElement
                            // event first.
                            MouseButtonEventArgs clickThrough = new MouseButtonEventArgs(this, mouseButtonEventArgs.Timestamp, mouseButtonEventArgs.ChangedButton, GetStylusDevice(e.StagingItem));
                            clickThrough.RoutedEvent=Mouse.PreviewMouseUpOutsideCapturedElementEvent;
                            //ProcessInput has a linkdemand
                            _inputManager.Value.ProcessInput(clickThrough);
                        }
                    }
                }
            }

        }
Example #6
0
        public void Synchronize()
        {
            // System.Console.WriteLine("Synchronize");
//             VerifyAccess();

            // Simulate a mouse move
            PresentationSource activeSource = CriticalActiveSource;
            if (activeSource != null && activeSource.CompositionTarget != null && !activeSource.CompositionTarget.IsDisposed)
            {
                int timeStamp = Environment.TickCount;
                Point ptClient = GetClientPosition();

                RawMouseInputReport report = new RawMouseInputReport(InputMode.Foreground,
                                                                     timeStamp,
                                                                     activeSource,
                                                                     RawMouseActions.AbsoluteMove,
                                                                     (int) ptClient.X,
                                                                     (int) ptClient.Y,
                                                                     0,
                                                                     IntPtr.Zero);
                report._isSynchronize = true;

                InputReportEventArgs inputReportEventArgs;
                if (_stylusDevice != null)
                {
                    // if we have a current stylusdevice .. use it
                    inputReportEventArgs = new InputReportEventArgs(_stylusDevice, report);
                }
                else
                {
                    inputReportEventArgs = new InputReportEventArgs(this, report);
                }

                inputReportEventArgs.RoutedEvent=InputManager.PreviewInputReportEvent;

                //ProcessInput has a linkdemand
                _inputManager.Value.ProcessInput(inputReportEventArgs);
            }
        }
Example #7
0
        private void PreProcessInput(object sender, PreProcessInputEventArgs e)
        { 
            if (_inputEnabled) 
            {
                if(e.StagingItem.Input.RoutedEvent == InputManager.PreviewInputReportEvent) 
                {
                    InputReportEventArgs input = e.StagingItem.Input as InputReportEventArgs;

                    if(input != null && !input.Handled) 
                    {
                        // See if we are in a DragDrop operation.  If so set our internal flag 
                        // which stops us from promoting Stylus or Mouse events! 
                        if (_inDragDrop != _inputManager.Value.InDragDrop)
                        { 
                            _inDragDrop = _inputManager.Value.InDragDrop;

                            // If we are going out of DragDrop then we need to re [....] the mouse state
                            // if we have a stylus device in range (otherwise we [....] on the next 
                            // stylus coming in range).
                            if (!_inDragDrop && _stylusDeviceInRange) 
                            { 
                                UpdateMouseState();
                            } 
                        }

                        if (input.Report.Type == InputType.Mouse)
                        { 
                            // If we see a non stylus mouse event (not triggered from stylus event)
                            if ((input.Device as StylusDevice) == null) 
                            { 
                                // And we only do work if we are enabled for stylus input (ie - have tablet devices)
                                if (TabletDevices.Count != 0) 
                                {
                                    RawMouseInputReport mouseInputReport = (RawMouseInputReport) input.Report;
                                    RawMouseActions actions = mouseInputReport.Actions;
                                    int mouseExtraInfo = NativeMethods.IntPtrToInt32(mouseInputReport.ExtraInformation); 
                                    bool fromWisptis = (mouseExtraInfo & 0xFFFFFF00) == 0xFF515700; // MI_WP_SIGNATURE
 
                                    // Grab the stylus info if from wisptis 
                                    if (fromWisptis)
                                    { 
                                        _lastMouseMoveFromStylus = true;

                                        // Grab the current stylus Id out of the extra info.
                                        _lastStylusDeviceId = (mouseExtraInfo & 0x000000FF); 
                                    }
 
                                    // If mouse is getting deactivated and StylusOver is non null then force stylusover to null. 
                                    if ((actions & RawMouseActions.Deactivate) == RawMouseActions.Deactivate)
                                    { 
                                        _seenRealMouseActivate = false;

                                        if (CurrentStylusDevice != null)
                                        { 
                                            PenContexts penContexts = GetPenContextsFromHwnd(mouseInputReport.InputSource);
 
                                            // If we are inRange still then defer the Deactivate call till we are OutOfRange. 
                                            if (_stylusDeviceInRange && !_inDragDrop && (penContexts == null || !penContexts.IsWindowDisabled))
                                            { 
                                                _mouseDeactivateInputReport = mouseInputReport;
                                                e.Cancel();
                                                input.Handled = true;
                                                return; 
                                            }
#if !MULTICAPTURE 
                                            else if (CurrentStylusDevice.DirectlyOver != null) 
#else
                                            else 
#endif
                                            {
                                                MouseDevice mouseDevice = _inputManager.Value.PrimaryMouseDevice;
 
                                                if (mouseDevice.CriticalActiveSource == mouseInputReport.InputSource)
                                                { 
#if !MULTICAPTURE 
                                                    // Update over to be null when deactivating.
                                                    CurrentStylusDevice.ChangeStylusOver(null); 
#else
                                                    lock (__stylusDeviceLock)
                                                    {
                                                        foreach (var pair in __stylusDeviceMap) 
                                                        {
                                                            var currentDevice = pair.Value; 
                                                            if (currentDevice.DirectlyOver != null) 
                                                            {
                                                                // Update over to be null when deactivating. 
                                                                currentDevice.ChangeStylusOver(null);
                                                            }
                                                        }
                                                    } 
#endif
                                                } 
                                            } 
                                        }
                                    } 
                                    // See if we got some mouse input we need to check for consistency (not tagged from wisptis)
                                    else if ((actions & RawMouseActions.CancelCapture) != 0)
                                    {
                                        // We need to resend this back through as coming from a stylusdevice if in range 
                                        if (CurrentStylusDevice != null && CurrentStylusDevice.InRange)
                                        { 
                                            RawMouseInputReport cancelCaptureInputReport = 
                                                        new RawMouseInputReport(mouseInputReport.Mode,
                                                                                mouseInputReport.Timestamp, 
                                                                                mouseInputReport.InputSource,
                                                                                mouseInputReport.Actions,
                                                                                0, // Rest of the parameters are not used...
                                                                                0, 
                                                                                0,
                                                                                IntPtr.Zero); 
 
                                            InputReportEventArgs args = new InputReportEventArgs(CurrentStylusDevice, cancelCaptureInputReport);
                                            args.RoutedEvent = InputManager.PreviewInputReportEvent; 
                                            e.Cancel();
                                            _inputManager.Value.ProcessInput(args);
                                        }
                                    } 
                                    // Handle the Mouse activation
                                    else if ((actions & RawMouseActions.Activate) != 0) 
                                    { 
                                        // If mouse is getting Activated and we ate a Deactivate then clear the cached Deactivate.
                                        _mouseDeactivateInputReport = null; 

                                        // We process Activate events and make sure to clear any other actions if we are resending
                                        // this from a StylusDevice.  This is so we don't get a move generated before we see the
                                        // StylusDevice InRange event and the following StylusMove which will generate a MouseMove. 
                                        StylusDevice activateStylusDevice = null;
                                        _seenRealMouseActivate = true; 
 
                                        // See if we need to process this event from us.
                                        if (CurrentStylusDevice != null && CurrentStylusDevice.InRange) 
                                            activateStylusDevice = CurrentStylusDevice;
                                        else if (fromWisptis || ShouldConsiderStylusInRange(mouseInputReport))
                                            activateStylusDevice = FindStylusDevice(_lastStylusDeviceId);
 
                                        // We need to resend this as coming from a stylusdevice if in range possibly.
                                        if (activateStylusDevice != null) 
                                        { 
                                            // Check to se if we have already Activated the mouse from a stylus event.
                                            // If not then we need to let this one go through marked from us if we are in range! 
                                            if (mouseInputReport.InputSource != _inputManager.Value.PrimaryMouseDevice.CriticalActiveSource)
                                            {
                                                Point pt;
 
                                                pt = activateStylusDevice.LastMouseScreenPoint; // Use last promoted mouse location.
                                                pt = PointUtil.ScreenToClient(pt, mouseInputReport.InputSource); 
 
                                                RawMouseInputReport activateInputReport =
                                                            new RawMouseInputReport(mouseInputReport.Mode, 
                                                                                    mouseInputReport.Timestamp,
                                                                                    mouseInputReport.InputSource,
                                                                                    RawMouseActions.Activate, // Only let activate happen.
                                                                                    (int)pt.X, 
                                                                                    (int)pt.Y,
                                                                                    mouseInputReport.Wheel, 
                                                                                    mouseInputReport.ExtraInformation); 

                                                InputReportEventArgs args = new InputReportEventArgs(activateStylusDevice, activateInputReport); 
                                                args.RoutedEvent = InputManager.PreviewInputReportEvent;
                                                _inputManager.Value.ProcessInput(args);
                                            }
 
                                            // If stylus is active then eat this since we'll send the activate.  We just cancel
                                            // to ensure the mouse event from HwndMouseInputProvider returns that it was not handled. 
                                            // The mouse device code will not do anything with the event during PreProcessInput and 
                                            // it will not see a PreNotifyInput event for this.
                                            e.Cancel(); 
                                        }
                                    }
                                    // Handle moves and button presses that might be from wisptis or in conflict with our current state
                                    else if ((actions & (RawMouseActions.AbsoluteMove | RawMouseActions.QueryCursor | 
                                                            RawMouseActions.Button1Press | RawMouseActions.Button1Release |
                                                            RawMouseActions.Button2Press | RawMouseActions.Button2Release)) != 0) 
                                    { 
                                        // If we see a mouse left down and stylus is inRange and we haven't sent a mouse down
                                        // then send it through. 
                                        if ((actions & RawMouseActions.Button1Press) != 0 && CurrentStylusDevice != null &&
                                            !CurrentStylusDevice.InAir)
                                        {
                                            // We can only Activate the window without flashing the tray icon for it when 
                                            // we are processing an Input message.  So we defer it till we see the mouse down.
                                            HwndSource hwndSource = mouseInputReport.InputSource as HwndSource; 
                                            IntPtr hwnd = hwndSource != null ? hwndSource.CriticalHandle : IntPtr.Zero; 

                                            // If we see a stylusdown and we are not the foreground window 
                                            // and there's no capture then make sure we get activated.
                                            // We only do this for top most windows.
                                            if (hwnd != IntPtr.Zero &&
                                                 _inputManager.Value.PrimaryMouseDevice.Captured != null && 
                                                 UnsafeNativeMethods.GetParent(new HandleRef(this, hwnd)) == IntPtr.Zero &&
                                                 hwnd != UnsafeNativeMethods.GetForegroundWindow()) 
                                            { 
                                                // Check to see if this window has the WS_EX_NOACTIVATE style set, if so don't do the activation work.
                                                int style = UnsafeNativeMethods.GetWindowLong(new HandleRef(this,hwnd), NativeMethods.GWL_EXSTYLE); 

                                                if ((style & NativeMethods.WS_EX_NOACTIVATE) == 0)
                                                {
                                                    UnsafeNativeMethods.SetForegroundWindow(new HandleRef(this,hwndSource.Handle)); 
                                                }
                                            } 
 
                                            // There are times we need to make sure we promote the left mouse down before we see a system gesture.
                                            // This is when the press and hold gesture is disabled and thus we can guarentee that sending the 
                                            // left mouse down is the correct thing to do.  This is critical for some controls such as repeat
                                            // buttons since in order get them in the pressed state (and start them repeating) we have to send the
                                            // left mouse down.  Note if you go down with the stylus and don't move it past the drag tolerance no
                                            // system gesture will be generated and the normal code to promote the mouse down will not happen otherwise. 
                                            //
                                            // This code will kick in on Vista with the new support to disable the press and hold gesture per element 
                                            // (via WM_TABLE_QUERYSYSTEMGESTURESTATUS message) and also on XP and Vista if the press and hold gesture is 
                                            // disabled in the tablet control panel.
                                            if (!CurrentStylusDevice.SentMouseDown && fromWisptis && ShouldPromoteToMouse(CurrentStylusDevice)) 
                                            {
                                                // left button down...lets replay the down at this time...
                                                // Note: We may wait till later if stylus is not down yet!
                                                // We will do it only when we are not manipulating and we will 
                                                // delay it if we know that manipulations are possible.
                                                StylusTouchDevice touchDevice = CurrentStylusDevice.TouchDevice; 
                                                if (touchDevice.PromotingToManipulation) 
                                                {
                                                    touchDevice.StoredStagingAreaItems.Add(e.StagingItem); 
                                                }
                                                else if (touchDevice.PromotingToOther)
                                                {
                                                    CurrentStylusDevice.PlayBackCachedDownInputReport(mouseInputReport.Timestamp); 
                                                }
                                            } 
                                        } 

                                        // We want to eat mouse messages with the wisptis injected signature except 
                                        // if the MouseDevice is getting activated or deactivated by it (filtered out
                                        // above).  We also want to eat any spurious mouse events recieved between the
                                        // stylus down and the stylus system gesture getting fired.
                                        if (fromWisptis) 
                                        {
                                            // eat mouse messages generated by stylus; 
                                            // these will be handled off the stylus event stream and promoted to a mouse input event 
                                            bool handled = true;
 
                                            // If the mouse is captured we need to validate that the mouse location
                                            // is actually inside the client area (we will only see those wisptis
                                            // events and can thus eat this one).
                                            Point ptMouse = new Point(mouseInputReport.X, mouseInputReport.Y); 
                                            bool stylusIsDown = (CurrentStylusDevice != null) ? !CurrentStylusDevice.InAir : false;
                                            if (!stylusIsDown && Mouse.Captured != null && !InWindowClientRect(ptMouse, mouseInputReport.InputSource)) 
                                            { 
                                                handled = false;
                                            } 

                                            // If the input has been marked as Handled, we want it to be cancelled at PreProcess stage.
                                            if (handled)
                                            { 
                                                // We can't mark left and right mouse buttons as handled since it will stop the
                                                // DefWindowProc from being processed but we Cancel it which stops mouse from processing 
                                                // it.  Move's though we need to eat. 
                                                if ((actions & (RawMouseActions.Button1Press | RawMouseActions.Button2Press)) == 0)
                                                { 
                                                    input.Handled = true;
                                                }
                                                e.Cancel();
 
                                                // If the stylus is in the up state when we see a mouse down then just note that we've
                                                // seen the mouse left down and wanted to send it but the stylus down 
                                                // has not been seen yet so we can't.  When we see the stylus down later we'll promote 
                                                // the left mouse down after processing the stylus down.
                                                if ((actions & RawMouseActions.Button1Press) != 0 && CurrentStylusDevice != null && 
                                                    CurrentStylusDevice.InAir)
                                                {
                                                    CurrentStylusDevice.SetSawMouseButton1Down(true);
                                                } 

                                                // Only try to process stylus events on wisptis generated mouse events and 
                                                // make sure we don't re-enter ourselves. 
                                                if (!_processingQueuedEvent)
                                                { 
                                                    // Make sure we process any pending Stylus Input before this mouse event.
                                                    InputManagerProcessInput(null);
                                                }
                                            } 
                                        }
                                        else 
                                        { 
                                            bool cancelMouseEvent = false;
                                            bool markHandled = true; 

                                            // If Stylus is in range then it will be driving the mouse.  Ignore any mouse input.
                                            if (_stylusDeviceInRange)
                                            { 
                                                cancelMouseEvent = true;
 
                                                // We can't mark left and right mouse buttons as handled since it will stop the 
                                                // DefWindowProc from being processed but we Cancel it which stops mouse from processing
                                                // it.  Move's though we need to eat. 
                                                if ((actions & (RawMouseActions.Button1Press | RawMouseActions.Button2Press)) == 0)
                                                {
                                                    markHandled = false;
                                                } 
                                            }
                                            // If we see only a mouse move related action while the stylus is in range then 
                                            // eat it or try to defer it if not currently in range to see if we come into range. 
                                            else if ((actions & ~(RawMouseActions.AbsoluteMove | RawMouseActions.QueryCursor)) == 0)
                                            { 
                                                if (DeferMouseMove(mouseInputReport))
                                                {
                                                    cancelMouseEvent = true;
                                                } 
                                                else
                                                { 
                                                    // If we now think we're going in range then eat this mouse event 
                                                    if (_lastMouseMoveFromStylus && ShouldConsiderStylusInRange(mouseInputReport))
                                                    { 
                                                        SendDeferredMouseEvent(false); // Make sure we clear any deferred mouse events now.
                                                        cancelMouseEvent = true;
                                                    }
                                                    // We're now allowing this mouse event (and deferred one) to be processed... 
                                                    else
                                                    { 
                                                        // It's a Synchronize that we are letting through so set stylus was not last move anymore. 
                                                        _lastMouseMoveFromStylus = false;
 
                                                        // See if we are dealing with a second mouse event,
                                                        // if so force the original one it to be processed first.
                                                        if (!_triedDeferringMouseMove)
                                                            SendDeferredMouseEvent(true); 

                                                        // CurrentStylusDevice is not in range and we're seeeing mouse messages 
                                                        // that are not from wisptis, time to set IsStylusOver to null 
                                                        if (CurrentStylusDevice != null)
                                                        { 
                                                            // No current stylus device anymore either.
                                                            SelectStylusDevice(null, null, true);
                                                        }
                                                    } 
                                                }
                                            } 
                                            // If we see a down and have a cached move then let them both go through 
                                            else
                                            { 
                                                // We see a mouse button 1 or 2 down/up.  If we have a cache then dump it and mark that we've
                                                // seen mouse input.
                                                _lastMouseMoveFromStylus = false;
                                                SendDeferredMouseEvent(true); 

                                                // CurrentStylusDevice is not in range and we're seeeing mouse messages 
                                                // that are not from wisptis, time to set IsStylusOver to null 
                                                if (CurrentStylusDevice != null)
                                                { 
                                                    // No current stylus device anymore either.
                                                    SelectStylusDevice(null, null, true);
                                                }
                                            } 

                                            // See if we wanted to eat this mouse event... 
                                            if (cancelMouseEvent) 
                                            {
                                                e.Cancel(); // abort this input 
                                                if (markHandled)
                                                {
                                                    input.Handled = true; // We also don't want MouseDevice processing this.
                                                } 
                                            }
                                        } 
                                    } 
                                    // Some other real mouse only generated event came through...
                                    else 
                                    {
                                        // Make sure it's only the ones we know should come through.
                                        Debug.Assert((actions & ~(RawMouseActions.Button3Press | RawMouseActions.Button3Release |
                                                                   RawMouseActions.Button4Press | RawMouseActions.Button4Release | 
                                                                   RawMouseActions.Button5Press | RawMouseActions.Button5Release |
                                                                   RawMouseActions.VerticalWheelRotate | 
                                                                   RawMouseActions.HorizontalWheelRotate)) == 0); 

                                        // If we are not in range then make sure we update our state. 
                                        // Otherwise we just let this event go through to the MouseDevice.
                                        if (!_stylusDeviceInRange)
                                        {
                                            // We are letting this move through so set stylus was not last move anymore. 
                                            _lastMouseMoveFromStylus = false;
 
                                            // Dump cache! 
                                            SendDeferredMouseEvent(true);
 
                                            // CurrentStylusDevice is not in range and we're seeeing mouse messages
                                            // that are not from wisptis, time to set IsStylusOver to null
                                            if (CurrentStylusDevice != null)
                                            { 
                                                // We now don't have a current stylus device.
                                                SelectStylusDevice(null, null, true); 
                                            } 
                                        }
                                        else 
                                        {
                                            // Make sure to dump the cached mouse event if we are in
                                            // range to make sure this mouse event is at the right spot!
                                            SendDeferredMouseEvent(true); 
                                        }
                                    } 
                                } 
                                else
                                { 
                                    _lastMouseMoveFromStylus = false;
                                }
                            }
                            else 
                            {
                                // This event is marked as coming from a StylusDevice so make sure we update flag that we saw mouse event from stylus. 
                                _lastMouseMoveFromStylus = true; 

                                RawMouseInputReport rawMouseInputReport = (RawMouseInputReport) input.Report; 
                                StylusDevice stylusDevice = (StylusDevice)input.Device;
                                if (!stylusDevice.InRange && rawMouseInputReport._isSynchronize)
                                {
                                    // eat this one because it is from an activate. 
                                    e.Cancel();
                                    input.Handled = true; 
                                } 
                            }
                        } 
                        else if (input.Report.Type == InputType.Stylus)
                        {
                            RawStylusInputReport stylusInputReport = (RawStylusInputReport) input.Report;
                            StylusDevice stylusDevice = stylusInputReport.StylusDevice; // RTI sets this if it finds StylusDevice based on Id. 
                            bool cancelInput = true; // Only process if we see we have valid input data.
 
                            if (stylusInputReport.InputSource != null && stylusInputReport.PenContext != null) 
                            {
                                if (stylusDevice == null) 
                                {
                                    // look up stylus device, select it in the Stylus, and claim input for it
                                    stylusDevice = FindStylusDevice(stylusInputReport.StylusDeviceId);
 
                                    // Try refreshing tablets if we failed to find this stylus device.
                                    if (stylusDevice == null) 
                                    { 
                                        stylusDevice = TabletDevices.UpdateStylusDevices(
                                                                    stylusInputReport.TabletDeviceId, 
                                                                    stylusInputReport.StylusDeviceId);
                                    }

                                    stylusInputReport.StylusDevice = stylusDevice; // update stylusdevice. 
                                }
 
                                _triedDeferringMouseMove = false; // reset anytime we see stylus input. 

                                // See if this is the special InRange input report that we use to track queued inrange 
                                // events so that we can better filter out bogus mouse input.
                                if (stylusInputReport.Actions == RawStylusActions.InRange && stylusInputReport.Data == null)
                                {
                                    stylusInputReport.PenContext.DecrementQueuedInRangeCount(); 
                                    e.Cancel();
                                    input.Handled = true; 
                                    _lastInRangeTime = Environment.TickCount; 
                                    return;
                                } 

                                // See if this is the special DoubleTap Gesture input report.  We use this
                                // event to know when we won't get the tap or drag gesture while the stylus
                                // is down.  This allows us to detect and generate the Drag gesture on our own. 
                                if (stylusInputReport.Actions == RawStylusActions.SystemGesture && stylusDevice != null)
                                { 
                                    RawStylusSystemGestureInputReport systemGestureReport = (RawStylusSystemGestureInputReport)stylusInputReport; 
                                    if (systemGestureReport.SystemGesture == RawStylusSystemGestureInputReport.InternalSystemGestureDoubleTap)
                                    { 
                                        stylusDevice.SeenDoubleTapGesture = true;
                                        e.Cancel();
                                        input.Handled = true;
                                        return; 
                                    }
                                } 
 
                                if (stylusDevice != null && IsValidStylusAction(stylusInputReport))
                                { 
                                    cancelInput = false; // We can process this event - don't cancel!

                                    // See if a static gesture can be generated
                                    TabletDevice tabletDevice = stylusDevice.TabletDevice; 
                                    if (tabletDevice != null)
                                    { 
                                        SystemGesture? systemGesture = tabletDevice.GenerateStaticGesture(stylusInputReport); 
                                        if (systemGesture != null)
                                        { 
                                            GenerateGesture(stylusInputReport, systemGesture.Value);
                                        }
                                    }
 
                                    // See if we need to generate a tap gesture.
                                    if (stylusInputReport.Actions == RawStylusActions.Up) 
                                    { 
                                        if (!stylusDevice.GestureWasFired)
                                        { 
                                            GenerateGesture(stylusInputReport, stylusDevice.LastTapBarrelDown ? SystemGesture.RightTap : SystemGesture.Tap);
                                        }

                                        if (!_inDragDrop && !stylusInputReport.PenContext.Contexts.IsWindowDisabled) 
                                        {
                                            // We need to process a MouseMove before promoting a MouseUp (in PromoteMainToMouse) 
                                            // since the stylus updates the button states for mouse to up then. 
                                            // Note: The Stylus Up is at the same location as the last stylus move so this is OK to do here.
                                            ProcessMouseMove(stylusDevice, stylusInputReport.Timestamp, false); 
                                        }
                                    }

                                    input.Device = stylusDevice; 
                                }
                            } 
 
                            if (cancelInput)
                            { 
                                e.Cancel();  // Don't process this bogus event any further.
                            }
                        }
                    } 
                }
            } 
        } 
Example #8
0
        private bool DeferMouseMove(RawMouseInputReport mouseInputReport)
        {
            if (!_triedDeferringMouseMove)
            { 
                if (_deferredMouseMove != null)
                { 
                    return false; // only allow one at a time. 
                }
                else 
                {
                    _deferredMouseMove = mouseInputReport;

                    // Now make the deferred call to the process the mouse move. 
                    Dispatcher.BeginInvoke(DispatcherPriority.Background, _processDeferredMouseMove, null);
                } 
                return true; 
            }
            return false; 
        }
Example #9
0
        internal bool ShouldConsiderStylusInRange(RawMouseInputReport mouseInputReport) 
        {
            int timestamp = mouseInputReport.Timestamp; 

            // First check to see if we are close to the last time we've had a Stylus InRange
            // We consider it inrange if _lastInRangeTime+500 >= timestamp (whether we've seen
            // one within last 500ms). 
            //  Here's some info on how this works...
            //      int.MaxValue - int.MinValue = -1 (subtracting any negative # from MaxValue keeps this negative) 
            //      int.MinValue - int.MaxValue = 1 (subtracting any positive # from MinValue keeps this positive) 
            //  So as values close to MaxValue and MinValue get farther apart the result increases from a
            //  of delta 1 and we can thus take the Abs value to use for this check. 
            // Note: we don't really care if times wrap since the worst thing that would happen
            // is we'd let a mouse event slip through as you brought the stylus in range which
            // can happen today anyway.
            if (Math.Abs(unchecked(timestamp - _lastInRangeTime)) <= 500) 
                return true;
 
            HwndSource hwndSource = mouseInputReport.InputSource as HwndSource; 
            if (hwndSource != null)
            { 
                PenContexts penContexts = GetPenContextsFromHwnd(hwndSource);
                if (penContexts != null)
                {
                    return penContexts.ConsiderInRange(timestamp); 
                }
            } 
            return false; 
        }
Example #10
0
        private void ProcessMouseMove(StylusDevice stylusDevice, int timestamp, bool isSynchronize)
        { 
            System.Diagnostics.Debug.Assert(stylusDevice != null);

            if (!ShouldPromoteToMouse(stylusDevice) || !stylusDevice.TouchDevice.PromotingToOther)
            { 
                return;
            } 
 
            PresentationSource mouseInputSource = stylusDevice.GetMousePresentationSource();
 
            if (mouseInputSource != null)
            {
                RawMouseActions actions = RawMouseActions.AbsoluteMove;
 
                // Don't set Activate flag if a synchronize is requested!
                if (!isSynchronize) 
                { 
                    if (_inputManager.Value.PrimaryMouseDevice.CriticalActiveSource != mouseInputSource)
                    { 
                        actions |= RawMouseActions.Activate;
                    }
                }
 
                Point pt = stylusDevice.LastMouseScreenPoint; // Use last promoted mouse location.
                pt = PointUtil.ScreenToClient(pt, mouseInputSource); 
 
                RawMouseInputReport mouseInputReport =
                            new RawMouseInputReport(InputMode.Foreground, 
                                                    timestamp,
                                                    mouseInputSource,
                                                    actions,
                                                    (int)pt.X, 
                                                    (int)pt.Y,
                                                    0, 
                                                    IntPtr.Zero); 

                if (isSynchronize) 
                {
                    mouseInputReport._isSynchronize = true;
                }
 
                _lastRawMouseAction = actions;
 
                InputReportEventArgs inputReportArgs = new InputReportEventArgs(stylusDevice, mouseInputReport); 
                inputReportArgs.RoutedEvent = InputManager.PreviewInputReportEvent;
 
                // Process this directly instead of doing a push. We want this event to get
                // to the user before the StylusUp and MouseUp event.
                InputManagerProcessInputEventArgs(inputReportArgs);
            } 
        }
Example #11
0
        private void PromoteMainToMouse(StagingAreaInputItem stagingItem)
        { 
            if(!stagingItem.Input.Handled) 
            {
                StylusEventArgs stylusArgs = stagingItem.Input as StylusEventArgs; 
                if (stylusArgs != null)
                {
                    StylusDevice stylusDevice = stylusArgs.StylusDevice;
 
                    // We only want to promote to mouse when we actually have real stylus input.
                    if (stylusDevice != null) 
                    { 
                        Debug.Assert(ShouldPromoteToMouse(stylusDevice) && stylusDevice.TouchDevice.PromotingToOther);
 
                        if (IgnoreGestureToMousePromotion(stylusArgs as StylusSystemGestureEventArgs, stylusDevice.TouchDevice))
                        {
                            return;
                        } 

                        RawMouseActions actions = stylusDevice.GetMouseActionsFromStylusEventAndPlaybackCachedDown(stagingItem.Input.RoutedEvent, stylusArgs); 
 
                        if (actions != RawMouseActions.None)
                        { 
                            PresentationSource mouseInputSource = stylusDevice.GetMousePresentationSource();

                            if (mouseInputSource != null)
                            { 
                                Point pt = PointUtil.ScreenToClient(stylusDevice.LastMouseScreenPoint, mouseInputSource);
 
                                // 
                                // use the dispatcher as a way of coalescing mouse *move* messages
                                // BUT don't flood the dispatcher with delegates if we're already 
                                // waiting for a callback
                                //
                                if ((actions & RawMouseActions.AbsoluteMove) != 0)
                                { 
                                    if (actions == _lastRawMouseAction && _waitingForDelegate)
                                    { 
                                        return; // We don't need to process this one. 
                                    }
                                    else 
                                    {
                                        //set the waiting bit so we won't enter here again
                                        //until we get the callback
                                        _waitingForDelegate = true; 

                                        Dispatcher.BeginInvoke(DispatcherPriority.Input, 
                                        (DispatcherOperationCallback)delegate(object unused) 
                                        {
                                            //reset our flags here in the callback. 
                                            _waitingForDelegate = false;
                                            return null;
                                        },
                                        null); 
                                    }
                                } 
 
                                // See if we need to set the Mouse Activate flag.
                                if (_inputManager.Value.PrimaryMouseDevice.CriticalActiveSource != mouseInputSource) 
                                {
                                    actions |= RawMouseActions.Activate;
                                }
 
                                _lastRawMouseAction = actions;
 
                                RawMouseInputReport mouseInputReport = new RawMouseInputReport( 
                                                                            InputMode.Foreground, stylusArgs.Timestamp, mouseInputSource,
                                                                            actions, (int)pt.X, (int)pt.Y, 0, IntPtr.Zero); 

                                InputReportEventArgs inputReportArgs = new InputReportEventArgs(stylusDevice, mouseInputReport);
                                inputReportArgs.RoutedEvent=InputManager.PreviewInputReportEvent;
                                _inputManager.Value.ProcessInput(inputReportArgs); 
                            }
                        } 
                    } 
                }
            } 
        }