2

Totally invisible means the window is not visible to the user, is not shown on the taskbar and is not present in Alt+Tab/Win+Tab views.

I want to create such window and be able to capture it with Windows Graphics Capture API. Here is what I already did:

  1. I create a hidden window and then create a child window. This removes the child window from the taskbar.
  2. Then I cloak the child window which makes it invisible on the screen.

What I can't do is removing it from the task switcher (Alt+Tab/Win+Tab). Adding WS_EX_NOACTIVATE or WS_EX_TOOLWINDOW or removing WS_VISIBLE styles does the job, but makes it non-capturable by the API.

I have already read this, but it doesn't help: https://devblogs.microsoft.com/oldnewthing/20071008-00/?p=24863

Is it possible to achieve what I want? If yes - how? Thanks!

n0p
  • 713
  • 10
  • 23
  • I haven't update my answer to use the `Windows.Graphics.Capture` namespace yet, but it'll come, in due time. – IInspectable Nov 07 '22 at 13:50
  • Thanks @IInspectable . But I don't see how is this a duplicate of the mentioned question? Does the chrome window there have the properties I need? – n0p Nov 07 '22 at 14:23
  • Chrome (presumably) implements the required functionality for your use case. This isn't true for *any* window, though the update to my previous answer will include a solution that will (hopefully) work for any window, including windows that are completely invisible, and not specifically prepared to handle `WM_PRINT` messages correctly. If my update (give it a day, or two) won't work for you, `@`-ping me and I'll re-open this question. – IInspectable Nov 07 '22 at 14:31
  • I wish there would be an API for accessing the internal window redirection surface for the cases being like yours. – jtxkopt Nov 07 '22 at 14:33
  • 1
    @jtxkopt [`Windows.Graphics.Capture`](https://learn.microsoft.com/en-us/uwp/api/windows.graphics.capture) does. – IInspectable Nov 07 '22 at 14:43
  • You're probably in a far better position to judge whether this question (and its answers) is a duplicate [this one](https://stackoverflow.com/questions/30965343/printwindow-could-not-print-google-chrome-window-chrome-widgetwin-1). – IInspectable Nov 07 '22 at 19:26
  • If I modify [the code](https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/blob/a59e7586c0bd1a967e1e25f6ca0363e20151afe5/cpp/ScreenCaptureforHWND/ScreenCaptureforHWND/Win32WindowEnumeration.h#L90) to capture hidden windows, the program will crash at [IGraphicsCaptureItemInterop::CreateForWindow](https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/blob/a59e7586c0bd1a967e1e25f6ca0363e20151afe5/cpp/ScreenCaptureforHWND/ScreenCaptureforHWND/capture.interop.h#L11). – YangXiaoPo-MSFT Nov 08 '22 at 06:09
  • Either you capture a screen and in this case, if the window is not visible by end-user you won't capture it, either you capture by window (CreateForWindow methods) and it won't work as (there's no official doc on this but as far as I known) it does not capture windows that are not displayed by ALT+TAB (just returns E_INVALIDARG from CreateForWindow). Maybe it's some sort of a "security" measure, or simply because in these cases the "invisible" window doesn't simply go through video composition/output process (DWM) so it's not capturable. – Simon Mourier Nov 08 '22 at 08:02
  • I'm not sure why my comment is deleted, but I was saying thanks to @IInspectable for his efforts. – n0p Nov 08 '22 at 11:51
  • @SimonMourier that I already knew (E_INVALIDARG), because I was debugging. Also, invisible window indeed goes through the composition process. You can thumbnail it on a visible window and observe changes. I am more inclined to think this is one of the gaps of the API. – n0p Nov 08 '22 at 11:54

1 Answers1

1

Setting WS_EX_TOOLWINDOW style on the window after capture item creation doesn't stop capturing.

n0p
  • 713
  • 10
  • 23
  • I am not accepting my answer as this a hack/workaround and undocumented behavior. – n0p Nov 22 '22 at 09:39
  • This also works with hiding the taskbar icon via the `ITaskbarList` interface. It is indeed hacky, because I had to find the right moment between the threading/delegate/messaging based capture item creation (`DispatcherQueue::TryEnqueue()`) and capture start. – Simpleton Dec 23 '22 at 10:34