8

I'm using BitBlt winapi function to take a screenshot of a given window, even if the window is partially overlapped.
I have everything working fine already, except that, on Windows 10, for some windows (like the Edge browser) the screenshot turns out completely black.

A number of other questions concur on attributing this problem to the use of a hardware-accelerated graphics context on those windows.

Apparently the GDI library is incompatible with that kind of graphics context so a different library has to be used.

My question is specifically about how to detect if a window is using a graphics context that's incompatible with the GDI library.

If I'm able to detect this, then I can choose which library to use for capturing the screenshot correctly (GDI, ActiveX or other).

Otherwise, the only way I could detect this is by scanning the screenshot pixel by pixel to check that's completely black. Then using a different capture method till I get some content on the screenshot.
But this sounds like an awful solution.

Tim
  • 81
  • 3
  • Take your screenshot from `GetDC(nullptr)` and then clip out the target window. – Jonathan Potter May 30 '19 at 23:47
  • @JonathanPotter, unfortunately that technique doesn't work with partially overlapped windows. – Tim May 30 '19 at 23:49
  • You can't use BitBlt to capture an overlapped window in any event. – Jonathan Potter May 30 '19 at 23:50
  • "*for some windows ... the screenshot turns out completely black*" - hardware acceleration is not the only reason that can happen. In Windows 7+, apps can simply [choose to opt-out](https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowdisplayaffinity) of their windows being rendered anywhere other than the actual display monitor (think DRM protection, for instance). – Remy Lebeau May 30 '19 at 23:51
  • 1
    @JonathanPotter, yes, you can. That's been possible since the introduction of DWM composition in Windows Vista. – Tim May 30 '19 at 23:57
  • Have you tried using `PrintWindow` with `PW_RENDERFULLCONTENT` as suggested in [the answer to the related question](https://stackoverflow.com/a/40042587/536172)? – AntonK Jun 08 '19 at 18:37
  • @AntonK, that looks promising. I'll try it and report back. – Tim Jun 08 '19 at 20:21
  • @AntonK, the `PW_RENDERFULLCONTENT` trick is indeed able to capturing hardware-accelerated windows. Although not an answer to the question, it's a useful workaround for Windows 10. – Tim Jun 10 '19 at 22:40

1 Answers1

1

I have everything working fine already, except that, on Windows 10, for some windows (like the Edge browser) the screenshot turns out completely black.

You can use DwmRegisterThumbnail to capture hidden/overlapped windows, in particular UWP (like Edge, Calc, etc...)

I use it on Windows 10 without problem (+ D3D to save the bitmap)

Castorix
  • 1,465
  • 1
  • 9
  • 11
  • I thought `DwmRegisterThumbnail` let you show a thumbnail in a window of yours, but it didn't give you access to the pixel data. How do you obtain the image data after calling `DwmUpdateThumbnailProperties`? – Tim Jun 08 '19 at 20:14
  • I tested with **D3DXSaveSurfaceToFile** (VS 2015, Windows 10) – Castorix Jun 08 '19 at 21:13