GetKeyboardState() private method

private GetKeyboardState ( byte lpKeyState ) : int
lpKeyState byte
return int
Exemplo n.º 1
0
        internal static Key VkToKey(VK vk, SC sc, LLKHF flags, bool has_shift,
                                    bool has_altgr, bool has_capslock)
        {
            byte[] keystate = new byte[256];
            NativeMethods.GetKeyboardState(keystate);
            keystate[(int)VK.SHIFT]   = (byte)(has_shift ? 0x80 : 0x00);
            keystate[(int)VK.CONTROL] = (byte)(has_altgr ? 0x80 : 0x00);
            keystate[(int)VK.MENU]    = (byte)(has_altgr ? 0x80 : 0x00);
            keystate[(int)VK.CAPITAL] = (byte)(has_capslock ? 0x01 : 0x00);

            // These two calls must be done together and in this order.
            string str_if_normal = VkToUnicode(vk, sc, keystate, flags);
            string str_if_dead   = VkToUnicode(VK.SPACE);

            // This indicates that vk was a dead key
            if (str_if_dead != "" && str_if_dead != " ")
            {
                return(new Key(str_if_dead));
            }

            // Special case: we don't consider characters such as Esc as printable
            // otherwise they are not properly serialised in the config file.
            if (str_if_normal == "" || str_if_normal[0] < ' ')
            {
                return(new Key(vk));
            }

            return(new Key(str_if_normal));
        }
Exemplo n.º 2
0
        private static bool OnKeyInternal(WM ev, VK vk, SC sc, LLKHF flags)
        {
            CheckKeyboardLayout();

            bool is_keydown = (ev == WM.KEYDOWN || ev == WM.SYSKEYDOWN);
            bool is_keyup   = !is_keydown;

            bool has_shift = (NativeMethods.GetKeyState(VK.SHIFT) & 0x80) != 0;
            bool has_altgr = (NativeMethods.GetKeyState(VK.LCONTROL) &
                              NativeMethods.GetKeyState(VK.RMENU) & 0x80) != 0;
            bool has_lrshift = (NativeMethods.GetKeyState(VK.LSHIFT) &
                                NativeMethods.GetKeyState(VK.RSHIFT) & 0x80) != 0;
            bool has_capslock = NativeMethods.GetKeyState(VK.CAPITAL) != 0;

            // Guess what key was just pressed. If we can not find a printable
            // representation for the key, default to its virtual key code.
            Key key = new Key(vk);

            byte[] keystate = new byte[256];
            NativeMethods.GetKeyboardState(keystate);
            keystate[(int)VK.SHIFT]   = (byte)(has_shift ? 0x80 : 0x00);
            keystate[(int)VK.CONTROL] = (byte)(has_altgr ? 0x80 : 0x00);
            keystate[(int)VK.MENU]    = (byte)(has_altgr ? 0x80 : 0x00);
            keystate[(int)VK.CAPITAL] = (byte)(has_capslock ? 0x01 : 0x00);



            string str_if_normal = KeyToUnicode(vk, sc, keystate, flags);
            string str_if_dead   = KeyToUnicode(VK.SPACE);

            if (str_if_normal != "")
            {
                // This appears to be a normal, printable key
                key = new Key(str_if_normal);
            }
            else if (str_if_dead != " ")
            {
                // This appears to be a dead key
                key = new Key(str_if_dead);
            }

            // Special case: we don't consider characters such as Esc as printable
            // otherwise they are not properly serialised in the config file.
            if (key.IsPrintable() && key.ToString()[0] < ' ')
            {
                key = new Key(vk);
            }

            Log("WM.{0} {1} (VK:0x{2:X02} SC:0x{3:X02})",
                ev.ToString(), key.FriendlyName, (int)vk, (int)sc);

            // FIXME: we don’t properly support compose keys that also normally
            // print stuff, such as `.
            if (key == Settings.ComposeKey.Value)
            {
                if (is_keyup)
                {
                    // If we receive a keyup for the compose key, but we hadn't
                    // previously marked it as down, it means we're in emulation
                    // mode and we need to cancel it.
                    if (!m_compose_down)
                    {
                        Log("Fallback Off");
                        SendKeyUp(Settings.ComposeKey.Value.VirtualKey);
                    }

                    m_compose_down = false;
                }
                else if (is_keydown && !m_compose_down)
                {
                    // FIXME: we don't want compose + compose to disable composing,
                    // since there are compose sequences that use Multi_key.
                    // FIXME: also, if a sequence was in progress, print it!
                    m_compose_down = true;
                    m_composing    = !m_composing;
                    if (!m_composing)
                    {
                        m_sequence.Clear();
                    }

                    Log("{0} Composing", m_composing ? "Now" : "No Longer");

                    // Lauch the sequence reset expiration thread
                    // FIXME: do we need to launch a new thread each time the
                    // compose key is pressed? Let's have a dormant thread instead
                    if (m_composing && Settings.ResetDelay.Value > 0)
                    {
                        new Thread(() =>
                        {
                            while (m_composing && DateTime.Now < m_last_key_time.AddMilliseconds(Settings.ResetDelay.Value))
                            {
                                Thread.Sleep(50);
                            }
                            ResetSequence();
                        }).Start();
                    }
                }

                Changed(null, new EventArgs());

                return(true);
            }

            // Feature: emulate capslock key with both shift keys, and optionally
            // disable capslock using only one shift key.
            if (key.VirtualKey == VK.LSHIFT || key.VirtualKey == VK.RSHIFT)
            {
                if (is_keyup && has_lrshift && Settings.EmulateCapsLock.Value)
                {
                    SendKeyPress(VK.CAPITAL);
                    return(false);
                }

                if (is_keydown && has_capslock && Settings.ShiftDisablesCapsLock.Value)
                {
                    SendKeyPress(VK.CAPITAL);
                    return(false);
                }
            }

            // If we are not currently composing a sequence, do nothing. But if
            // this was a dead key, eat it.
            if (!m_composing)
            {
                return(false);
            }

            // If the compose key is down, maybe there is a key combination
            // going on, such as Alt+Tab or Windows+Up, so we abort composing
            // and tell the OS that the key is down.
            if (m_compose_down && (Settings.KeepOriginalKey.Value ||
                                   !Settings.IsUsableKey(key)))
            {
                Log("Fallback On");
                ResetSequence();
                SendKeyDown(Settings.ComposeKey.Value.VirtualKey);
                return(false);
            }

            // If the key can't be used in a sequence, just ignore it.
            if (!Settings.IsUsableKey(key))
            {
                return(false);
            }

            // If we reached this point, everything else ignored this key, so it
            // is a key we must add to the current sequence.
            if (is_keydown)
            {
                return(AddToSequence(key));
            }

            return(true);
        }