public static void PressKeys(string keys, KeyPressMode mode) { var specialKeys = ")!@#$%^&*("; foreach (var key in keys) { var isSpecialCharOrUpper = specialKeys.Contains(key.ToString()) | char.IsUpper(key); switch (mode) { case KeyPressMode.KBDEVENT: KeybdSendKey(key.ToString(), isSpecialCharOrUpper); break; case KeyPressMode.SENDINPUT: if (isSpecialCharOrUpper) { SendShift(true); SendKey(key.ToString()); SendShift(false); } else { SendKey(key.ToString()); } break; } } }
// understand keycore - see above public static string KeyCore(Queue <SKEvent> events, ref string s, int defdelay, int defshiftdelay, int defupdelay, int d1, int d2, int d3, KeyPressMode kmd) { Keys shift = KeyObjectExtensions.IsShiftPrefix(ref s); Keys ctrl = Keys.None; Keys alt = Keys.None; if (shift == Keys.None || s.StartsWith("+")) { s = s.Skip("+"); alt = KeyObjectExtensions.IsAltPrefix(ref s); if (alt == Keys.None || s.StartsWith("+")) { s = s.Skip("+"); ctrl = KeyObjectExtensions.IsCtrlPrefix(ref s); if (ctrl != Keys.None) { s = s.Skip("+"); } } } bool vkeyspresent = s.Length > 0 && s[0] != ' '; bool shiftpresent = shift != Keys.None || ctrl != Keys.None || alt != Keys.None; // keydown is d1 or def int keydowndelay = (d1 != -1) ? d1 : defdelay; // if mainpart present, its d2 or defshift. If no main part, its d1 or def shift int shiftdelay = (vkeyspresent) ? (d2 != -1 ? d2 : defshiftdelay) : (d1 != -1 ? d1 : defshiftdelay); // if in up/down mode, its d1 or def up. If its got shift and vkeys, its d3/defup. else its d2/defup int keyupdelay = (kmd == KeyPressMode.Up || kmd == KeyPressMode.Down) ? (d1 != -1 ? d1 : defupdelay) : ((shiftpresent && vkeyspresent) ? (d3 != -1 ? d3 : defupdelay) : (d2 != -1 ? d2 : defupdelay)); if (shift != Keys.None) // we already run shift keys here. If we are doing UP, we send a up, else we are doing down/press { events.Enqueue(new SKEvent(kmd == KeyPressMode.Up ? BaseUtils.Win32Constants.WM.KEYUP : BaseUtils.Win32Constants.WM.KEYDOWN, shift, shiftdelay)); } if (ctrl != Keys.None) { events.Enqueue(new SKEvent(kmd == KeyPressMode.Up ? BaseUtils.Win32Constants.WM.KEYUP : BaseUtils.Win32Constants.WM.KEYDOWN, ctrl, shiftdelay)); } if (alt != Keys.None) { events.Enqueue(new SKEvent(kmd == KeyPressMode.Up ? BaseUtils.Win32Constants.WM.SYSKEYUP : BaseUtils.Win32Constants.WM.SYSKEYDOWN, alt, shiftdelay)); } if (vkeyspresent) { if (s.Length == 0) { return("Invalid no characters after shifters"); } bool brackets = ObjectExtensionsStrings.IsPrefixRemove(ref s, "("); while (s.Length > 0) { string word = ObjectExtensionsStrings.FirstWord(ref s, new char[] { ' ', ')' }); Keys key = word.ToVkey(); if (key != Keys.None) { AddMsgsForVK(events, key, alt != Keys.None && ctrl == Keys.None, keydowndelay, keyupdelay, kmd); //System.Diagnostics.Debug.WriteLine(shift + " " + alt + " " + ctrl + " press " + key.VKeyToString()); } else { while (word.Length > 0) { string ch = new string(word[0], 1); key = ch.ToVkey(); if (key.IsSingleCharName()) { AddMsgsForVK(events, key, alt != Keys.None && ctrl == Keys.None, keydowndelay, keyupdelay, kmd); //System.Diagnostics.Debug.WriteLine(shift + " " + alt + " " + ctrl + " press " + key.VKeyToString()); word = word.Substring(1); } else { return("Invalid key " + word); } } } if (!brackets) { break; } else if (s.Length > 0 && s[0] == ')') { s = s.Substring(1); break; } } } if (kmd == KeyPressMode.Press) // only on a press do we release here { if (alt != Keys.None) { events.Enqueue(new SKEvent(BaseUtils.Win32Constants.WM.SYSKEYUP, alt, keyupdelay)); } if (ctrl != Keys.None) { events.Enqueue(new SKEvent(BaseUtils.Win32Constants.WM.KEYUP, ctrl, keyupdelay)); } if (shift != Keys.None) { events.Enqueue(new SKEvent(BaseUtils.Win32Constants.WM.KEYUP, shift, keyupdelay)); } } s = s.Trim(); if (s.Length > 0 && s[0] == ',') // comma can be used between key groups { s = s.Substring(1).TrimStart(); } return(""); }
private static void AddMsgsForVK(Queue <SKEvent> events, Keys vk, bool altnoctrldown, int downdel, int updel, KeyPressMode kmd) { if (kmd == KeyPressMode.Press || kmd == KeyPressMode.Down) { events.Enqueue(new SKEvent(altnoctrldown ? BaseUtils.Win32Constants.WM.SYSKEYDOWN : BaseUtils.Win32Constants.WM.KEYDOWN, vk, downdel)); } if (kmd == KeyPressMode.Press || kmd == KeyPressMode.Up) { events.Enqueue(new SKEvent(BaseUtils.Win32Constants.WM.KEYUP, vk, updel)); // key up has a short nominal delay } }
// understand parsekeys above public static string ParseKeys(Queue <SKEvent> events, string s, int defdelay, int defshiftdelay, int defupdelay, IAdditionalKeyParser additionalkeyparser = null, int d1def = -1, int d2def = -1, int d3def = -1, KeyPressMode kmddef = KeyPressMode.Press) { s = s.Trim(); while (s.Length > 0) { int d1 = d1def; // reset dx's to their default values int d2 = d2def; int d3 = d3def; if (s.Length >= 1 && s[0] == '[') { if (!s.Contains(']')) { return("Missing closing ] in delay"); } s = s.Substring(1); string word = ObjectExtensionsStrings.FirstWord(ref s, new char[] { ']', ',' }); if (!word.InvariantParse(out d1)) { return("Delay not properly given"); } if (s.Length >= 1 && s[0] == ',') { s = s.Substring(1); word = ObjectExtensionsStrings.FirstWord(ref s, new char[] { ']', ',' }); if (!word.InvariantParse(out d2)) { return("Second Delay not properly given"); } } if (s.Length >= 1 && s[0] == ',') { s = s.Substring(1); word = ObjectExtensionsStrings.FirstWord(ref s, new char[] { ']' }); if (!word.InvariantParse(out d3)) { return("Third Delay not properly given"); } } if (s.Length >= 1 && s[0] == ']') { s = s.Substring(1); } else { return("Missing closing ] in delay"); } } int repeat = 1; // repeat is always 1 - it does not carry down the tree if (s.Length >= 1 && s[0] == '#') { s = s.Substring(1); var r = ObjectExtensionsNumbersBool.ReadDecimalInt(ref s); if (r == null || r < 1) { return("Missing/Invalid decimal count after #"); } s = s.TrimStart(); repeat = r.Value; } KeyPressMode kmd = kmddef; // set keymode to its default. if (s[0] == '^' || s[0] == '<') { kmd = KeyPressMode.Up; s = s.Substring(1); } else if (s[0] == '!' || s[0] == '>') { kmd = KeyPressMode.Down; s = s.Substring(1); } else if (s[0] == '&') { kmd = KeyPressMode.Press; s = s.Substring(1); } string repeatarea = s; // keep it pristine for repeats for (int rpc = 0; rpc < repeat; rpc++) // and repeat.. { s = repeatarea; var replace = additionalkeyparser?.Parse(ref s) ?? null; // try a replace if (replace != null) // if found { if (replace.Item2.HasChars()) // report errors { return(replace.Item2); } // recurse in. note no additionalparser so no recursion below, and pass in the collected dx and kmd values to the level down string res = ParseKeys(events, replace.Item1, defdelay, defshiftdelay, defupdelay, null, d1, d2, d3, kmd); if (res.HasChars()) { return(res); } } else { string res = KeyCore(events, ref s, defdelay, defshiftdelay, defupdelay, d1, d2, d3, kmd); // key core processing with these values if (res.HasChars()) { return(res); } } } } //foreach (BaseUtils.EnhancedSendKeysParser.SKEvent x in events) System.Diagnostics.Debug.WriteLine($"Event {x.wm} {x.sc} {x.vkey} {x.delay}"); return(""); }