SendInput不适用于Print Screen键

Dom*_*ius 8 c++ windows winapi

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

我已经设法用SendInput模拟我想要的任何按键,除了"打印屏幕"键.

我没有运气使用虚拟键码,我认为这不适用于全屏应用程序.因此,部分代码被注释掉了.(编辑:更好的解释 - 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;
}
Run Code Online (Sandbox Code Playgroud)

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