游戏用的是DirectDraw, 我的截屏是这样做的:
1.hook了DirectDrawCreate获取了LPDIRECTDRAW
2.hook了CreateSurface, 将主表面地址保存起来
3.创建一个离屏surface,将主表面copy到这个离屏表面上,然后输出到文件
现在问题是这个截屏后,若游戏窗口被遮挡,则被遮挡部分无法获取.
这个是什么原因呢? 是这种截图方式不支持遮挡部分截屏呢?
还是说跟游戏主表面的创建有关,有点诡异,游戏窗口大小是800*600,却创建了一个1400*900(显示器大小)的主表面.
还请高手指点下:)
//创建后台表面
if (g_lpDirectDrawCopySurface == NULL)
{
LPDIRECTDRAW lpDD = NULL;
//创建DirectDraw
if (FAILED( DirectDrawCreate(NULL,&lpDD,NULL)))
{
MyTrace(L_ERROR, "Couldn't create DirectDraw object.");
return E_FAIL;
}
if (FAILED(lpDD->SetCooperativeLevel(hwnd/*NULL*/, DDSCL_NORMAL)))
{
MyTrace(L_ERROR, "SetCooperativeLevel failed.");
lpDD->Release();
return E_FAIL;
}
//创建后台表面
RECT rc;
GetClientRect(hwnd, &rc);
DDSURFACEDESC desc;
ZeroMemory(&desc,sizeof(desc));
desc.dwSize=sizeof(desc);
desc.dwFlags= DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS;
desc.dwWidth=/*::GetSystemMetrics(SM_CXSCREEN); */ /*primedesc.dwWidth*/ /*800*/ rc.right - rc.left;
desc.dwHeight=/*::GetSystemMetrics(SM_CYSCREEN); */ /*primedesc.dwHeight*/ /*600*/ rc.bottom - rc.top;
desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
if (FAILED(hr = lpDD->CreateSurface(&desc, &g_lpDirectDrawCopySurface, NULL)))
{
MyTrace(L_ERROR, "CreateSurface copysurface failed.err=0x%x", hr);
lpDD->Release();
return E_FAIL;
}
}
RECT rc;
//GetWindowRect(hwnd, &rc);
GetClientRect(hwnd, &rc);
MyTrace(L_DEBUG, "GetClientRect: %d,%d,%d,%d", rc.left, rc.right, rc.top, rc.bottom);
DDSURFACEDESC desc;
ZeroMemory(&desc,sizeof(desc));
desc.dwSize = sizeof(desc);
if (FAILED(hr = g_lpDirectDrawCopySurface->GetSurfaceDesc(&desc)))
{
MyTrace(L_ERROR, "copysurface GetSurfaceDesc failed.err=0x%x", hr);
return E_FAIL;
}
else
{
MyTrace(L_DEBUG, "copysurface GetSurfaceDesc successfully, nWidth=%d, nHeight=%d", desc.dwWidth, desc.dwHeight);
}
if (FAILED(hr = g_lpDirectDrawCopySurface->BltFast(0,0,g_lpDirectDrawPrimeSurface,&rc,DDBLTFAST_NOCOLORKEY| DDBLTFAST_WAIT)))
{
MyTrace(L_ERROR, "BltFast failed.err=0x%x", hr);
return E_FAIL;
}
if (FAILED(hr = g_lpDirectDrawCopySurface->Lock(NULL, &desc, DDLOCK_WAIT|DDLOCK_NOSYSLOCK,NULL)))
{
MyTrace(L_ERROR, "Lock failed.err=0x%x", hr);
return E_FAIL;
}
//save to bmp
if(SaveToBitmapFile(&desc, pszFilePath) != S_OK)
{
g_lpDirectDrawCopySurface->Unlock(NULL);
MyTrace(L_ERROR, "SaveToBitmapFile failed.");
return E_FAIL;
}
else
{
g_lpDirectDrawCopySurface->Unlock(NULL);
MyTrace(L_DEBUG, "SaveToBitmapFile successfully.");
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)