0

I am creating a desktop virtualization capture driver. Basically, the driver opens a virtualized desktop and captures the screen into a bitmap buffer and sends it to the client which then gets drawn onto their screen (GetDIBits/SetDIBits).

The problem is, the problem is with PrintWindow in Windows 7. In Windows 8.1+ there was an extra flag added to this function PW_RENDERFULLCONTENT which draws the entire desktop in one go, however in Windows 7 this flag doesn't exist.

My question is, how can I properly emulate this flags behaviour in Windows 7 such that all windows are drawn properly. For example, without this flag, when the host machine opens Chrome in their virtualized desktop, the PrintWindow call fails since Chrome is rendered with Aura and PrintWindow isn't built to handle this functionality, hence chrome is drawn with a black square in the middle:

image

Radiodef
  • 37,180
  • 14
  • 90
  • 125
  • You can copy the whole desktop screen, it will copy whatever is on the screen. If you call `GetDC(somewindow)` it will lead to this problem, there is no way around it as far as I know. – Barmak Shemirani Aug 09 '18 at 19:56
  • 1
    Please edit the question and make [MCVE](https://stackoverflow.com/help/mcve). See also this [example](https://stackoverflow.com/q/40367360/4603670) – Barmak Shemirani Aug 09 '18 at 20:26
  • 1
    @BarmakShemirani "*it will copy whatever is on the screen*" - not everything, for instance windows protected by [`SetWindowDisplayAffinity()`](https://msdn.microsoft.com/en-us/library/windows/desktop/dd375340.aspx) will not be copied. – Remy Lebeau Aug 09 '18 at 21:44
  • @RemyLebeau that's true. I don't think Chrome uses `SetWindowDisplayAffinity`, at least not by default. It might not be the problem here. – Barmak Shemirani Aug 09 '18 at 22:02
  • 1
    Please don't make more work for people by vandalizing your posts. By posting on the Stack Exchange (SE) network, you've granted a non-revocable right, under the [CC BY-SA 3.0 license](//creativecommons.org/licenses/by-sa/3.0), for SE to distribute that content (i.e. regardless of your future choices). By SE policy, the non-vandalized version of the post is the one which is distributed. Thus, any vandalism will be reverted. – Makyen Aug 11 '18 at 23:01

1 Answers1

1

A quick test indicates the capturing the correct area of the screen produces correct results. Code like this:

memDC.BitBlt(0, 0, src_rect.Width(), src_rect.Height(), 
             &screen, 
             src_rect.TopLeft().x, src_rect.TopLeft().y, 
             SRCCOPY | CAPTUREBLT);

...was adequate to capture a picture of your question being displayed in Chrome:

enter image description here

CAPTUREBLT is recommended, but doesn't seem to be truly necessary for this particular case. This code is using MFC's wrapper around BitBlt, but that shouldn't change anything significant compared to calling BitBlt directly.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Capturing the window itself is not a problem. In my question I stated that I am trying to capture chrome from a virtualized desktop, meaning I have it running in another desktop station (`CreateDesktopA`/`OpenDesktopA`). It is not visible in the current desktop session so I am forced to send a `WM_PAINT` message (`PrintWindow`) to it before drawing, but since Chrome uses `DirectComposition` it won't register with the `WM_PAINT` message. I managed to get around this by disabling direct composition with a flag, but I am looking for a native solution. –  Aug 10 '18 at 21:53