Desktop Window Manager capture the whole screen - windows-7

I was wondering if anyone could give me a starting point of how to capture the entire screen in Windows Vista/7? I know how to do it in previous versions of Windows, but would really like to keep everything in the D3D stack, without resorting to GDI/BltBit calls.
I realize that you can get a live thumbnail of a given window if you have the HWND using the DWM API, but how do you get a "thumbnail" of the entire desktop?
Thanks,
Alex

Unfortunately, the functions to do this are in the dwmapi.dll, and are undocumented. Someone figured out how to do it to get the directx surface of another window in vista, and use this to capture the screen, but those functions don't work on Windows 7.
The best thing you can do is get the thumbnails of individual windows, at least, that's all I've found.

Related

StartScreenCapturebyWindowId() not excluding overlapping windows for certain programs (Agora Unity)

I am trying to setup individual window sharing for a project in Unity for Windows. The way I'm currently going about doing this is by using EnumWindows(), IsVisableWindow(), and GetWindowText() to create a dictionary of window titles and handles, then calling StartScreeCapturebyWindowId() to share the selected window.
This works relatively well for most process; the window of the process and only the window of the process is streamed. However, for certain programs (like Google Chrome, Discord, and Windows Photos) the captured area is set correctly, but overlapping windows are not culled out.
Does anyone know what could be causing this problem? Is there something wrong with the way I'm grabbing the handles for these windows? Or is there something about starting a screen capture that I am missing?
You certainly did the correct things. However, you also hit the limitation to the Windows part of the SDK. To understand this better, the set of programs are UWP applications. They have different ways to share the visible pixels. Previously version of Agora SDK could not even show the window. Starting from 3.0.1, the SDK uses Rectangle cutting method to get the window display. You may further read the online documentation about that API here.
There isn't much Agora can do for the near term. So you will just need to deal with the user experience (e.g. by warning them) or look at solutions like using Web SDK instead.

Why is my application's window border grey in Windows 8, rather than being based off the desktop like other windows?

I have a large legacy application which is showing up with a perpetually grey border on every Windows 8 machine we run it on, while the other windows for other apps accurately use a color derived from the desktop background. For the life of me I can't find out why.
I've tried my best google-fu to crawl MSDN for APIs to control this but came up empty. The app looks like all others in Windows XP, Vista, and 7...just Windows 8 is grey in color. We definitely haven't added Win8 specific code to treat this otherwise.
It's just an MFC window on the outside, but inside it embeds a .NET/WPF component and a Direct3D 9-enabled visual area.
My best guess is it could somehow be related to having a Direct3D surface in the window, but I couldn't validate that anywhere.
Any help would be greatly appreciated!
Thanks
Edit: The grey matches the effect of not having focus, and we definitely do play games with window focus...so that could be it.
The problem was a developer overloaded OnNcActivate() and returned TRUE at the end. They needed to call up to the baseclass's (CWnd) OnNcActivate instead.
This was visible on Windows 7 as well if you looked close enough.
The Desktop in Windows 8 does not use transparency in window borders like Windows 7 and Vista did with the Aero Themes. If you are move the focus to another top window in your app, this could explain why your seeing the grey border. Try changing the colors for windows without the focus to something discernable from grey to verify that is what you are seeing.

Screenshot of window

I'm trying to take screenshots of all open windows, also the minimized ones. Currently I'm using this code:
http://www.developerfusion.com/code/4630/capture-a-screen-shot/
But it doesn't work for minimized windows and the areas where there is a Glass effect since Vista like the explorer title bar are black. Can anyone help me out?
My objective is to create something similar to Flip 3D; it would be great if someone also knew something about how to create a live preview.
For the glass effect areas: I think it doesn't work because those areas may be drawn with some strange DirectX method instead of normal GDI.
For the minimized windows problem: if a window is minimized, its DC isn't painted (conceptually, it doesn't even have a reason to exist); you should try to send to such windows a WM_PRINT message, asking them to paint themselves on the DC you'll provide them. The problem with this approach is that not all the windows handle correctly WM_PRINT.
I've found the API that is used for the taskbar previews a.s.o.:
DWM Thumbnail Overview
Pretty awesome, it even allows you to do live previews!

Cursor disappears on bitblt

I have a windows application that scrapes pixels from the screen for recording (in the form of a video) to a custom screen-sharing format. The problem is that on machines using a software cursor, blitting from the screen with SRCCOPY|CAPTUREBLIT (so that layered windows also show up in the image) causes the cursor to blink, as described in Case of the Disappearing Cursor.
For single screen shots, this is not a problem, but when multiple screen shots are taken in rapid succession, the cursor blinks so fast that it sometimes seems to disappear altogether.
I have looked into using the Windows Media Encoder SDK (as described in a codeproject article, see below) because it doesn't cause the cursor to blink, but there seems to be no way to directly access the frame data. Unfortunately, both real-time encoding and the custom format are both requirements, which makes windows Media Encoder unusable for this purpose.
I have also tried the DirectX way (described in the same article, see below), and it seems to suffer from the same problem.
Has anyone else run into this problem? There must be a way around it - many commercial screen sharing programs have no such problem.
article: www.codeproject.com/KB/dialog/screencap.aspx
you can use Magnification API in windows vista or later.
i cannot find a good idea in windows xp.
What about using a mirror driver?
You are right, a mirror would certainly work. However, at the moment, I am trying to stay away from that approach because of the security and permissions concerns when installing under a user without admin rights. Correct me if I am wrong, but I don't think there is any way to install a driver without such rights. Besides that, it seems that that would be needlessly complex: there should be a simpler / less invasive way to do this. (I should have mentioned this in my original question)
Just copy the screen and the cursor separately and overlay them.
The thought I had to overcome the flicker is to "manually" draw "your own copy of the mouse", then make the BitBlt call, or to call BitBlt with just SRCCOPY then manually capture any visible transparent windows over the top of it. I don't know how the commercial stuff does it (or the windows media encoder apparently does).
ref: http://us.generation-nt.com/xp-bitblt-captureblt-option-help-26970632.html

Windows Vista Desaturated: Grayscale UI

Occasionally working in Windows Vista the O.S. will desaturate the screen, rendering all colors as grayscale. Is there a way to do this programatically? Failing that, is there a way to do it by tweaking Vista settings?
Thanks.
Umm, if I had to guess, I'd say that Vista (and XP, by the way) are simply applying some sort of overlay to the whole screen. I'm guessing it's done by rendering an opaque rectangle with a blend mode of some sort. This is only my guess, though.
Dmitri's suspicion is correct. Windows essentially takes a screenshot and fades it, while displaying a popup in front of it. You can do the same if you need to.
You can test this by running a video or something that is animated, then selecting Shut Down to display that popup and dimmed background -- note that the video has stopped, and when you cancel the "shutdown" and return to your apps, you'll see that the video has continued in the background.
edit: I'm not aware of an existing function to do this, but nothing stops you from creating your own.

Resources