You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用SendMessage替代SendInput模拟硬件按键实现游戏截图?

解决游戏屏蔽GDI与注入按键的截图问题

一、纠正SendMessage的认知误区

VK_SNAPSHOT的系统截图逻辑不是通过WM_KEYDOWN/WM_KEYUP消息传递给桌面窗口实现的,而是由Windows内核级键盘处理逻辑直接响应物理按键事件,所以直接给桌面窗口发送这类消息完全无效,你的假设不成立。

二、修复SendInput模拟PrintScreen的问题

你当前的SendInput代码错误地给VK_SNAPSHOT添加了KEYEVENTF_EXTENDEDKEY标记——VK_SNAPSHOT不属于扩展按键(扩展按键指小键盘键、Home/End等特殊键),多余的标记可能让游戏钩子更容易识别出这是注入事件。修改代码如下:

INPUT inputs[2];
memset(inputs, 0x00, sizeof(INPUT) * 2);
// 按下PrintScreen
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = VK_SNAPSHOT;
// 移除KEYEVENTF_EXTENDEDKEY标记

// 释放PrintScreen
inputs[1].type = INPUT_KEYBOARD;
inputs[1].ki.wVk = VK_SNAPSHOT;
inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;

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

如果仍被拦截,说明游戏的低级钩子确实在检查LLKHF_INJECTED标记,SendInput的注入事件无法绕过,需更换截图方案。

三、替代截图方案(绕过GDI Hook)

1. 使用DXGI/Direct3D捕获屏幕

对于Direct3D渲染的游戏,DXGI提供的屏幕捕获能力不受GDI Hook影响,核心步骤:

  1. 初始化D3D设备并获取DXGI接口;
  2. 创建桌面输出副本;
  3. 循环捕获帧数据并转换为位图。
    核心代码片段:
// 初始化D3D设备
ID3D11Device* pDevice = nullptr;
D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &pDevice, nullptr, nullptr);

// 获取DXGI设备接口
IDXGIDevice* pDxgiDevice = nullptr;
pDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&pDxgiDevice);

// 获取适配器与主显示器输出
IDXGIAdapter* pAdapter = nullptr;
pDxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&pAdapter);
IDXGIOutput* pOutput = nullptr;
pAdapter->EnumOutputs(0, &pOutput);

// 创建桌面副本
IDXGIOutputDuplication* pOutputDupl = nullptr;
pOutput->DuplicateOutput(pDevice, &pOutputDupl);

// 捕获帧
DXGI_OUTDUPL_FRAME_INFO frameInfo;
IDXGIResource* pDesktopResource = nullptr;
pOutputDupl->AcquireNextFrame(INFINITE, &frameInfo, &pDesktopResource);

2. 使用Windows.Graphics.Capture(Win10 1809+)

这是WinRT提供的现代屏幕捕获API,支持捕获整个屏幕或特定窗口,不受传统Hook影响。C语言可通过COM接口调用,核心逻辑:

  • 用GraphicsCapturePicker选择捕获目标;
  • 创建GraphicsCaptureSession启动捕获;
  • 通过Direct3D11CaptureFramePool获取帧数据。

3. 尝试PrintWindow API

如果游戏窗口未限制,可尝试直接捕获窗口内容:

HWND gameWnd = FindWindowA(nullptr, "游戏窗口标题"); // 替换为实际窗口标题
HDC hdcScreen = GetDC(nullptr);
HDC hdcMem = CreateCompatibleDC(hdcScreen);
RECT rect;
GetWindowRect(gameWnd, &rect);
HBITMAP hBitmap = CreateCompatibleBitmap(hdcScreen, rect.right - rect.left, rect.bottom - rect.top);
SelectObject(hdcMem, hBitmap);
PrintWindow(gameWnd, hdcMem, PW_CLIENTONLY);
// 后续将hBitmap保存到文件或剪贴板
DeleteDC(hdcMem);
ReleaseDC(nullptr, hdcScreen);
DeleteObject(hBitmap);

四、其他注意事项

  • 确保程序以管理员权限运行,部分游戏会限制非管理员进程的截图操作;
  • 若游戏使用反作弊系统,需确保截图行为符合用户协议。

内容的提问来源于stack exchange,提问作者Aravind A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 14:05:29