SendInput不适用于Print Screen键

时间:2018-01-24 12:06:27

标签: c++ windows winapi

我为各种模拟器制作前端并触发各种功能,例如保存/加载状态,保存屏幕截图,但使用统一界面。 FS-UAE恼人地使用" Print Screen"作为截图密钥,我希望避免用户必须从默认的热键设置中更改模拟器。

我设法用SendInput模拟我想要的任何按键,除了" Print Screen"键。

我对使用虚拟密钥代码没有任何好运,我认为这不适用于全屏应用程序。因此,部分代码被注释掉了。 (编辑:更好的解释 - DirectInput软件忽略虚拟密钥代码)

使用扫描码,我可以得到任何按键 - 几乎。打印屏幕似乎是奇怪的。

以下是我用于扫描代码的参考资料; https://msdn.microsoft.com/en-us/library/aa299374(v=vs.60).aspx

以下是重现问题的最低可行代码。如果你运行它,按一个键然后快速切换到记事本并等待2秒,它应按下字母" q"进入记事本,然后退出。

将扫描代码从0x10(q)更改为0x37(打印屏幕),请务必在两个位置执行此操作 - KEY DOWN和KEY UP。

现在再次运行,按一个键然后等待。要查看“打印屏幕”是否有效,请打开MS Paint或其他任何内容,然后按CTRL + V,查看是否获得了桌面的屏幕截图。它不起作用!但是,如果您手动按Print Screen,并按CTRL + V进入MS Paint,它将起作用。

为什么Print Screen键不起作用?

#include "stdafx.h"

//For create process & keyboard codes
#include <windows.h>
#include <stdio.h>
#include <tchar.h>

int main()
{
    INPUT ip = {};

    ip.type = INPUT_KEYBOARD;
    ip.ki.wScan = 0;
    ip.ki.wVk = 0;
    ip.ki.dwExtraInfo = 0;
    ip.ki.dwFlags = 0;

    printf("Press a key, then taskswitch.\n");
    system("pause");
    Sleep(2000);

    //KEY DOWN
    ip.ki.wScan = 0x10; //0x37 PrintScreen, 0x10 Q
    ip.ki.dwFlags = KEYEVENTF_SCANCODE;
    //ip.ki.wVk = VK_SNAPSHOT;
    //ip.ki.dwFlags = 0;
    SendInput(1, &ip, sizeof(INPUT));

    //KEY UP
    ip.ki.wScan = 0x10;
    ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP; 
    //ip.ki.wVk = VK_SNAPSHOT;
    //ip.ki.dwFlags = KEYEVENTF_KEYUP; 
    SendInput(1, &ip, sizeof(INPUT));

    printf("Done.\n");
    system("pause");
    return 0;
}

2 个答案:

答案 0 :(得分:2)

使用wVk代替wScan,并确保未设置KEYEVENTF_SCANCODE,因为它会忽略wVk。您必须使用VK_SNAPSHOT

INPUT ip[2] = { 0 };

ip[0].type = INPUT_KEYBOARD;
ip[0].ki.wVk = VK_SNAPSHOT;

ip[1] = ip[0];
ip[1].ki.dwFlags |= KEYEVENTF_KEYUP;
SendInput(2, ip, sizeof(INPUT));

答案 1 :(得分:2)

好的,我在这里回答了我自己的问题;

所以我做了一些更多的研究,发现这个令人惊讶的帖子是一个能够解决扫描码细节的人,看起来Print Screen很奇怪,需要一个特殊的序列。触发得当; https://handmade.network/forums/t/2011-keyboard_inputs_-_scancodes,_raw_input,_text_input,_key_names (另外还有一篇关于3种不同扫描代码集的历史的文章,它提供了一些关于为什么某些键可能很奇怪的原因,因为新的键被添加到标准中)http://www.quadibloc.com/comp/scan.htm

然而,我仍然无法在该文章中尝试各种代码序列 - 最后,我设法通过了解FS-UAE支持ALTERNATE键序列来解决我的原始问题保存屏幕截图:F12-S,我正在使用它而且它工作得很好。

所以这次我可能已经避免了这个问题,但是在扫描代码级别需要合法模拟Print Screen按键而不使用&#34;虚拟键代码&#34; ...的人很难过。一个神秘的神秘任务,我还没有实现。