SendInput () and non-English characters and keyboard layouts

I'm having trouble simulating character clicks when Windows uses a non-English input language.

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 it really works (of course, in my code, I also do KEYUP after pressing the key) ... except for GTK + applications (there may be other instances in which it also does not work).

According to MSDN , if KEYEVENTF_UNICODE is specified, SendInput sends a WM_KEYDOWN or WM_KEYUP message to the foreground thread message queue with wParam equal to VK_PACKET. When GetMessage or PeekMessage receives this message, sending the message to TranslateMessage sends a WM_CHAR message with the Unicode character originally specified by wScan. This Unicode character will be automatically converted to the corresponding ANSI value if it is sent to the ANSI window.

Therefore, I believe that when KEYEVENTF_UNICODE is passed, the functionality of SendInput () is different ... not as low as usual.

Throughout my life, I cannot find another way to get SendInput () to correctly print characters for the user's keyboard language. For example, if the input language on the keyboard is "Swedish", I cannot force it to display "@" (instead it prints a quotation mark), and I cannot force it to output characters other than ASCII, either (letters with an accent, etc. .).

Thanks in advance.

+4
source share
3 answers

I found that the correct way to do this is to get a virtual symbol key code of the symbol by calling VkKeyScanEx() with the symbol. The top-order byte of the return value will tell you which modifier keys you need to "press": "Control", "Alt" and / or "Shift"; lower order bytes are the actual virtual key code.

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

Then it's just a matter of simulating a keystroke with the information just received.

+4
source

As I understand it, SendInput () is just a wrapper around the mouse_event () and keybd_event () calls, which ensures that your input will not be interleaved by input from the user or other callers.

So, I think I have a question: have you tried using keybd_event ()?

+1
source

In .NET, all strings are stored as Unicode strings (UTF-8) internally. You can make sure the conversion of the string to an array (byte [], NOT char []!). That way, you can simply ignore anything about scan codes, keyboard layouts, and virtual keyboard codes.

In C # /. NET, the following works:

 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; 

...

+1
source

All Articles