Пример #1
0
        // Parse a key macro and return a string of tokens
        public string[] ValidateMacro(string macro)
        {
            // This will track modifier keys to ensure they're all terminated
            List <string> Modifiers = new List <string>();
            // Holds series of tokens to be returned
            List <string> KeyTokens = new List <string>();

            // Split input into words
            string[] tokens = macro.Split(' ');

            if (tokens.Length < 1)
            {
                throw new FormatException("Key macro is blank");
            }

            // Iterate over words
            foreach (string token in tokens)
            {
                string tokenU = token.ToUpper();
                // Check if word is a valid key
                if (SendRawInput.KeyData.ContainsKey(tokenU))
                {
                    // Add it to the return value
                    KeyTokens.Add(tokenU);
                    SendRawInput.KeyInfo key = SendRawInput.KeyData[tokenU];
                    // If the key is a modifier and isn't in the Modifiers list, add it.
                    // Otherwise, remove it.
                    // This will be used to ensure all modifiers are terminated.
                    if (key.Modifier)
                    {
                        if (!Modifiers.Contains(tokenU))
                        {
                            Modifiers.Add(tokenU);
                        }
                        else
                        {
                            Modifiers.Remove(tokenU);
                        }
                    }
                }
                else
                {
                    // Was not a valid key; give up and throw exception (since otherwise we'd need to
                    // return an empty string, which is vague)
                    throw new FormatException("Invalid key name: " + token);
                }
            }

            // If there are any unmatched modifier keys (pressed but never released), release them now
            if (Modifiers.Count > 0)
            {
#if DEBUG
                DbgW("Modifier keys " + string.Join(",", Modifiers) + " were not terminated, terminating automatically.");
#endif

                // Add each modifier to the returned string
                foreach (string Modifier in Modifiers)
                {
                    KeyTokens.Add(Modifier);
                }
            }

            return(KeyTokens.ToArray());

            /*
             * Note for later reference: there are a lot of ways of making modifier keys work, and at some later date,
             * if anyone has interest in this project , I would love to see this language replaced with one that does a
             * cleaner job with them, but parsers are the opposite of my forte, so this isn't going to be clean.
             *
             * A good way to handle this would be to say that a single modifier by itself is an instantaneous keypress,
             * a modifier prefixed e.g. CTRL {A A S} will send Ctrl keydown, A A S as keypresses, then Ctrl keyup. But
             * the code for that is ugly and confusing to my head, so I'm just going to make every modifier a toggle.
             *
             * Every modifier is flagged as such in the key value structure, and has a state field. when it's in a
             * macro it will toggle the state every time it's called; macro validation will fail if not all modifiers are
             * released after being set. This is probably adequate long term, frankly.
             */
        }
Пример #2
0
        // Common function for triggering button events so delay & instant buttons use the same code
        private void ButtonEvent(int index)
        {
            // New sendkey APIs
            //SendRawInput.SendKeyDown(SendRawInput.KeyCodes.DIK_LCONTROL);
            //SendRawInput.SendKeyPress(SendRawInput.KeyCodes.DIK_V, 50);
            //SendRawInput.SendKeyUp(SendRawInput.KeyCodes.DIK_LCONTROL);

            // Don't actually send keys if "Enable binds" is unchecked
            if (ChkBinds.Checked == false)
            {
                DbgW("Binds disabled; not sending keys");
                return;
            }

            string macro = ActionStrings[index].Text;

            string[] MacroTokens;
            // Validate the macro and get an array of valid keycodes back
            try
            {
                MacroTokens = ValidateMacro(macro);
            } catch (FormatException e)
            {
                DbgW("Macro for button " + index.ToString() + " is invalid: " + e.Message);
                return;
            }

            // This will track modifier keys to ensure they're all terminated
            List <string> Modifiers = new List <string>();

            DbgW("Sending keys: " + string.Join(",", MacroTokens));
            // Send the actual keystrokes
            foreach (string Token in MacroTokens)
            {
                SendRawInput.KeyInfo key = SendRawInput.KeyData[Token];
                // Track which modifiers are down and send the appropriate Down or Up
                if (key.Modifier)
                {
                    if (!Modifiers.Contains(Token))
                    {
                        Modifiers.Add(Token);
                        SendRawInput.SendKeyDown(Token);
                    }
                    else
                    {
                        Modifiers.Remove(Token);
                        SendRawInput.SendKeyUp(Token);
                    }
                }
                else
                {
                    // It's a normal key, just press it
                    // Currently there is a 50ms hardcoded delay; this will be improved later
                    SendRawInput.SendKeyPress(Token, 50);
                }
            }

            // Play default sound
            if (ButtonState[index].SoundEffect == true)
            {
                PlaySound("coinin");
            }
        }