//Adds key or other event. Calls _ModUp(). Not used fo sleep and repeat. AKeys _AddKey(_KEvent e) { _AddModUp(); _pstate.plus = false; _a.Add(e); return(this); }
unsafe void _SendText(_KEvent ke) { string s = _GetData(ke.data) as string; var opt = _GetOptionsAndWndFocused(out var wFocus, true); var textOption = opt.TextOption; if (s.Length >= opt.PasteLength) textOption = KTextOption.Paste; }
unsafe void _SendKey(_KEvent k, int i) { bool needScanCode = k.scan == 0 && !k.SIFlags.HasAny(_KFlags.Scancode | _KFlags.Unicode); var opt = _GetOptionsAndWndFocused(out var wFocus, needScanCode); if (needScanCode) { var hkl = Api.GetKeyboardLayout(wFocus.ThreadId); //most layouts have the same standard scancodes, but eg dvorak different k.scan = Internal_.VkToSc(k.vk, hkl); } bool isLast = i == _a.Count - 1; _SendKey2(k, isLast ? default : _a[i + 1], isLast, opt); }
//Caller should set k.scan; this func doesn't. unsafe static void _SendKey2(_KEvent k, _KEvent kNext, bool isLast, OptKey opt) { var ki = new Api.INPUTK(k.vk, k.scan, (uint)k.SIFlags); int count = 1, sleep = opt.KeySpeed; if (isLast) { if (!k.IsPair) { sleep = Internal_.LimitSleepTime(sleep) - opt.SleepFinally; } } else { if (kNext.IsRepeat) { count = kNext.repeat; } else if (!k.IsPair) { //If this is pair, sleep between down and up, and don't sleep after up. //Else if repeat, sleep always. //Else in most cases don't need to sleep. In some cases need, but can limit the time. // For example, in Ctrl+C normally would not need to sleep after Ctrl down and Ctrl up. // However some apps/controls then may not work. Maybe they process mod and nonmod keys somehow async. // For example, Ctrl+C in IE address bar often does not work if there is no sleep after Ctrl down. Always works if 1 ms. sleep = Internal_.LimitSleepTime(sleep); if (kNext.IsKey) { bool thisMod = KeyTypes_.IsMod(k.vk), nextMod = KeyTypes_.IsMod(kNext.vk); if (!k.IsUp) { if (kNext.IsUp) { sleep = opt.KeySpeed; } else if (thisMod == nextMod) { sleep = 0; } } else { if (!thisMod || nextMod) { sleep = 0; } } } else if (kNext.IsSleep) { sleep = sleep - kNext.sleep; } } } if (sleep < 0) { sleep = 0; } //var s = (k.vk).ToString(); //if(k.IsPair) AOutput.Write($"{s}<{sleep}>"); //else { var ud = k.IsUp ? '-' : '+'; if(sleep > 0) AOutput.Write($"{s}{ud} {sleep}"); else AOutput.Write($"{s}{ud}"); } for (int r = 0; r < count; r++) { //APerf.First(); Api.SendInput(&ki); //APerf.Next(); if (sleep > 0) { Internal_.Sleep(sleep); } if (k.IsPair) { ki.dwFlags |= Api.KEYEVENTF_KEYUP; Api.SendInput(&ki); ki.dwFlags &= ~Api.KEYEVENTF_KEYUP; } //APerf.NW(); //speed: min 400 mcs for each event. Often > 1000. Does not depend on whether all events sent by single SendInput call. } }
/// <summary> /// Sends Enter. /// </summary> public static void Enter(OptKey opt) { var e = new _KEvent(true, KKey.Enter, 0, 0x1C); _SendKey2(e, default, true, opt);