SendInput()和非英文字符和键盘布局

时间:2009-12-28 18:45:50

标签: windows unicode keyboard-events keyboard-layout

在Windows中使用非英语输入键盘语言时,我无法模拟字符按键。

我尝试使用KEYEVENTF_UNICODE调用SendInput():

KEYBDINPUT ki;
INPUT input;
int character = 0;

ki.wVk = 0;
ki.wScan = character;
ki.dwFlags = KEYEVENTF_UNICODE;
ki.time = 0;
ki.dwExtraInfo = 0;   
input.type = INPUT_KEYBOARD;
input.ki = ki;
SendInput(1, &input, sizeof(INPUT));

这实际上是有效的(当然,在我的代码中,我也在键下来之后做了一个KEYUP)......除了在GTK +应用程序中(可能还有其他实例,它也不起作用)。

MSDN如果指定KEYEVENTF_UNICODE,SendInput发送WM_KEYDOWN或WM_KEYUP消息给前台线程的消息队列wParam等于VK_PACKET。 GetMessage或PeekMessage获取此消息后,将消息传递给TranslateMessage会发布带有最初由wScan指定的Unicode字符的WM_CHAR消息。如果将此Unicode字符发布到ANSI窗口,则会自动将其转换为相应的ANSI值。

所以我相信当传递KEYEVENTF_UNICODE时,SendInput()的功能是不同的......不像通常那样低级。

对于我的生活,我无法想出任何其他方法来让SendInput()正确打印出用户键盘语言的字符。例如,如果键盘输入语言是“瑞典语”,我不能让它输出'@'(相反,它打印出一个引号),我不能让它输出非正确的ASCII字符,要么(重音字母等)。

提前致谢。

3 个答案:

答案 0 :(得分:4)

我发现执行此操作的正确方法是通过使用该字符调用VkKeyScanEx()来获取角色的虚拟键代码。返回值的高位字节将告诉您需要“按下”哪些修改键:Control,Alt和/或Shift;低位字节是实际的虚拟键代码。

要获取VK的扫描代码,请致电MapVirtualKeyEx(vkCode, 0);

然后,只需使用刚刚获得的信息进行按键模拟即可。

答案 1 :(得分:1)

据我所知,SendInput()只是对mouse_event()和keybd_event()的调用的一个包装,它保证你的输入不会散布来自用户或其他调用者的输入。

所以我想我的问题是,您是否尝试过使用keybd_event()?

答案 2 :(得分:1)

在.NET中,所有字符串都在内部保存为Unicode(UTF-8)字符串。您可以通过将字符串转换为数组(byte [],NOT char []!)来验证。因此,您可以忽略有关扫描代码,键盘布局和虚拟键码的任何信息。

以下内容适用于C#/ .NET:

string myText = "greekcyrillicjapaneseorwhathaveyou"; // can be input via a Forms textbox

char[] Mychars = myText.ToCharArray();

UInt16 uniCode = chars[5]; // if you want to simulate, say, the sixth' char of the string

...

ki.wScan = unicode

ki.dwFlags = KEYEVENTF_UNICODE;

...