Winapi - 扩展键盘扫描码

时间:2016-05-01 22:07:40

标签: c windows winapi scancodes

如果我想使用扩展扫描代码(如0xE0 0x1D(右CTRL))来模拟按键,我将如何在C中模拟这样的按键?我尝试用两个SendInput结构调用INPUT,但只有左按CTRL键被“按下”。在具有“twin”(Shift和Alt)的其他键的情况下也会发生同样的事情。

其次,如何为“扩展”键导致键盘事件?

2 个答案:

答案 0 :(得分:3)

KEYBDINPUT结构有一个KEYEVENTF_EXTENDEDKEY标志来处理0xE0字节:

  

如果指定,则扫描代码前面有一个前缀字节,其值为0xE0(224)。

尝试这样的事情:

INPUT inputs[2];
ZeroMemory(inputs, sizeof(inputs));

inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wScan = 0x1D;
inputs[0].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_EXTENDEDKEY;

CopyMemory(&inputs[1], &inputs[0], sizeof(INPUT));
inputs[1].ki.dwFlags |= KEYEVENTF_KEYUP;

SendInput(2, inputs, sizeof(INPUT));

但是,我建议使用虚拟密钥而不是扫描代码:

INPUT inputs[2];
ZeroMemory(inputs, sizeof(inputs));

inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = VK_CONTROL;
inputs[0].ki.dwFlags = KEYEVENTF_EXTENDEDKEY;

CopyMemory(&inputs[1], &inputs[0], sizeof(INPUT));
inputs[1].ki.dwFlags |= KEYEVENTF_KEYUP;

SendInput(2, inputs, sizeof(INPUT));

但是,如果您绝对需要扫描代码,至少要查看MapVirtualKey()将虚拟密钥转换为扫描代码:

inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wScan = MapVirtualKey(VK_RCONTROL, MAPVK_VK_TO_VSC);
inputs[0].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_EXTENDEDKEY;

答案 1 :(得分:-2)

您未指定是将密钥发送到同一应用程序还是其他应用程序。使用SendInput,我们无法指定键的位置。我们必须以某种方式确保窗口处于活动状态并且焦点设置正确。 请注意,SendInput将发送WM_KEYDOWN或WM_KEYUP消息。 如果直接使用SendMesage发送WM_KEYDOWN和WM_KEYUP消息,则可以更灵活。您指定要发送到的窗口的窗口句柄。 窗口句柄用于文本框或带文本的控件,而不是文本框或其他控件所在的窗口。

这是如何确定在SendMessage中使用的确切参数。请注意,SendInput将生成SendMessage。

在Visual Studio中,单击“工具”菜单。你会看到" Spy ++"和"间谍++ x64"。我不确定什么时候我们需要一个或另一个,但如果一个不起作用,那么试试另一个。在Spy ++中,单击Messages菜单,然后单击" Logging Options ..."。在右上角区域中,单击Findor Tool并拖动到窗口。松开鼠标后,单击“消息”选项卡。然后点击"全部清除"然后选中"键盘"的复选框。请注意,“消息”菜单还包含用于启动和停止日志记录的命令,但我认为默认情况下它处于启用状态。转到所选窗口,然后键入要尝试的键。然后查看Spy ++中记录的消息。您将看到发送到窗口或从窗口发送的所有消息。我通常会在拥有所需的所有内容后立即停止日志记录,具体取决于为日志记录选择的消息,可能会记录太多消息。如果您只记录键盘消息,那么您将无法记录太多消息。

对我来说,右侧Ctrl的扩展字段为1,左侧Ctrl为0。