Ejemplo n.º 1
0
        public override KeyInfo ReadKey(ReadKeyOptions options)
        {
            ConsoleKeyInfo   consoleKeyInfo  = Console.ReadKey((int)(options & ReadKeyOptions.NoEcho) != 0);
            ControlKeyStates controlKeyState = (ControlKeyStates)0;

            if ((int)(consoleKeyInfo.Modifiers & ConsoleModifiers.Alt) != 0)
            {
                controlKeyState = controlKeyState | ControlKeyStates.RightAltPressed | ControlKeyStates.LeftAltPressed;
            }
            if ((int)(consoleKeyInfo.Modifiers & ConsoleModifiers.Control) != 0)
            {
                controlKeyState = controlKeyState | ControlKeyStates.RightCtrlPressed | ControlKeyStates.LeftCtrlPressed;
            }
            if ((int)(consoleKeyInfo.Modifiers & ConsoleModifiers.Shift) != 0)
            {
                controlKeyState |= ControlKeyStates.ShiftPressed;
            }
            if (Console.CapsLock)
            {
                controlKeyState |= ControlKeyStates.CapsLockOn;
            }
            if (Console.NumberLock)
            {
                controlKeyState |= ControlKeyStates.NumLockOn;
            }
            return(new KeyInfo((int)consoleKeyInfo.Key, consoleKeyInfo.KeyChar, controlKeyState, (int)(options & ReadKeyOptions.IncludeKeyDown) != 0));
        }
Ejemplo n.º 2
0
        public static ControlKeyStates ToControlKeyState(this Console.ConsoleControlKeyStates state)
        {
            var map = new Dictionary <Console.ConsoleControlKeyStates, ControlKeyStates>
            {
                { ConsoleControlKeyStates.CapsLockOn, ControlKeyStates.CapsLockOn },
                { ConsoleControlKeyStates.EnhancedKey, ControlKeyStates.EnhancedKey },
                { ConsoleControlKeyStates.LeftAltPressed, ControlKeyStates.LeftAltPressed },
                { ConsoleControlKeyStates.LeftCtrlPressed, ControlKeyStates.LeftCtrlPressed },
                { ConsoleControlKeyStates.NumLockOn, ControlKeyStates.NumLockOn },
                { ConsoleControlKeyStates.RightAltPressed, ControlKeyStates.RightAltPressed },
                { ConsoleControlKeyStates.RightCtrlPressed, ControlKeyStates.RightCtrlPressed },
                { ConsoleControlKeyStates.ScrollLockOn, ControlKeyStates.ScrollLockOn },
                { ConsoleControlKeyStates.ShiftPressed, ControlKeyStates.ShiftPressed },
            };

            ControlKeyStates controlKeyState = 0;

            map.ToList().ForEach(pair =>
            {
                if (0 != (pair.Key & state))
                {
                    controlKeyState |= pair.Value;
                }
            });
            return(controlKeyState);
        }
Ejemplo n.º 3
0
 public KeyInfo(int virtualKeyCode, char ch, ControlKeyStates controlKeyState, bool keyDown)
 {
     this.virtualKeyCode = virtualKeyCode;
     this.character = ch;
     this.controlKeyState = controlKeyState;
     this.keyDown = keyDown;
 }
Ejemplo n.º 4
0
 public KeyInfo(int virtualKeyCode, char ch, ControlKeyStates controlKeyState, bool keyDown)
 {
     this.virtualKeyCode  = virtualKeyCode;
     this.character       = ch;
     this.controlKeyState = controlKeyState;
     this.keyDown         = keyDown;
 }
Ejemplo n.º 5
0
        public void WithoutSwitches_CorrectResults()
        {
            const ControlKeyStates keys = ControlKeyStates.SHIFT_PRESSED | ControlKeyStates.LEFT_ALT_PRESSED | ControlKeyStates.CAPSLOCK_ON |
                                          ControlKeyStates.NUMLOCK_ON | ControlKeyStates.SCROLLLOCK_ON;

            keys.WithoutSwitches().Should().Be(ControlKeyStates.SHIFT_PRESSED | ControlKeyStates.LEFT_ALT_PRESSED);
        }
