1

I am trying to take a screenshot of a DirectX game. I want to capture the window even when it is behind other windows without bringing the window to the front. When I run the application on my system, it works perfectly. However, on all other systems I run the application on, it only captures the border and the area inside is black.

My system, works

Second system, only border

Third system, only border

My code:

// get the hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(hWnd);

// get the size
Rectangle windowRect = new Rectangle();
User32.GetWindowRect(hWnd, ref windowRect);
int width = windowRect.Right - windowRect.Left;
int height = windowRect.Bottom - windowRect.Top;

// create a device context we can copy to
IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc);

// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height);

// select the bitmap object
IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap);

// bitblt over
Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRCCOPY);

// restore selection
Gdi32.SelectObject(hdcDest, hOld);

// clean up 
Gdi32.DeleteDC(hdcDest);
User32.ReleaseDC(hWnd, hdcSrc);

// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);

// free up the Bitmap object
Gdi32.DeleteObject(hBitmap);

if (bmp != null)
    bmp.Dispose();
bmp = new Bitmap(img);

If it matters, my system's graphics card is NVIDIA GeForce GTX 970, the second is NVIDIA GeForce GTX 1060, and the third is NVIDIA GeForce GTX 960M. All systems are Windows 10 64 bit.

Deltin
  • 11
  • 2
  • You might have better luck with SRCCOPY | CAPTUREBLT. Backgrounder [is here](https://stackoverflow.com/questions/21535001/why-do-directx-fullscreen-applications-give-black-screenshots). – Hans Passant May 07 '18 at 16:33
  • I get the same result with SRCCOPY | CAPTUREBLT; works on my pc, not on anyone else's. – Deltin May 07 '18 at 17:00

0 Answers0