You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinForms中SendKeys.Send能否用AltGr修饰符替代左Alt键?

WinForms模拟输入:AltGr键替代左Alt的解决方案

问题背景

我正在编写一个简易WinForms程序,从文本框获取文本后,使用SendKeys.Send方法逐个字符模拟输入。目前遇到的问题是,代表Alt键的修饰符%对应的是左Alt键而非AltGr键,导致无法输入通过AltGr组合键生成的字符。

比如在匈牙利键盘布局下,输入{时,代码里用%b,但聚焦记事本时会触发加粗字体样式,而非输入目标字符。

相关代码如下:

private void startButton_Click(object sender, EventArgs e)
{
    Thread.Sleep(3000);

    for (int i=0; i<toType.Text.Length; i++)
    {
        SendKeys.Send(charToKeystroke(toType.Text[i]));
        Thread.Sleep(150);
    }
}

string characters = ".-,";

private string charToKeystroke(char c)
{
    string stroke = "";

    if ((char.IsLetter(c) && !char.IsUpper(c)) || char.IsDigit(c) || characters.Contains(c))
    {
        return "" + c;
    }
    else if (char.IsLetter(c) && char.IsUpper(c))
    {
        return "+"+(c+"").ToLower();
    }
    else
    {
        switch (c)
        {
            case '(':
                return "+8";
            case ')':
                return "+9";
            case '{':
                return "%b";
            case '}':
                return "%n";
            case '[':
                return "%f";
            case ']':
                return "%g";
            case ';':
                return "%,";
            case '<':
                return "%í";
            case '>':
                return "%y";
            case '=':
                return "+7";
            case '!':
                return "+4";
            case '$':
                return "%é";
            case '\n':
                return "{ENTER}";
            case '\t':
                return "{TAB}";
            case '+':
                return "{PLUS}";
            case '-':
                return "{MINUS}";
            case '/':
                return "{DIVIDE}";
            case '*':
                return "{MULTIPLY}";
            case '&':
                return "%c";
            case '\'':
                return "+1";
            case '"':
                return "+2";
            case '|':
                return "%w";
            case ':':
                return "+.";
            case '#':
                return "%x";
            case '@':
                return "%v";
            case ' ':
                return "{SPACE}";
        }
    }

    return stroke;
}

可行方案

方案1:用Windows API的SendInput精确模拟AltGr

AltGr本质是左Ctrl + 右Alt的组合键,SendKeys不支持直接指定右Alt,因此改用SendInput函数可以精准控制按键:

  1. 首先引入必要的API声明:
using System.Runtime.InteropServices;

[DllImport("user32.dll", SetLastError = true)]
private static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);

[StructLayout(LayoutKind.Sequential)]
private struct INPUT
{
    public uint type;
    public InputUnion u;
}

[StructLayout(LayoutKind.Explicit)]
private struct InputUnion
{
    [FieldOffset(0)] public MOUSEINPUT mi;
    [FieldOffset(0)] public KEYBDINPUT ki;
    [FieldOffset(0)] public HARDWAREINPUT hi;
}

[StructLayout(LayoutKind.Sequential)]
private struct KEYBDINPUT
{
    public ushort wVk;
    public ushort wScan;
    public uint dwFlags;
    public uint time;
    public IntPtr dwExtraInfo;
}

[StructLayout(LayoutKind.Sequential)]
private struct MOUSEINPUT { /* 无需实现,仅用于结构体占位 */ }

[StructLayout(LayoutKind.Sequential)]
private struct HARDWAREINPUT { /* 无需实现,仅用于结构体占位 */ }

private const uint INPUT_KEYBOARD = 1;
private const uint KEYEVENTF_KEYUP = 0x0002;
private const ushort VK_RMENU = 0xA5; // 右Alt的虚拟键码
private const ushort VK_LCONTROL = 0xA2; // 左Ctrl的虚拟键码
  1. 编写模拟AltGr+按键的方法:
private void SendAltGrChar(ushort keyCode)
{
    // 构建按下左Ctrl、右Alt、目标键的输入事件
    INPUT[] pressInputs = new INPUT[3];
    pressInputs[0].type = INPUT_KEYBOARD;
    pressInputs[0].u.ki.wVk = VK_LCONTROL;

    pressInputs[1].type = INPUT_KEYBOARD;
    pressInputs[1].u.ki.wVk = VK_RMENU;

    pressInputs[2].type = INPUT_KEYBOARD;
    pressInputs[2].u.ki.wVk = keyCode;

    SendInput(3, pressInputs, Marshal.SizeOf(typeof(INPUT)));
    Thread.Sleep(10); // 短暂延迟确保按键生效

    // 构建释放所有按键的输入事件
    INPUT[] releaseInputs = new INPUT[3];
    releaseInputs[0].type = INPUT_KEYBOARD;
    releaseInputs[0].u.ki.wVk = keyCode;
    releaseInputs[0].u.ki.dwFlags = KEYEVENTF_KEYUP;

    releaseInputs[1].type = INPUT_KEYBOARD;
    releaseInputs[1].u.ki.wVk = VK_RMENU;
    releaseInputs[1].u.ki.dwFlags = KEYEVENTF_KEYUP;

    releaseInputs[2].type = INPUT_KEYBOARD;
    releaseInputs[2].u.ki.wVk = VK_LCONTROL;
    releaseInputs[2].u.ki.dwFlags = KEYEVENTF_KEYUP;

    SendInput(3, releaseInputs, Marshal.SizeOf(typeof(INPUT)));
}
  1. 修改原逻辑,替换%相关的调用:
    比如处理{时,不再返回%b,而是直接调用SendAltGrChar((ushort)Keys.B),同时调整循环逻辑:
private void startButton_Click(object sender, EventArgs e)
{
    Thread.Sleep(3000);

    for (int i=0; i<toType.Text.Length; i++)
    {
        char c = toType.Text[i];
        if (IsAltGrChar(c)) // 自定义方法判断是否需要AltGr输入
        {
            ushort keyCode = GetAltGrKeyCode(c); // 映射字符到对应按键码
            SendAltGrChar(keyCode);
        }
        else
        {
            SendKeys.Send(charToKeystroke(c));
        }
        Thread.Sleep(150);
    }
}

// 示例映射,根据匈牙利键盘布局调整
private bool IsAltGrChar(char c)
{
    return new[] {'{', '}', '[', ']', ';', '<', '>', '$', '&', '#', '@', '|'}.Contains(c);
}

private ushort GetAltGrKeyCode(char c)
{
    return c switch
    {
        '{' => (ushort)Keys.B,
        '}' => (ushort)Keys.N,
        '[' => (ushort)Keys.F,
        ']' => (ushort)Keys.G,
        ';' => (ushort)Keys.Oemcomma,
        '<' => (ushort)Keys.Oemtilde, // 根据实际键盘布局调整
        '>' => (ushort)Keys.Y,
        '$' => (ushort)Keys.Oemtilde,
        '&' => (ushort)Keys.C,
        '#' => (ushort)Keys.X,
        '@' => (ushort)Keys.V,
        '|' => (ushort)Keys.W,
        _ => 0
    };
}

方案2:直接发送Unicode字符(简单场景适用)

如果不需要模拟真实按键流程,只是要输入目标字符,可以直接发送Unicode值,绕过AltGr组合键:

修改charToKeystroke方法中特殊字符的返回值,比如:

case '{':
    return "{{" + ((int)'{').ToString() + "}}"; // 注意转义大括号,SendKeys中用{数字}表示Unicode字符
case '}':
    return "{{" + ((int)'}').ToString() + "}}";

或者直接在循环中处理:

SendKeys.SendWait("{{" + ((int)c).ToString() + "}}");

这个方法无需调用API,但对部分系统或应用的兼容性可能不如SendInput。


内容的提问来源于stack exchange,提问作者Zoltán Király

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 13:12:44