我一直在尝试对阻止 Windows GDI API(可能通过 API 挂钩)的游戏进行屏幕捕获,因此我无法使用旧的BitBlt()
不幸的是,用于捕获屏幕。每当我打电话BitBlt
,它失败并显示错误代码:126(ERROR_MOD_NOT_FOUND
),这很奇怪!
我尝试使用首选 API 模拟键盘上的打印屏幕键SendInput()
发送VK_SNAPSHOT
Windows 的关键事件,以及它可以成功地将屏幕捕获到剪贴板, 但仅当游戏未运行时.
INPUT inputs[2];
memset(inputs, 0x00, sizeof(INPUT) * 2);
// Key Press
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = VK_SNAPSHOT;
inputs[0].ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
// Key release
inputs[1].type = INPUT_KEYBOARD;
inputs[1].ki.wVk = VK_SNAPSHOT;
inputs[1].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP;
SendInput(2, inputs, sizeof(INPUT));
我理解这种行为的原因可能是因为游戏(闭源软件)通过安装了低级键盘挂钩SetWindowHookEx()
并且正在捕获VK_SNAPSHOT
并能够通过检查来区分注入的击键flags
for LLKHF_INJECTED
,并捕获这样的注入VK_SNAPSHOT
通过使其跳过链来获取密钥,并且它不会传递到 Windows。
But, the game application generously allows the hardware presses to be interpreted by Windows, and I can take a screenshot by pressing the hardware PrntSc (print screen) key on the physical keyboard!
现在,我假设 Windows 中有一个窗口(可能是桌面窗口?)可以直接接受打印屏幕击键,无论是虚拟的还是硬件的。我可能是错的,请纠正我。
所以,我正在考虑使用Windows APISendMessage()
发送VK_SNAPSHOT
事件到桌面窗口,但不幸的是它不起作用,无论是在游戏运行时,还是在正常情况下VK_SNAPSHOT
由...发送SendInput()
工作正常。
这就是我使用的方式SendMessage()
:
/* Key Press */
SendMessage(GetDesktopWindow(), WM_KEYDOWN, VK_SNAPSHOT, 0) // Is lParam = 0, a problem here?
/* Key Release */
SendMessage(GetDesktopWindow()), WM_KEYUP, VK_SNAPSHOT, 0)
编码语言:C,环境:Microsoft Visual Studio 2022、Windows 10 或 Windows 11。
请考虑这一切并帮助我!每一个帮助、评论和回答都将受到赞赏!请理解,一切都是为了合理使用,游戏制造商在截屏方面没有问题,我不知道他们为什么要阻止这一点。
其他向我展示如何进行屏幕截图的方法将对我有很大帮助!