Ejemplo n.º 6
0
 /// <param name="where">Position.</param>
 /// <param name="action">Action.</param>
 /// <param name="buttons">Buttons.</param>
 /// <param name="controls">Control keys.</param>
 /// <param name="value">Wheel value.</param>
 public MouseInfo(Point where, MouseAction action, MouseButtons buttons, ControlKeyStates controls, int value)
     : base(controls)
 {
     _Where   = where;
     _Buttons = buttons;
     _Action  = action;
     _Value   = value;
 }
Ejemplo n.º 7
0
 internal KeyEventArgs(ConsoleKeyEventArgs e)
 {
     UnicodeChar     = e.UnicodeChar;
     RepeatCount     = e.RepeatCount;
     VirtualKey      = e.VirtualKeyCode;
     VirtualScanCode = e.VirtualScanCode;
     KeyDown         = e.KeyDown;
     ControlKeys     = e.ControlKeys;
 }
Ejemplo n.º 8
0
 public ConsoleKeyEventArgs(KEY_EVENT_RECORD rec)
 {
     KeyDown         = rec.KeyDown != 0;
     RepeatCount     = rec.RepeatCount;
     VirtualKeyCode  = rec.VirtualKeyCode;
     VirtualScanCode = rec.VirtualScanCode;
     UnicodeChar     = rec.UnicodeChar;
     ControlKeys     = rec.ControlKeys;
 }
        public static (bool ctrl, bool alt, bool shift) GetModifiers(this ControlKeyStates dwControlKeyState)
        {
            var shift = (dwControlKeyState & ControlKeyStates.SHIFT_PRESSED) == ControlKeyStates.SHIFT_PRESSED;
            var alt   = (dwControlKeyState & ControlKeyStates.LEFT_ALT_PRESSED) == ControlKeyStates.LEFT_ALT_PRESSED ||
                        (dwControlKeyState & ControlKeyStates.RIGHT_ALT_PRESSED) == ControlKeyStates.RIGHT_ALT_PRESSED;

            var control = (dwControlKeyState & ControlKeyStates.LEFT_CTRL_PRESSED) == ControlKeyStates.LEFT_CTRL_PRESSED ||
                          (dwControlKeyState & ControlKeyStates.RIGHT_CTRL_PRESSED) == ControlKeyStates.RIGHT_CTRL_PRESSED;

            return(control, alt, shift);
        }
Ejemplo n.º 10
0
        public static KeyInfo ReadKey(ReadKeyOptions options)
        {
            if (ConsoleLoaded)
            {
                bool noecho = false;
                if (options == ReadKeyOptions.NoEcho)
                {
                    noecho = true;
                }

                bool CapsLock   = (((ushort)GetKeyState(0x14)) & 0xffff) != 0;
                bool NumLock    = (((ushort)GetKeyState(0x90)) & 0xffff) != 0;
                bool ScrollLock = (((ushort)GetKeyState(0x91)) & 0xffff) != 0;

                ConsoleKeyInfo conKeyInfo = Console.ReadKey(noecho);

                ControlKeyStates cks = new ControlKeyStates();
                if (conKeyInfo.Modifiers == ConsoleModifiers.Shift)
                {
                    cks = cks | ControlKeyStates.ShiftPressed;
                }
                if (conKeyInfo.Modifiers == ConsoleModifiers.Control)
                {
                    cks = cks | ControlKeyStates.LeftCtrlPressed | ControlKeyStates.RightCtrlPressed;
                }
                if (conKeyInfo.Modifiers == ConsoleModifiers.Alt)
                {
                    cks = cks | ControlKeyStates.LeftAltPressed | ControlKeyStates.RightAltPressed;
                }
                if (CapsLock)
                {
                    cks = cks | ControlKeyStates.CapsLockOn;
                }
                if (NumLock)
                {
                    cks = cks | ControlKeyStates.NumLockOn;
                }
                if (ScrollLock)
                {
                    cks = cks | ControlKeyStates.ScrollLockOn;
                }

                return(new KeyInfo(VkKeyScan(conKeyInfo.KeyChar), conKeyInfo.KeyChar, cks, true));
            }
            else
            {
                return(new KeyInfo());
            }
        }
