public RawKeyboardInputReport(
            PresentationSource inputSource,
            InputMode mode,
            int timestamp, 
            RawKeyboardActions actions, 
            int scanCode, 
            bool isExtendedKey,
            bool isSystemKey,
            int virtualKey, 
            IntPtr extraInformation) : base(inputSource, InputType.Keyboard, mode, timestamp)
        {
            if (!IsValidRawKeyboardActions(actions))
                throw new System.ComponentModel.InvalidEnumArgumentException("actions", (int)actions, typeof(RawKeyboardActions));

            _actions = actions;
            _scanCode = scanCode;
            _isExtendedKey = isExtendedKey;
            _isSystemKey = isSystemKey;
            _virtualKey = virtualKey;
            _extraInformation = new SecurityCriticalData<IntPtr>(extraInformation);
        }
예제 #2
0
        private RawKeyboardActions GetNonRedundantActions(NotifyInputEventArgs e) 
        {
            RawKeyboardActions actions; 
 
            // 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 = (RawKeyboardActions) o; 
            }
            else 
            { 
                actions = new RawKeyboardActions();
            } 

            return actions;
        }
        // IsValid Method for RawKeyboardActions. Relies on the enum being flags.
        internal static bool IsValidRawKeyboardActions(RawKeyboardActions actions)
        {
            if (((RawKeyboardActions.AttributesChanged | RawKeyboardActions.Activate | RawKeyboardActions.Deactivate |
                  RawKeyboardActions.KeyDown | RawKeyboardActions.KeyUp) & actions) == actions)
            {
                if (!((((RawKeyboardActions.KeyUp | RawKeyboardActions.KeyDown) & actions) == (RawKeyboardActions.KeyUp | RawKeyboardActions.KeyDown)) ||
                      ((RawKeyboardActions.Deactivate & actions) == actions && RawKeyboardActions.Deactivate != actions)))
                {
                    return true;
                }
            }
	    return false;
        }
예제 #4
0
        private void PreNotifyInput(object sender, NotifyInputEventArgs e)
        {
            RawKeyboardInputReport keyboardInput = ExtractRawKeyboardInputReport(e, InputManager.PreviewInputReportEvent);

            if (keyboardInput != null)
            {
                CheckForDisconnectedFocus();

                // Activation
                //
                // MITIGATION: KEYBOARD_STATE_OUT_OF_SYNC
                //
                // It is very important that we allow multiple activate events.
                // This is how we deal with the fact that Win32 sometimes sends
                // us a WM_SETFOCUS message BEFORE it has updated it's internal
                // internal keyboard state information.  When we get the
                // WM_SETFOCUS message, we activate the keyboard with the
                // keyboard state (even though it could be wrong).  Then when
                // we get the first "real" keyboard input event, we activate
                // the keyboard again, since Win32 will have updated the
                // keyboard state correctly by then.
                //
                if ((keyboardInput.Actions & RawKeyboardActions.Activate) == RawKeyboardActions.Activate)
                {
                    //if active source is null, no need to do special-case handling
                    if (_activeSource == null)
                    {
                        // we are now active.
                        _activeSource = new SecurityCriticalDataClass <PresentationSource>(keyboardInput.InputSource);
                    }
                    else if (_activeSource.Value != keyboardInput.InputSource)
                    {
                        IKeyboardInputProvider toDeactivate = _activeSource.Value.GetInputProvider(typeof(KeyboardDevice)) as IKeyboardInputProvider;

                        // we are now active.
                        _activeSource = new SecurityCriticalDataClass <PresentationSource>(keyboardInput.InputSource);

                        if (toDeactivate != null)
                        {
                            toDeactivate.NotifyDeactivate();
                        }
                    }
                }

                // Generally, we need to check against redundant actions.
                // We never prevet the raw event from going through, but we
                // will only generate the high-level events for non-redundant
                // actions.  We store the set of non-redundant actions in
                // the dictionary of this event.

                // If the input is reporting a key down, the action is never
                // considered redundant.
                if ((keyboardInput.Actions & RawKeyboardActions.KeyDown) == RawKeyboardActions.KeyDown)
                {
                    RawKeyboardActions actions = GetNonRedundantActions(e);
                    actions |= RawKeyboardActions.KeyDown;
                    e.StagingItem.SetData(_tagNonRedundantActions, actions);

                    // Pass along the key that was pressed, and update our state.
                    Key key = KeyInterop.KeyFromVirtualKey(keyboardInput.VirtualKey);
                    e.StagingItem.SetData(_tagKey, key);
                    e.StagingItem.SetData(_tagScanCode, new ScanCode(keyboardInput.ScanCode, keyboardInput.IsExtendedKey));

                    // Tell the InputManager that the MostRecentDevice is us.
                    if (_inputManager != null)
                    {
                        _inputManager.Value.MostRecentInputDevice = this;
                    }
                }

                // We are missing detection for redundant ups
                if ((keyboardInput.Actions & RawKeyboardActions.KeyUp) == RawKeyboardActions.KeyUp)
                {
                    RawKeyboardActions actions = GetNonRedundantActions(e);
                    actions |= RawKeyboardActions.KeyUp;
                    e.StagingItem.SetData(_tagNonRedundantActions, actions);

                    // Pass along the key that was pressed, and update our state.
                    Key key = KeyInterop.KeyFromVirtualKey(keyboardInput.VirtualKey);
                    e.StagingItem.SetData(_tagKey, key);
                    e.StagingItem.SetData(_tagScanCode, new ScanCode(keyboardInput.ScanCode, keyboardInput.IsExtendedKey));

                    // Tell the InputManager that the MostRecentDevice is us.
                    if (_inputManager != null)
                    {
                        _inputManager.Value.MostRecentInputDevice = this;
                    }
                }
            }

            // On KeyDown, we might need to set the Repeat flag

            if (e.StagingItem.Input.RoutedEvent == Keyboard.PreviewKeyDownEvent)
            {
                CheckForDisconnectedFocus();

                KeyEventArgs args = (KeyEventArgs)e.StagingItem.Input;

                // Is this the same as the previous key?  (Look at the real key, e.g. TextManager
                // might have changed args.Key it to Key.TextInput.)

                if (_previousKey == args.RealKey)
                {
                    // Yes, this is a repeat (we got the keydown for it twice, with no KeyUp in between)
                    args.SetRepeat(true);
                }

                // Otherwise, keep this key to check against next time.
                else
                {
                    _previousKey = args.RealKey;
                    args.SetRepeat(false);
                }
            }

            // On KeyUp, we clear Repeat flag
            else if (e.StagingItem.Input.RoutedEvent == Keyboard.PreviewKeyUpEvent)
            {
                CheckForDisconnectedFocus();

                KeyEventArgs args = (KeyEventArgs)e.StagingItem.Input;
                args.SetRepeat(false);

                // Clear _previousKey, so that down/up/down/up doesn't look like a repeat
                _previousKey = Key.None;
            }
        }
