private static void CharToKeyboardInput(char c, ref WinApi.INPUT input) { input.type = WinApi.INPUT_KEYBOARD; input.union.keyboard.wVk = 0; input.union.keyboard.wScan = c; input.union.keyboard.dwFlags = WinApi.KEYEVENTF_UNICODE; input.union.keyboard.time = 0; input.union.keyboard.dwExtraInfo = UIntPtr.Zero; }
public static async Task <bool> FeedTextAsync(string text, CancellationToken token) { await s_asyncLock.WaitAsync(token); try { var foregroundWindow = WinApi.GetForegroundWindow(); WinApi.BlockInput(true); try { var size = Marshal.SizeOf <WinApi.INPUT>(); var input = new WinApi.INPUT[1]; // feed each character individually and asynchronously foreach (var c in text) { token.ThrowIfCancellationRequested(); if (WinApi.GetForegroundWindow() != foregroundWindow || IsAnyKeyPressed()) { break; } if (c == '\n' || c == '\r') { // we need this for correctly handling line breaks // when pasting into Chromium's <textarea> SimulateKeyDown(WinApi.VK_RETURN); SimulateKeyUp(WinApi.VK_RETURN); } else { CharToKeyboardInput(c, ref input[0]); if (WinApi.SendInput((uint)input.Length, input, size) == 0) { break; } } if (InputHelpers.AnyInputMessage(WinApi.QS_ALLINPUT)) { await InputHelpers.TimerYield(token : token); } } return(true); } finally { WinApi.BlockInput(false); } } finally { s_asyncLock.Release(); } }
public static async Task <bool> FeedTextAsync(string text, CancellationToken token) { await s_asyncLock.WaitAsync(token); try { var foregroundWindow = WinApi.GetForegroundWindow(); WinApi.BlockInput(true); try { var size = Marshal.SizeOf <WinApi.INPUT>(); var input = new WinApi.INPUT[1]; // feed each character individually and asynchronously foreach (var c in text) { token.ThrowIfCancellationRequested(); if (WinApi.GetForegroundWindow() != foregroundWindow || IsAnyKeyPressed()) { break; } CharToKeyboardInput(c, ref input[0]); if (WinApi.SendInput((uint)input.Length, input, size) == 0) { break; } if (InputHelpers.AnyInputMessage(WinApi.QS_ALLINPUT)) { await InputHelpers.TimerYield(token : token); } } return(true); } finally { WinApi.BlockInput(false); } } finally { s_asyncLock.Release(); } }