开发者

SendInput() isn't "sending" 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 differ开发者_如何学Cent key codes for '/' and '?'(same key), however if you try using this method to write a message containing '?', it will only write '/'. I don't know what's going on. Same thing occurs with ';' and ':'.

I partly don't understand key codes and scan codes. Most characters have a virtual key code, however I can't find something similar for question marks. They must exist, but aren't listed?


Scan codes are the raw key ids returned from the keyboard. So a 101 key keyboard will (in theory) have 101 unique scan codes that it can return. (see footnote 1)

Virtual key codes are a separate set of codes that represent an key on an idealized keyboard. No matter where on a real keyboard the TAB key is, and what 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 the printable ones, the virtual key code is the same as 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 an 'A' then you have to send a VK_SHIFT down, then 'a' down, then 'a' up, then VK_SHIFT up.

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

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

So you can't just take the return from VkKeyScanEx(), you need to check to see if it has a shift key flagged. 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 have to send a keyup for every keydown.

Footnotes:

1 This is in theory only, in practice standard PC keyboards emulate a old IBM keyboard that you can't even get anymore, so some keys can return 2 different scan codes based on another key, while other in other cases two keys can return the same scan code.


Try doing it like this. If you do it using KEYEVENTF_UNICODE, the host platform will need to 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 from the fact that you didn't fill out your input structure correctly and left some required members uninitialised, I'd assume you haven't seen the documentation for this. See SendInput, INPUT and KEYBDINPUT.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