This is the code that I use to take screenshots in-app. Note that if run in windowed mode it captures the entire desktop and cuts out the window area. This means that if some other window is put in front of your window it will capture that data as well.
LPDIRECT3DSURFACE9 CaptureScreen()
{
UINT width;
UINT height;
if (IsFullscreen()) {
width = GetDisplayWidth();
height = GetDisplayHeight();
}
else {
width = GetSystemMetrics(SM_CXSCREEN);
height = GetSystemMetrics(SM_CYSCREEN);
}
LPDIRECT3DSURFACE9 pCaptureSurface;
HRESULT hr = GetD3DDevice()->CreateOffscreenPlainSurface(width, height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pCaptureSurface, NULL);
if (FAILED(hr)) {
SAFE_RELEASE(pCaptureSurface);
return NULL;
}
hr = GetD3DDevice()->GetFrontBufferData(0, pCaptureSurface);
if (FAILED(hr)) {
SAFE_RELEASE(pCaptureSurface);
return NULL;
}
return pCaptureSurface;
}
bool TakeScreenshot(const std::wstring& filename)
{
LPDIRECT3DSURFACE9 pCaptureSurface = GetGraphicsDevice()->CaptureScreen();
HRESULT hr = E_FAIL;
if (pCaptureSurface != NULL) {
D3DXIMAGE_FILEFORMAT imageFileFormat = D3DXIFF_JPG;
std::wstring fileExtention = GXFile::GetFileExtention(filename);
if (GXString::CompareNoCase(fileExtention.c_str(), L"bmp")) {
imageFileFormat = D3DXIFF_BMP;
}
else if (GXString::CompareNoCase(fileExtention.c_str(), L"png")) {
imageFileFormat = D3DXIFF_PNG;
}
if (GetGraphicsDevice()->IsFullscreen()) {
hr = D3DXSaveSurfaceToFile(filename.c_str(), imageFileFormat, pCaptureSurface, NULL, NULL);
if (FAILED(hr)) {
GXLOG_WARN_F(L"Failed to save fullscreen screenshot to %s", filename.c_str());
}
}
else {
// Calculate the rectangle within the screen that the window is currently located.
// I.e. 0,0 is top left of screen for all screens even on multi-monitor setups.
RECT rcWindow;
GetClientRect(m_hWnd, &rcWindow);
POINT topPoint = {rcWindow.left, rcWindow.top};
POINT bottomPoint = {rcWindow.right, rcWindow.bottom};
ClientToScreen(m_hWnd, &topPoint);
ClientToScreen(m_hWnd, &bottomPoint);
rcWindow.left = topPoint.x;
rcWindow.top = topPoint.y;
rcWindow.right = bottomPoint.x;
rcWindow.bottom = bottomPoint.y;
for (unsigned int i = 0; i < m_displays.size(); i++) {
RECT rcDest;
if (IntersectRect(&rcDest, &m_displays[i].rect, &rcWindow)) {
rcWindow.left -= m_displays[i].rect.left;
rcWindow.top -= m_displays[i].rect.top;
rcWindow.right -= m_displays[i].rect.left;
rcWindow.bottom -= m_displays[i].rect.top;
break;
}
}
hr = D3DXSaveSurfaceToFile(filename.c_str(), imageFileFormat, pCaptureSurface, NULL, &rcWindow);
if (FAILED(hr)) {
GXLOG_WARN_F(L"Failed to save windowed screenshot to %s", filename.c_str());
}
}
SAFE_RELEASE(pCaptureSurface);
}
return SUCCEEDED(hr);
}