first commit
This commit is contained in:
commit
761b95080f
404 files changed
+312608
No files matched your search
@@ -0,0 +1,88 @@
|
||||
using anjianjingling.Common;
|
||||
using anjianjingling.Native;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace anjianjingling.Input
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统级键盘模拟(SendInput):单键、组合键、Unicode 文本。
|
||||
/// </summary>
|
||||
public sealed class KeyboardInput
|
||||
{
|
||||
private static void SendKey(Win32.KEYBDINPUT ki)
|
||||
{
|
||||
var input = new Win32.INPUT
|
||||
{
|
||||
type = Win32.INPUT_KEYBOARD,
|
||||
u = new Win32.INPUTUNION { ki = ki }
|
||||
};
|
||||
Win32.SendInput(1, new[] { input }, Marshal.SizeOf<Win32.INPUT>());
|
||||
}
|
||||
|
||||
/// <summary>发送一次按键(按下并弹起)。</summary>
|
||||
public void KeyPress(string keyName)
|
||||
{
|
||||
ushort vk = ResolveOrThrow(keyName);
|
||||
KeyDownVk(vk);
|
||||
Thread.Sleep(30);
|
||||
KeyUpVk(vk);
|
||||
}
|
||||
|
||||
public void KeyDown(string keyName) => KeyDownVk(ResolveOrThrow(keyName));
|
||||
|
||||
public void KeyUp(string keyName) => KeyUpVk(ResolveOrThrow(keyName));
|
||||
|
||||
private static void KeyDownVk(ushort vk)
|
||||
{
|
||||
ushort scan = (ushort)Win32.MapVirtualKey(vk, Win32.MAPVK_VK_TO_VSC);
|
||||
uint flags = Win32.KEYEVENTF_SCANCODE;
|
||||
if (VirtualKeys.IsExtended(vk)) flags |= Win32.KEYEVENTF_EXTENDEDKEY;
|
||||
SendKey(new Win32.KEYBDINPUT { wVk = vk, wScan = scan, dwFlags = flags });
|
||||
}
|
||||
|
||||
private static void KeyUpVk(ushort vk)
|
||||
{
|
||||
ushort scan = (ushort)Win32.MapVirtualKey(vk, Win32.MAPVK_VK_TO_VSC);
|
||||
uint flags = Win32.KEYEVENTF_SCANCODE | Win32.KEYEVENTF_KEYUP;
|
||||
if (VirtualKeys.IsExtended(vk)) flags |= Win32.KEYEVENTF_EXTENDEDKEY;
|
||||
SendKey(new Win32.KEYBDINPUT { wVk = vk, wScan = scan, dwFlags = flags });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 组合键,如 "Ctrl+A"、"Ctrl+Shift+Esc":修饰键依次按下,主键按下弹起,修饰键逆序弹起。
|
||||
/// </summary>
|
||||
public void HotKey(string expression)
|
||||
{
|
||||
var parts = expression.Split('+', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 0) throw new ArgumentException($"无法解析组合键:{expression}");
|
||||
|
||||
var vks = parts.Select(ResolveOrThrow).ToArray();
|
||||
for (int i = 0; i < vks.Length - 1; i++) KeyDownVk(vks[i]);
|
||||
Thread.Sleep(40);
|
||||
KeyDownVk(vks[^1]);
|
||||
Thread.Sleep(40);
|
||||
KeyUpVk(vks[^1]);
|
||||
for (int i = vks.Length - 2; i >= 0; i--)
|
||||
{
|
||||
Thread.Sleep(20);
|
||||
KeyUpVk(vks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 输入整段文本(含中文),使用 KEYEVENTF_UNICODE,不依赖键盘布局。
|
||||
/// </summary>
|
||||
public void TypeText(string text)
|
||||
{
|
||||
foreach (char c in text)
|
||||
{
|
||||
SendKey(new Win32.KEYBDINPUT { wScan = c, dwFlags = Win32.KEYEVENTF_UNICODE });
|
||||
SendKey(new Win32.KEYBDINPUT { wScan = c, dwFlags = Win32.KEYEVENTF_UNICODE | Win32.KEYEVENTF_KEYUP });
|
||||
}
|
||||
}
|
||||
|
||||
private static ushort ResolveOrThrow(string name)
|
||||
=> VirtualKeys.Resolve(name)
|
||||
?? throw new ArgumentException($"未知按键名:\"{name}\"(可用如 A、F5、ENTER、SPACE、方向键等)");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user