예제 #5
0
        private void PostProcessInput(object sender, ProcessInputEventArgs e)
        {
            // PreviewKeyDown --> KeyDown
            if (e.StagingItem.Input.RoutedEvent == Keyboard.PreviewKeyDownEvent)
            {
                CheckForDisconnectedFocus();

                if (!e.StagingItem.Input.Handled)
                {
                    KeyEventArgs previewKeyDown = (KeyEventArgs)e.StagingItem.Input;

                    // Dig out the real key.
                    bool isSystemKey         = false;
                    bool isImeProcessed      = false;
                    bool isDeadCharProcessed = false;
                    Key  key = previewKeyDown.Key;
                    if (key == Key.System)
                    {
                        isSystemKey = true;
                        key         = previewKeyDown.RealKey;
                    }
                    else if (key == Key.ImeProcessed)
                    {
                        isImeProcessed = true;
                        key            = previewKeyDown.RealKey;
                    }
                    else if (key == Key.DeadCharProcessed)
                    {
                        isDeadCharProcessed = true;
                        key = previewKeyDown.RealKey;
                    }

                    KeyEventArgs keyDown = new KeyEventArgs(this, previewKeyDown.UnsafeInputSource, previewKeyDown.Timestamp, key);
                    keyDown.SetRepeat(previewKeyDown.IsRepeat);

                    // Mark the new event as SystemKey as appropriate.
                    if (isSystemKey)
                    {
                        keyDown.MarkSystem();
                    }
                    else if (isImeProcessed)
                    {
                        // Mark the new event as ImeProcessed as appropriate.
                        keyDown.MarkImeProcessed();
                    }
                    else if (isDeadCharProcessed)
                    {
                        keyDown.MarkDeadCharProcessed();
                    }

                    keyDown.RoutedEvent   = Keyboard.KeyDownEvent;
                    keyDown.ScanCode      = previewKeyDown.ScanCode;
                    keyDown.IsExtendedKey = previewKeyDown.IsExtendedKey;
                    e.PushInput(keyDown, e.StagingItem);
                }
            }

            // PreviewKeyUp --> KeyUp
            if (e.StagingItem.Input.RoutedEvent == Keyboard.PreviewKeyUpEvent)
            {
                CheckForDisconnectedFocus();

                if (!e.StagingItem.Input.Handled)
                {
                    KeyEventArgs previewKeyUp = (KeyEventArgs)e.StagingItem.Input;

                    // Dig out the real key.
                    bool isSystemKey         = false;
                    bool isImeProcessed      = false;
                    bool isDeadCharProcessed = false;
                    Key  key = previewKeyUp.Key;
                    if (key == Key.System)
                    {
                        isSystemKey = true;
                        key         = previewKeyUp.RealKey;
                    }
                    else if (key == Key.ImeProcessed)
                    {
                        isImeProcessed = true;
                        key            = previewKeyUp.RealKey;
                    }
                    else if (key == Key.DeadCharProcessed)
                    {
                        isDeadCharProcessed = true;
                        key = previewKeyUp.RealKey;
                    }

                    KeyEventArgs keyUp = new KeyEventArgs(this, previewKeyUp.UnsafeInputSource, previewKeyUp.Timestamp, key);

                    // Mark the new event as SystemKey as appropriate.
                    if (isSystemKey)
                    {
                        keyUp.MarkSystem();
                    }
                    else if (isImeProcessed)
                    {
                        // Mark the new event as ImeProcessed as appropriate.
                        keyUp.MarkImeProcessed();
                    }
                    else if (isDeadCharProcessed)
                    {
                        keyUp.MarkDeadCharProcessed();
                    }

                    keyUp.RoutedEvent   = Keyboard.KeyUpEvent;
                    keyUp.ScanCode      = previewKeyUp.ScanCode;
                    keyUp.IsExtendedKey = previewKeyUp.IsExtendedKey;
                    e.PushInput(keyUp, e.StagingItem);
                }
            }

            RawKeyboardInputReport keyboardInput = ExtractRawKeyboardInputReport(e, InputManager.InputReportEvent);

            if (keyboardInput != null)
            {
                CheckForDisconnectedFocus();

                if (!e.StagingItem.Input.Handled)
                {
                    // In general, this is where we promote the non-redundant
                    // reported actions to our premier events.
                    RawKeyboardActions actions = GetNonRedundantActions(e);

                    // Raw --> PreviewKeyDown
                    if ((actions & RawKeyboardActions.KeyDown) == RawKeyboardActions.KeyDown)
                    {
                        Key key = (Key)e.StagingItem.GetData(_tagKey);
                        if (key != Key.None)
                        {
                            KeyEventArgs previewKeyDown = new KeyEventArgs(this, keyboardInput.InputSource, keyboardInput.Timestamp, key);
                            ScanCode     scanCode       = (ScanCode)e.StagingItem.GetData(_tagScanCode);
                            previewKeyDown.ScanCode      = scanCode.Code;
                            previewKeyDown.IsExtendedKey = scanCode.IsExtended;
                            if (keyboardInput.IsSystemKey)
                            {
                                previewKeyDown.MarkSystem();
                            }
                            previewKeyDown.RoutedEvent = Keyboard.PreviewKeyDownEvent;
                            e.PushInput(previewKeyDown, e.StagingItem);
                        }
                    }

                    // Raw --> PreviewKeyUp
                    if ((actions & RawKeyboardActions.KeyUp) == RawKeyboardActions.KeyUp)
                    {
                        Key key = (Key)e.StagingItem.GetData(_tagKey);
                        if (key != Key.None)
                        {
                            KeyEventArgs previewKeyUp = new KeyEventArgs(this, keyboardInput.InputSource, keyboardInput.Timestamp, key);
                            ScanCode     scanCode     = (ScanCode)e.StagingItem.GetData(_tagScanCode);
                            previewKeyUp.ScanCode      = scanCode.Code;
                            previewKeyUp.IsExtendedKey = scanCode.IsExtended;
                            if (keyboardInput.IsSystemKey)
                            {
                                previewKeyUp.MarkSystem();
                            }
                            previewKeyUp.RoutedEvent = Keyboard.PreviewKeyUpEvent;
                            e.PushInput(previewKeyUp, e.StagingItem);
                        }
                    }
                }

                // Deactivate
                if ((keyboardInput.Actions & RawKeyboardActions.Deactivate) == RawKeyboardActions.Deactivate)
                {
                    if (IsActive)
                    {
                        _activeSource = null;

                        // Even if handled, a keyboard deactivate results in a lost focus.
                        ChangeFocus(null, e.StagingItem.Input.Timestamp);
                    }
                }
            }
        }
