SendInput() and non-English characters and keyboard layouts

天涯浪子 提交于 2019-12-07 09:23:21

问题


I'm having trouble simulating character keypresses when a non-English input keyboard language is being used in Windows.

I tried calling SendInput() with KEYEVENTF_UNICODE:

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));

And this actually works (of course, in my code, I also do a KEYUP after the key down)... except in GTK+ apps (there may be other instances where it doesn't work either).

According to MSDN, If KEYEVENTF_UNICODE is specified, SendInput sends a WM_KEYDOWN or WM_KEYUP message to the foreground thread's message queue with wParam equal to VK_PACKET. Once GetMessage or PeekMessage obtains this message, passing the message to TranslateMessage posts a WM_CHAR message with the Unicode character originally specified by wScan. This Unicode character will automatically be converted to the appropriate ANSI value if it is posted to an ANSI window.

So I believe that when KEYEVENTF_UNICODE is passed, the functionality of SendInput() is different... not as low-level as it usually is.

For the life of me, I can't figure out any other way to get SendInput() to print out characters properly for the user's keyboard language. For example, if the keyboard input language is "Swedish", I can't get it to output '@' (instead, it prints out a quotation mark), and I can't get it to output non-ASCII characters properly, either (accented letters, etc).

Thanks in advance.


回答1:


I discovered that the proper way to do this is to get the virtual-key code of the character by calling VkKeyScanEx() with the character. The high-order bytes of the return value will tell you which modifier keys you need to "press": Control, Alt, and/or Shift; the low-order bytes are the actual virtual-key code.

To get the scan code of the VK, call MapVirtualKeyEx(vkCode, 0);

Then it's just a matter of doing the keypress simulation with the information just obtained.




回答2:


As I understand it SendInput() is just a wrapper around calls to mouse_event() and keybd_event() that gurantees that your input doesn't get interspersed with input from the user or other callers.

So I guess the question I have is, have you tried using keybd_event()?




回答3:


In .NET all strings are kept as Unicode (UTF-8) strings, internally. You can verify that by converting a string to an array (byte[], NOT char[]!). So you can just ignore anything about scan codes, keyboard layouts and virtual keycodes.

The following works for me in 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;

...



来源:https://stackoverflow.com/questions/1970917/sendinput-and-non-english-characters-and-keyboard-layouts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!