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

Ale*_*kov 7 c++ winapi scancodes virtual-keyboard sendinput

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

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

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

Joh*_*ler 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
Run Code Online (Sandbox Code Playgroud)

您还必须为每个keydown发送一个keyup.

脚注:

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


Sam*_*Sam 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 ) );
Run Code Online (Sandbox Code Playgroud)

从您没有正确填写输入结构并且未初始化一些必需的成员这一事实来看,我假设您还没有看到这方面的文档。请参阅SendInputINPUTKEYBDINPUT