C# 模拟非ASCII字符的输入

C# 模拟非ASCII字符的输入,c#,windows,winapi,windows-7,C#,Windows,Winapi,Windows 7,我正在寻找一种使用Windows API模拟输入非ASCII字符(例如CJK字符)的方法keybd_事件或SendInput将不起作用,因为输入字符可能不是有效的虚拟键 我想要什么 我想使用Windows API模拟Unicode字符的输入,而无需编写IME或TSF提供程序 我试过的 我已尝试将WM\u IME\u CHAR消息发送到当前关注的窗口: // Gets the currently focused input control (if any) internal static IntP

我正在寻找一种使用Windows API模拟输入非ASCII字符(例如CJK字符)的方法
keybd_事件
SendInput
将不起作用,因为输入字符可能不是有效的虚拟键

我想要什么 我想使用Windows API模拟Unicode字符的输入,而无需编写IME或TSF提供程序

我试过的 我已尝试将
WM\u IME\u CHAR
消息发送到当前关注的窗口:

// Gets the currently focused input control (if any)
internal static IntPtr GetActiveWindowControl()
{
    IntPtr activeWin = GetForegroundWindow();
    if (activeWin == IntPtr.Zero)
    {
        return IntPtr.Zero;
    }
    uint threadId = GetWindowThreadProcessId(activeWin, IntPtr.Zero);
    GUITHREADINFO guiThreadInfo = new GUITHREADINFO();
    guiThreadInfo.cbSize = Marshal.SizeOf(guiThreadInfo);
    GetGUIThreadInfo(threadId, ref guiThreadInfo);
    if (guiThreadInfo.hwndFocus == IntPtr.Zero)
    {
        return activeWin; // Example: console
    }
    else
    {
        return guiThreadInfo.hwndFocus;
    }
}

internal void SimulateInput()
{
    // Encoding.Default on my computer is CP950 (Big5)
    byte[] b = Encoding.Default.GetBytes("我"); // one single Chinese character
    IntPtr activeHwnd = GetActiveWindowControl();
    if (activeHwnd != IntPtr.Zero)
    {
        int ch = 0;
        for (int i = 0; i < b.Length; i++) // Assumed b has <=2 elements
        {
            ch = (ch << 8) | b[i];
        }
        uint WM_IME_CHAR = 0x0286;
        SendMessage(activeHwnd, WM_IME_CHAR, (IntPtr)ch, (IntPtr)0)
    }
}

我还在.NET中找到了一个类。在我的应用程序中可以使用它吗?

经过一番搜索后,结果证明
SendInput
实际上可以使用发送Unicode输入

现在我的代码看起来像这样(
inputssender
是我自己的类):

内部静态无效输入字符串(string str)
{
char[]chars=str.ToCharArray();
InputSender.Input[]inputs=新的InputSender.Input[chars.Length*2];
for(int i=0;i
但事实证明这是真的。稍加搜索即可发现问题,但使用较旧版本GTK+的程序仍可能遇到问题。刚刚用Geany试用了最新的GTK+,但Inkscape拒绝解释输入


无论如何,如果我忽略GTK+的问题,使用
SendInput
就足够了(应该比
WM\u IME\u CHAR
更好)。我没有尝试过,因为我不知道怎么做,并且认为这是不可行的。

当你安装中文输入法并在记事本++中输入一个真实字符时会发生什么?它甚至接受你的角色吗?可能您已将文档编码设置为ASCII,但它不会接受非7位字符。@Axarydax它会输入。使用Spy++时,我发现当我使用IME键入时,没有
WM\u IME\u CHAR
消息发送给它,因此发生了一些奇怪的事情。是否有IME发送的消息?@Axarydax我为问题添加了更多信息。我想知道你是否能帮忙?
SendMessage(active, WM_IME_STARTCOMPOSITION, (IntPtr)0, (IntPtr)0);
//SendMessage(active, WM_IME_COMPOSITION, (IntPtr)ch, (IntPtr)0x0800);
SendMessage(active, WM_IME_COMPOSITION, (IntPtr)0xA7DA, (IntPtr)0x0800);
SendMessage(active, WM_IME_NOTIFY, (IntPtr)0x010D, (IntPtr)0);
SendMessage(active, WM_IME_ENDCOMPOSITION, (IntPtr)0, (IntPtr)0);
SendMessage(active, WM_IME_NOTIFY, (IntPtr)0x010E, (IntPtr)0);
internal static void InputString(string str)
{
    char[] chars = str.ToCharArray();
    InputSender.Input[] inputs = new InputSender.Input[chars.Length * 2];

    for (int i = 0; i < chars.Length; i++)
    {
        ushort ch = (ushort)chars[i];
        // Key down
        inputs[i * 2].type = InputSender.InputType.Keyboard;
        inputs[i * 2].ki.wScan = ch;
        inputs[i * 2].ki.dwFlags = InputSender.KeyboardEventFlags.Unicode;
        // Key up
        inputs[i * 2 + 1].type = InputSender.InputType.Keyboard;
        inputs[i * 2 + 1].ki.wScan = ch;
        inputs[i * 2 + 1].ki.dwFlags = InputSender.KeyboardEventFlags.Unicode | InputSender.KeyboardEventFlags.KeyUp;
    }
    InputSender.SendInput(inputs);
}