如何实现DX后台截图C的?
摘要:DX后台截图C++实现代码 传统的GDI API (BitBlt)虽然可以完美的完成后台截图的任务,但是归根结底效率还是太低。 直接使用DXGI方法截图只能完成前台窗口的截图,而DX HOOK的截图方法平
DX后台截图C++实现代码
传统的GDI API (BitBlt)虽然可以完美的完成后台截图的任务,但是归根结底效率还是太低。
直接使用DXGI方法截图只能完成前台窗口的截图,而DX HOOK的截图方法平添风险,以及很多场景不现实。
本文讲介绍使用 DwmGetDxSharedSurface 函数,优雅的完成后台截图的工作。
API介绍
函数定义
BOOL WINAPI DwmGetDxSharedSurface (
HWND hwnd,
HANDLE* phSurface,
LUID* pAdapterLuid,
ULONG* pFmtWindow,
ULONG* pPresentFlags,
ULONGLONG* pWin32kUpdateId
)
\(DwmGetDxSharedSurface\)来自于user32.dll(很离谱是吧,DwmApi不在DwmApi.dll里)。由于是ms没有公开的API,需要使用动态方法加载。
调用函数方法
//动态载入该函数
typedef HRESULT(WINAPI* DwmGetDxSharedSurface_t)(HWND, HANDLE*, LUID*, ULONG*, ULONG*, ULONGLONG*);
DwmGetDxSharedSurface_t DwmGetDxSharedSurface = NULL;
//获取地址
HMODULE hUser32 = LoadLibraryA("user32.dll");
if (hUser32 == NULL)
{
std::cout << "LoadLibraryA failed" << std::endl;
return 0;
}
DwmGetDxSharedSurface = (DwmGetDxSharedSurface_t)GetProcAddress(hUser32, "DwmGetDxSharedSurface");
//Dwm函数 在 user32.dll 中,真是离谱
if (DwmGetDxSharedSurface == NULL)
{
std::cout << "GetProcAddress failed" << std::endl;
return 0;
}
std::cout << DwmGetDxSharedSurface << std::endl;
参数含义
hwnd 被截图窗口的句柄
phSurface 被截图窗口的共享画面的句柄(应该是这么翻译吧)
其他,暂时还没了解。
API调用
问题
显然这个API不能一步到位获得到BMP或者其他类型的图像数据。和BitBlt一样,这个API只是拿到了对应画面的副本(?,不清楚这样描述是否准确)。参照唯一有官方信息的API\(DwmDxGetWindowSharedSurface\),得到的是DX的一个对象,那就应该从DX下手。
初始化DX
这里讲个遇到的坑,DX设备的初始化不能在dllmain里进行,否则会失败。
