5

在 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 会发布一条 WM_CHAR 消息,该消息具有最初由 wScan 指定的 Unicode 字符。如果将此 Unicode 字符发布到 ANSI 窗口,它将自动转换为适当的 ANSI 值。

所以我相信当 KEYEVENTF_UNICODE 被传递时,SendInput() 的功能就不同了……不像平时那么低级。

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

提前致谢。

4

3 回答 3

4

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

要获取 VK 的扫描码,请调用MapVirtualKeyEx(vkCode, 0);

然后就是用刚刚得到的信息做按键模拟。

于 2009-12-28T23:48:50.477 回答
1

据我了解,SendInput() 只是对 mouse_event() 和 keybd_event() 调用的包装,它保证您的输入不会与来自用户或其他调用者的输入穿插。

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

于 2009-12-28T19:00:17.377 回答
1

在 .NET 中,所有字符串在内部都保存为 Unicode (UTF-8) 字符串。您可以通过将字符串转换为数组来验证这一点(byte[],而不是 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;

...

于 2010-01-10T12:01:52.257 回答