Ejemplo n.º 11
0
        public void MouseEvents_MouseEventRaisedWithCorrectValues()
        {
            const ControlKeyStates controlKeys = ControlKeyStates.LEFT_ALT_PRESSED | ControlKeyStates.CAPSLOCK_ON;
            const int scroll = 123;
            const MouseButtonStates buttons = MouseButtonStates.LeftButtonPressed;
            Point position             = (3, 7).Pt();
            const MouseEventFlags kind = MouseEventFlags.Wheeled;

            var api = new StubbedNativeCalls();

            using var controller = new StubbedConsoleController();
            var graphicsProvider = new StubbedGraphicsProvider();

            var args = new ConsoleMouseEventArgs(new MOUSE_EVENT_RECORD
            {
                ButtonState   = buttons,
                ControlKeys   = controlKeys,
                EventFlags    = kind,
                MousePosition = new COORD(position),
                Scroll        = scroll
            });

            using var sut = new ConControls.Controls.ConsoleWindow(api, controller, graphicsProvider);
            bool raised = false;

            sut.MouseEvent += OnMouse;
            controller.MouseEventEvent(controller, args);
            raised.Should().BeTrue();
            raised          = false;
            sut.MouseEvent -= OnMouse;
            controller.MouseEventEvent(controller, args);
            raised.Should().BeFalse();

            void OnMouse(object sender, MouseEventArgs e)
            {
                sender.Should().Be(sut);
                e.ControlKeys.Should().Be(controlKeys);
                e.Scroll.Should().Be(scroll);
                e.ButtonState.Should().Be(buttons);
                e.Position.Should().Be(position);
                e.Kind.Should().Be(kind);
                raised = true;
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// This API reads a pressed, released, or pressed and released keystroke
        /// from the keyboard device, blocking processing until a keystroke is
        /// typed that matches the specified keystroke options.
        /// </summary>
        /// <param name="options">Options, such as IncludeKeyDown,  used when reading the keyboard.</param>
        /// <returns>KeyInfo of the key pressed</returns>
        public override KeyInfo ReadKey(ReadKeyOptions options)
        {
            VsKeyInfo keyInfo = _debuggingService.CallbackService.VsReadKey();

            if (keyInfo == null)
            {
                // abort current pipeline
                throw new PipelineStoppedException();
            }

            ControlKeyStates states = default(ControlKeyStates);

            states |= (keyInfo.CapsLockToggled ? ControlKeyStates.CapsLockOn : 0);
            states |= (keyInfo.NumLockToggled ? ControlKeyStates.NumLockOn : 0);
            states |= (keyInfo.ShiftPressed ? ControlKeyStates.ShiftPressed : 0);
            states |= (keyInfo.AltPressed ? ControlKeyStates.LeftAltPressed : 0);      // assume LEFT alt
            states |= (keyInfo.ControlPressed ? ControlKeyStates.LeftCtrlPressed : 0); // assume LEFT ctrl

            return(new KeyInfo(keyInfo.VirtualKey, keyInfo.KeyChar, states, keyDown: (keyInfo.KeyStates == KeyStates.Down)));
        }
        public override KeyInfo ReadKey(ReadKeyOptions options)
        {
            // NOTE: readkey options are ignored as they are not really usable or applicable in PM console.

            VsKeyInfo keyInfo = Console.Dispatcher.WaitKey();

            if (keyInfo == null)
            {
                // abort current pipeline (ESC pressed)
                throw new PipelineStoppedException();
            }

            ControlKeyStates states = default(ControlKeyStates);

            states |= (keyInfo.CapsLockToggled ? ControlKeyStates.CapsLockOn : 0);
            states |= (keyInfo.NumLockToggled ? ControlKeyStates.NumLockOn : 0);
            states |= (keyInfo.ShiftPressed ? ControlKeyStates.ShiftPressed : 0);
            states |= (keyInfo.AltPressed ? ControlKeyStates.LeftAltPressed : 0);      // assume LEFT alt
            states |= (keyInfo.ControlPressed ? ControlKeyStates.LeftCtrlPressed : 0); // assume LEFT ctrl

            return(new KeyInfo(keyInfo.VirtualKey, keyInfo.KeyChar, states, keyDown: (keyInfo.KeyStates == KeyStates.Down)));
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Gets the control key states.
        /// </summary>
        /// <param name="kb">The <see cref="KeyboardDevice"/>.</param>
        /// <returns>The <see cref="ControlKeyStates"/> Flags</returns>
        private static ControlKeyStates GetControlKeyStates(this KeyboardDevice kb)
        {
            ControlKeyStates controlStates = default(ControlKeyStates);

            if (kb.IsKeyDown(Key.LeftCtrl))
            {
                controlStates |= ControlKeyStates.LeftCtrlPressed;
            }
            if (kb.IsKeyDown(Key.LeftAlt))
            {
                controlStates |= ControlKeyStates.LeftAltPressed;
            }
            if (kb.IsKeyDown(Key.RightAlt))
            {
                controlStates |= ControlKeyStates.RightAltPressed;
            }
            if (kb.IsKeyDown(Key.RightCtrl))
            {
                controlStates |= ControlKeyStates.RightCtrlPressed;
            }
            if (kb.IsKeyToggled(Key.Scroll))
            {
                controlStates |= ControlKeyStates.ScrollLockOn;
            }
            if (kb.IsKeyToggled(Key.CapsLock))
            {
                controlStates |= ControlKeyStates.CapsLockOn;
            }
            if (kb.IsKeyToggled(Key.NumLock))
            {
                controlStates |= ControlKeyStates.NumLockOn;
            }
            if (kb.IsKeyDown(Key.LeftShift) || kb.IsKeyDown(Key.RightShift))
            {
                controlStates |= ControlKeyStates.ShiftPressed;
            }
            return(controlStates);
        }
Ejemplo n.º 15
0
 /// <param name="virtualKeyCode">Virtual key code of <see cref="Key"/></param>
 /// <param name="controlKeyState">Control states of <see cref="Key"/></param>
 /// <param name="text">See <see cref="Text"/></param>
 /// <param name="longText">See <see cref="LongText"/></param>
 public KeyBar(int virtualKeyCode, ControlKeyStates controlKeyState, string text, string longText)
 {
     Key      = new KeyData(virtualKeyCode, controlKeyState);
     Text     = text;
     LongText = longText;
 }
Ejemplo n.º 16
0
 /// <param name="where">Position.</param>
 /// <param name="action">Action.</param>
 /// <param name="buttons">Buttons.</param>
 /// <param name="controls">Control keys.</param>
 /// <param name="value">Wheel value.</param>
 public MouseInfo(Point where, MouseAction action, MouseButtons buttons, ControlKeyStates controls, int value)
     : base(controls)
 {
     _Where = where;
     _Buttons = buttons;
     _Action = action;
     _Value = value;
 }
Ejemplo n.º 17
0
 /// <param name="virtualKeyCode">See <see cref="KeyData.VirtualKeyCode"/></param>
 /// <param name="character">See <see cref="Character"/></param>
 /// <param name="controlKeyState">See <see cref="KeyBase.ControlKeyState"/></param>
 /// <param name="keyDown">See <see cref="KeyDown"/></param>
 public KeyInfo(int virtualKeyCode, char character, ControlKeyStates controlKeyState, bool keyDown)
     : base(virtualKeyCode, controlKeyState)
 {
     _Character = character;
     _KeyDown   = keyDown;
 }
Ejemplo n.º 18
0
 /// <param name="controlKeyState">See <see cref="ControlKeyState"/></param>
 protected KeyBase(ControlKeyStates controlKeyState)
 {
     _ControlKeyState = controlKeyState;
 }
Ejemplo n.º 19
0
 public KeyState(ControlKeyStates state)
 {
     keyState = state;
 }
Ejemplo n.º 20
0
 /// <param name="virtualKeyCode">See <see cref="VirtualKeyCode"/></param>
 /// <param name="controlKeyState">See <see cref="KeyBase.ControlKeyState"/></param>
 public KeyData(int virtualKeyCode, ControlKeyStates controlKeyState)
     : base(controlKeyState)
 {
     _VirtualKeyCode = virtualKeyCode;
 }
Ejemplo n.º 21
0
 public void AddKey(int virtualKeyCode, ControlKeyStates controlKeyState, EventHandler <MenuEventArgs> handler)
 {
     myKeys.Add(new KeyData(virtualKeyCode, controlKeyState));
     myHandlers.Add(handler);
 }
Ejemplo n.º 22
0
 /// <param name="virtualKeyCode">See <see cref="VirtualKeyCode"/></param>
 /// <param name="controlKeyState">See <see cref="KeyBase.ControlKeyState"/></param>
 public KeyData(int virtualKeyCode, ControlKeyStates controlKeyState)
     : base(controlKeyState)
 {
     _VirtualKeyCode = virtualKeyCode;
 }
Ejemplo n.º 23
0
 /// <param name="virtualKeyCode">See <see cref="KeyData.VirtualKeyCode"/></param>
 /// <param name="character">See <see cref="Character"/></param>
 /// <param name="controlKeyState">See <see cref="KeyBase.ControlKeyState"/></param>
 /// <param name="keyDown">See <see cref="KeyDown"/></param>
 public KeyInfo(int virtualKeyCode, char character, ControlKeyStates controlKeyState, bool keyDown)
     : base(virtualKeyCode, controlKeyState)
 {
     _Character = character;
     _KeyDown = keyDown;
 }
Ejemplo n.º 24
0
 public void AddKey(int virtualKeyCode, ControlKeyStates controlKeyState)
 {
     AddKey(virtualKeyCode, controlKeyState, null);
 }
Ejemplo n.º 25
0
 public KeyInfo(int virtualKeyCode, char ch, ControlKeyStates controlKeyState, bool keyDown)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 26
0
 public KeyInfo(int virtualKeyCode, char ch, ControlKeyStates controlKeyState, bool keyDown)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 27
0
 KeyInfo
 (
     int virtualKeyCode,
     char ch,
     ControlKeyStates controlKeyState,
     bool keyDown
 )
 {
     VirtualKeyCode = virtualKeyCode;
     Character = ch;
     ControlKeyState = controlKeyState;
     KeyDown = keyDown;
 }
Ejemplo n.º 28
0
 /// <param name="virtualKeyCode">Virtual key code of <see cref="Key"/></param>
 /// <param name="controlKeyState">Control states of <see cref="Key"/></param>
 /// <param name="text">See <see cref="Text"/></param>
 /// <param name="longText">See <see cref="LongText"/></param>
 public KeyBar(int virtualKeyCode, ControlKeyStates controlKeyState, string text, string longText)
 {
     Key = new KeyData(virtualKeyCode, controlKeyState);
     Text = text;
     LongText = longText;
 }
Ejemplo n.º 29
0
 /// <param name="controlKeyState">See <see cref="ControlKeyState"/></param>
 protected KeyBase(ControlKeyStates controlKeyState)
 {
     _ControlKeyState = controlKeyState;
 }
Ejemplo n.º 30
0
        /// <summary>
        /// Thread method invoked from <see cref="ReadKey"/> that waits for the user to press a key.
        /// </summary>
        /// <param name="state"><see cref="Tuple{T1, T2}"/> object containing a <see cref="StreamConnection"/> object and a <see cref="ReadKeyOptions"/>
        /// object.</param>
        private void ReadInput(object state)
        {
            StreamConnection connection       = (state as Tuple <StreamConnection, ReadKeyOptions>).Item1;
            ReadKeyOptions   options          = (state as Tuple <StreamConnection, ReadKeyOptions>).Item2;
            bool             inEscapeSequence = false;
            bool             readKey          = false;

            while (!readKey)
            {
                if (connection.OutputQueue.Count > 0)
                {
                    while (connection.OutputQueue.Count > 0)
                    {
                        byte currentByte = connection.OutputQueue.Dequeue();

                        // Handle the backspace key
                        if (currentByte == 8)
                        {
                            _readKey = new KeyInfo
                            {
                                VirtualKeyCode = 8
                            };

                            // If we're not already at the beginning of the line and we're echoing the output, move the cursor left
                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho && CursorPosition.X > 1)
                            {
                                CursorPosition = new Coordinates(CursorPosition.X - 1, CursorPosition.Y);
                            }

                            readKey = true;
                            break;
                        }

                        // The ^X character signifies the start of an ANSI escape sequence
                        else if (currentByte == 27)
                        {
                            inEscapeSequence = true;
                        }

                        // If we're in an escape sequence, read past the "[" and "~" characters
                        else if (currentByte == 91 && inEscapeSequence)
                        {
                        }

                        else if (currentByte == 126 && inEscapeSequence)
                        {
                        }

                        // ^X7 is the home key
                        else if (currentByte == 55 && inEscapeSequence)
                        {
                            _readKey = new KeyInfo
                            {
                                VirtualKeyCode = 0x24
                            };

                            // If we're not already at the beginning of the line and we're echoing the output, move the cursor to the start of the line
                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho)
                            {
                                CursorPosition = new Coordinates(1, CursorPosition.Y);
                            }

                            readKey = true;
                            break;
                        }

                        // ^X8 or ^X3 is the end key
                        else if ((currentByte == 56 || currentByte == 51) && inEscapeSequence)
                        {
                            _readKey = new KeyInfo
                            {
                                VirtualKeyCode = 0x23
                            };

                            // If we're not already at the beginning of the line and we're echoing the output, move the cursor to the end of the line
                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho)
                            {
                                CursorPosition = new Coordinates(BufferSize.Width, CursorPosition.Y);
                            }

                            readKey = true;
                            break;
                        }

                        // ^XD is the left arrow
                        else if (currentByte == 68 && inEscapeSequence)
                        {
                            _readKey = new KeyInfo
                            {
                                VirtualKeyCode = 0x25
                            };

                            // If we're not already at the beginning of the line and we're echoing the output, move the cursor left
                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho && CursorPosition.X > 1)
                            {
                                CursorPosition = new Coordinates(CursorPosition.X - 1, CursorPosition.Y);
                            }

                            readKey = true;
                            break;
                        }

                        // ^XC is the right arrow
                        else if (currentByte == 67 && inEscapeSequence)
                        {
                            _readKey = new KeyInfo
                            {
                                VirtualKeyCode = 0x27
                            };

                            // If we're not already at the beginning of the line and we're echoing the output, move the cursor right
                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho && CursorPosition.X < BufferSize.Width)
                            {
                                CursorPosition = new Coordinates(CursorPosition.X + 1, CursorPosition.Y);
                            }

                            readKey = true;
                            break;
                        }

                        // Handle the carriage return sequence
                        else if (currentByte == 13)
                        {
                            _readKey = new KeyInfo
                            {
                                Character      = '\r',
                                VirtualKeyCode = 0x0D
                            };

                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho)
                            {
                                CursorPosition = new Coordinates(1, CursorPosition.Y);
                            }

                            readKey = true;
                            break;
                        }

                        // Otherwise, get the virtual key code and character and populate _readKey
                        else
                        {
                            short            virtualKey  = User32.VkKeyScan((char)currentByte);
                            int              modifiers   = virtualKey >> 8;
                            ControlKeyStates controlKeys = 0;

                            if ((modifiers & 2) != 0)
                            {
                                controlKeys |= ControlKeyStates.LeftCtrlPressed;
                            }

                            if ((modifiers & 4) != 0)
                            {
                                controlKeys |= ControlKeyStates.LeftAltPressed;
                            }

                            _readKey = new KeyInfo
                            {
                                Character       = (char)currentByte,
                                VirtualKeyCode  = (virtualKey & 0xFF),
                                ControlKeyState = controlKeys
                            };

                            if ((options & ReadKeyOptions.NoEcho) != ReadKeyOptions.NoEcho)
                            {
                                _terminal.TerminalPane.ConnectionTag.Receiver.DataArrived(
                                    new byte[]
                                {
                                    currentByte
                                }, 0, 1);
                            }

                            readKey = true;
                            break;
                        }
                    }
                }

                // If we didn't read a key, sleep for a bit
                if (!readKey)
                {
                    Thread.Sleep(50);
                }
            }

            // Signal to ReadKey() that we've read a key
            _inputSemaphore.Set();
        }
Ejemplo n.º 31
0
 internal static ControlKeyStates WithoutSwitches(this ControlKeyStates controlKeys) =>
 controlKeys & ~(ControlKeyStates.CAPSLOCK_ON | ControlKeyStates.NUMLOCK_ON | ControlKeyStates.SCROLLLOCK_ON);