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.
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.
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()?
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