SendInput () doesn't "send" the correct shifted characters?

void WriteChar(char c) { INPUT input = {0}; input.type = INPUT_KEYBOARD; input.ki.wVk= VkKeyScanEx(c, GetKeyboardLayout(0) ) ; SendInput(1,&input, sizeof(INPUT)); } 

VkKeyScanEx returns different key codes for '/' and '?' (same key), however, if you try to use this method to write a message containing "?", it will only write "/". I do not know what's happening. The same thing happens with ';' and ':'.

I partially do not understand the key codes and scan codes. Most characters have a virtual key code, but I can not find something similar for question marks. They must exist, but not indicated?

+6
c ++ winapi sendinput virtual-keyboard
source share
2 answers

Scan codes are raw key identifiers returned from the keyboard. Thus, 101 keyboard keyboards (theoretically) will have 101 unique scan codes that it can return. (see footnote 1)

Virtual key codes are a separate set of codes that represent a key on an idealized keyboard. No matter where on the real keyboard there is a TAB key and which scancode is used for it, the virtual key code is always VK_TAB. windows.h defines VK_xxx codes for non-printable virtual keys, for printable ones, the virtual key code matches the ASCII value.

But virtual key codes are still key codes. "A" and "a" have the same virtual key code, so if you want to send "A", you need to send VK_SHIFT down, then "a" down, then "a" up, then VK_SHIFT up.

VkKeyScanEx() converts a character to a scan key and a shift state. See the quote below http://msdn.microsoft.com/en-us/library/ms646332(VS.85).aspx

If the function succeeds, the low byte of the return value contains the virtual key code, and the high byte contains the shift state, which may be a combination of the following flag bits.

So you cannot just take a return from VkKeyScanEx (), you need to check if the shift flag is checked. and send the shift key as a separate keystroke

 SHORT vk = VkKeyScanEx(c, ...); if (vk & 0x100) // check upper byte for shift flag { // send a shift key down } if (vk & 0x200) // check for ctrl flag { // send a ctrl key down } input.ki.wVk = vk & 0xFF; // send keyup for each of the keydown 

You also need to send a key for each keystroke.

Footnote:

1 This is only theoretically, in practice, standard PC keyboards mimic an old IBM keyboard that you cannot even get, so some keys can return 2 different scan codes based on a different key, while others in other cases, two keys can return the same scan code .

+9
source share

Try to do it like this. If you do this with KEYEVENTF_UNICODE , the host platform must be at least Windows 2000 or XP.

 INPUT input[ 2 ]; input[ 0 ].type = INPUT_KEYBOARD; input[ 0 ].ki.wVk = 0; input[ 0 ].ki.wScan = c; input[ 0 ].ki.dwFlags = KEYEVENTF_UNICODE; input[ 0 ].ki.time = 0; input[ 0 ].ki.dwExtraInfo = GetMessageExtraInfo(); input[ 1 ].type = INPUT_KEYBOARD; input[ 1 ].ki.wVk = 0; input[ 1 ].ki.wScan = c; input[ 1 ].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; input[ 1 ].ki.time = 0; input[ 1 ].ki.dwExtraInfo = GetMessageExtraInfo(); SendInput( ( UINT )2, input, sizeof( *input ) ); 

Judging by the fact that you did not fill out your input structure correctly and left some required members uninitialized, I would assume that you did not see the documentation for this. See SendInput , INPUT, and KEYBDINPUT .

+1
source share

All Articles