SendInput()不是“发送”正确的移位字符?

时间:2010-01-30 07:08:28

标签: c++ winapi virtual-keyboard sendinput scancodes

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

VkKeyScanEx为'/'和'?'(相同的密钥)返回不同的密钥代码,但是如果您尝试使用此方法编写包含'?'的消息,则只会写'/'。我不知道发生了什么事。同样的事情发生在';'和':'。

我部分不了解密钥代码和扫描代码。大多数角色都有虚拟键码,但我找不到类似问号的东西。它们必须存在,但没有列出?

2 个答案:

答案 0 :(得分:9)

扫描码是键盘返回的原始键ID。因此,101键键盘(理论上)将具有101个可以返回的唯一扫描码。 (见脚注 1

虚拟键码是一组独立的代码,代表理想键盘上的键。无论在真正的键盘上TAB键是什么,以及使用了什么扫描码,虚拟键码始终是VK_TAB。 windows.h为不可打印的虚拟键定义VK_xxx代码,对于可打印的虚拟键,虚拟键代码与ASCII值相同。

但虚拟键码仍然是键码。 'A'和'a'具有相同的虚拟键码,因此如果你想发送'A',那么你必须向下发送VK_SHIFT,然后'a'向下,然后'a'向上,然后向上发送VK_SHIFT。

VkKeyScanEx()将字符转换为扫描键并转换状态请参阅此页面中的引用http://msdn.microsoft.com/en-us/library/ms646332(VS.85).aspx

  

如果函数成功,返回值的低位字节包含虚拟键代码,高位字节包含移位状态,可以是以下标志位的组合。

所以你不能只从VkKeyScanEx()获取返回,你需要检查它是否有标记的shift键。并将shift键作为单独的击键

发送
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

你还必须为每个keydown发送一个keyup。

脚注:

1 这在理论上是唯一的,在实践中,标准PC键盘模拟了一个你甚至无法获得的旧IBM键盘,因此一些键可以根据另一个键返回2个不同的扫描码,而在其他情况下,其他两个键可以返回相同的扫描码。

答案 1 :(得分:1)

尝试这样做。如果使用KEYEVENTF_UNICODE执行此操作,则主机平台必须至少为Windows 2000或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 ) );

从你没有正确填写你的输入结构并留下一些未经初始化的必要成员的事实判断,我认为你还没有看到这方面的文档。请参阅SendInputINPUTKEYBDINPUT