8

I am starting to believe that you can do nothing with Windows API.

I have two windows. One has a DWM thumbnail in it. What I want to do is, I want to be able to capture the screen of the window with the thumbnail into the other one. When I do this, using bitblt, everything is copied except the thumbnail. It just isn't there in the bitmap.

So how does the DWM rendering work? I mean, if DWM renders thumbnails directly onto the DC of the registered window, then my approach should work. I'm confused.

Thanks a bunch.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
Dogan Demir
  • 189
  • 2
  • 9

2 Answers2

11

That's not how DWM works: the contents of the thumbnail are never blitted onto the DC of your window. Instead, the DWM composition engine will render the thumbnail directly over the contents of your window when the desktop is presented.

There's no (official) way to access the image data of a DWM thumbnail unfortunately (there is however a hack on the net that tries to access the underlying vertex data and render it in DirectX 9).

LorenzCK
  • 7,411
  • 2
  • 36
  • 28
  • 1
    Just tried this myself on Win10 and found it fail just like the OP did. Why does Alt+PrntScr grab everything though when you paste it into mspaint? – mikew Oct 05 '19 at 00:21
  • Fair point: the difference is that DWM Thumbnails do not actively _blit_ anything into your window's drawing context. A DWM Thumbnail only reminds the windows compositor to compose one window on top of another when rendering the final pixels that are going to screen. When screen grabbing, you grab the final rendering, and thus are able to get the composited windows as well: try using a window capture API on your own window, for instance, and you should be able to get everything (original windows content + thumbnails). – LorenzCK Oct 06 '19 at 08:42
  • What window capture APIs do you think would work? I've tried getting the bitmap in the DC itself, I've tried BitBlt, I've tried PrintWindow, none seem to work for me. – mikew Oct 08 '19 at 19:22
  • _Note: I haven't tested any of these, they are just methods that could work._ When doing screen capture via GDI, I _think_ you should be screen capturing the desktop window itself, not the specific window you are trying to clone. This way you get the desktop's output, not the contents of the source window (of course, you'll have to crop the desktop in order to get only the window you are interested in). Otherwise, you might look into how to do it [with DirectX](https://stackoverflow.com/a/30138664/3118) or the [new UWP APIs](https://docs.microsoft.com/en-us/uwp/api/windows.graphics.capture). – LorenzCK Oct 09 '19 at 20:49
  • Thanks I will look into those options. I forgot to mention, the reason I'm capturing a specific window is because I'm needing to capture these windows when they are BEHIND other windows in the Z-Order. So they are effectively obscured, and wouldn't be shown by capturing the desktop. That's why I'm getting the DC of the window itself first. – mikew Oct 11 '19 at 21:05
  • Graphics.Capture API works in this case, however it forces DWM to re-render the window which adds GPU usage overhead. And things are even worse if there are thumbnails. – n0p Apr 13 '22 at 15:25
3

You cannot expect a thumbnail to be place in a window's device context, because the thumbnail is not placed in a window's device context. So your approach will not work.

But if you're trying to steal the thumbnail of an application, just ask the Dwm to give you it's thumbnail. That will allow you to present to the user the exact thumbnail you want.

If, on the other hand, you want to access the pixels in the thumbnail of another process, then you have a problem.

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219