C# 模拟非ASCII字符的输入
我正在寻找一种使用Windows API模拟输入非ASCII字符(例如CJK字符)的方法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
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);
}