【发布时间】:2014-04-29 11:01:52
【问题描述】:
我正在使用 DirectX 开发屏幕捕获应用程序,该应用程序适用于大多数情况,但屏幕具有分层窗口时除外,它会被 DirectX 捕获忽略。
我知道使用 GDI 我可以使用 CAPTUREBLT 标志来捕获这些窗口,但我不知道如何使用 DirectX 来做到这一点,所以我的问题是:
使用 DirectX,我如何捕获分层窗口?
我的代码:
LPDIRECT3D9 d3d9;
LPDIRECT3DDEVICE9 d3ddev;
IDirect3DSurface9* dest;
void Init()
{
CoInitialize(NULL);
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
ww = GetSystemMetrics(SM_CXSCREEN);
wh = GetSystemMetrics(SM_CYSCREEN);
HWND hwnd = GetDesktopWindow();
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferWidth = ww;
d3dpp.BackBufferHeight = wh;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.hDeviceWindow = hwnd;
d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
d3ddev->CreateOffscreenPlainSurface(ww, wh, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &dest, NULL);
}
void Screenshot()
{
d3ddev->GetFrontBufferData(0, dest);
D3DLOCKED_RECT rect;
ZeroMemory(&rect, sizeof(D3DLOCKED_RECT));
dest->LockRect(&rect, NULL, D3DLOCK_READONLY);
uchar *bits = (uchar*)rect.pBits;
dest->UnlockRect();
//Use bits
}
void End()
{
dest->Release();
d3ddev->Release();
d3d9->Release();
CoUninitialize();
}
【问题讨论】:
-
为什么说图层窗口?覆盖表面?
-
当我提到分层窗口时,我指的是这个答案:stackoverflow.com/a/1194281/2014561,它可以在不忽略任何窗口的情况下捕获屏幕,但它是一种捕获屏幕的 GDI 方式。我不确定它是否是覆盖面。
标签: c++ directx screen-capture