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

000*_*000 5 windows unicode keyboard-layout keyboard-events

在 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));
Run Code Online (Sandbox Code Playgroud)

这实际上有效(当然,在我的代码中,我也在按下键后执行 KEYUP)...除了在 GTK+ 应用程序中(可能还有其他情况下它也不起作用)。

根据MSDN如果指定了 KEYEVENTF_UNICODE,SendInput 将 WM_KEYDOWN 或 WM_KEYUP 消息发送到前台线程的消息队列,wParam 等于 VK_PACKET。一旦 GetMessage 或 PeekMessage 获得此消息,将消息传递给 TranslateMessage 会发布一条 WM_CHAR 消息,其中包含最初由 wScan 指定的 Unicode 字符。如果将这个 Unicode 字符发送到 ANSI 窗口,它将自动转换为适当的 ANSI 值。

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

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

提前致谢。

000*_*000 4

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

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

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