예제 #6
0
        private bool ReportInput(
            IntPtr hwnd,
            InputMode mode,
            int timestamp,
            RawKeyboardActions actions,
            int scanCode,
            bool isExtendedKey,
            bool isSystemKey,
            int virtualKey)
        {
            Debug.Assert(null != _source);

            // The first event should also activate the keyboard device.
            if ((actions & RawKeyboardActions.Deactivate) == 0)
            {
                if (!_active || _partialActive)
                {
                    try
                    {
                        // Include the activation action.
                        actions |= RawKeyboardActions.Activate;

                        // Remember that we are active.
                        _active        = true;
                        _partialActive = false;
                    }
                    catch (System.ComponentModel.Win32Exception)
                    {
                        System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: GetKeyboardState failed!");

                        // We'll go ahead and report the input, but we'll try to "activate" next time.
                    }
                }
            }

            // Get the extra information sent along with the message.
            IntPtr extraInformation = IntPtr.Zero;

            try
            {
                extraInformation = UnsafeNativeMethods.GetMessageExtraInfo();
            }
            catch (System.ComponentModel.Win32Exception)
            {
                System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: GetMessageExtraInfo failed!");
            }

            RawKeyboardInputReport report = new RawKeyboardInputReport(_source.Value,
                                                                       mode,
                                                                       timestamp,
                                                                       actions,
                                                                       scanCode,
                                                                       isExtendedKey,
                                                                       isSystemKey,
                                                                       virtualKey,
                                                                       extraInformation);


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

            return(handled);
        }
        private bool ReportInput( 
            IntPtr hwnd, 
            InputMode mode,
            int timestamp, 
            RawKeyboardActions actions,
            int scanCode,
            bool isExtendedKey,
            bool isSystemKey, 
            int virtualKey)
        { 
            Debug.Assert( null != _source ); 

            // The first event should also activate the keyboard device. 
            if((actions & RawKeyboardActions.Deactivate) == 0)
            {
                if(!_active || _partialActive)
                { 
                    try
                    { 
                        // Include the activation action. 
                        actions |= RawKeyboardActions.Activate;
 
                        // Remember that we are active.
                        _active = true;
                        _partialActive = false;
                    } 
                    catch(System.ComponentModel.Win32Exception)
                    { 
                        System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: GetKeyboardState failed!"); 

                        // We'll go ahead and report the input, but we'll try to "activate" next time. 
                    }
                }
            }
 
            // Get the extra information sent along with the message.
            IntPtr extraInformation = IntPtr.Zero; 
            try 
            {
                extraInformation = UnsafeNativeMethods.GetMessageExtraInfo(); 
            }
            catch(System.ComponentModel.Win32Exception)
            {
                System.Diagnostics.Debug.WriteLine("HwndMouseInputProvider: GetMessageExtraInfo failed!"); 
            }
 
            RawKeyboardInputReport report = new RawKeyboardInputReport(_source.Value, 
                                                                       mode,
                                                                       timestamp, 
                                                                       actions,
                                                                       scanCode,
                                                                       isExtendedKey,
                                                                       isSystemKey, 
                                                                       virtualKey,
                                                                       extraInformation); 
 

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

            return handled;
        }
 /// <summary>
 /// Construct RawKeyboardInputReportWrapper with keyboard state
 /// </summary>
 /// <param name="inputSource">inputSource</param>
 /// <param name="mode">mode</param>
 /// <param name="timestamp">timestamp</param>
 /// <param name="actions">actions</param>
 /// <param name="scanCode">scanCode</param>
 /// <param name="isExtendedKey">isExtendedKey</param>
 /// <param name="isSystemKey">isSystemKey</param>
 /// <param name="virtualKey">virtualKey</param>
 /// <param name="extraInformation">extraInformation</param>
 /// <param name="keyboardState">keyboardState</param>
 public RawKeyboardInputReportWrapper(PresentationSource inputSource, InputMode mode, int timestamp, RawKeyboardActions actions, int scanCode, bool isExtendedKey, bool isSystemKey, int virtualKey, IntPtr extraInformation, RawKeyboardState keyboardState)
     : base()
 {
     object[] objArrayInputReportConstructor = new object[] { inputSource, mode, timestamp, actions, scanCode, isExtendedKey, isSystemKey, virtualKey, extraInformation, keyboardState };
     this.InnerObject = Activator.CreateInstance(ReportType, objArrayInputReportConstructor);
     Trace.Assert(this.InnerObject != null, "Uh oh, not an input report");
 }