No mouse cursor in d3d9 GetFrontBufferData - winapi

I' writing a screen capturing application. The screen is captured using Direct3d 9 API and the output media file is written using Windows Media Foundation h264 codec.
The app must work on all Windows versions starting from 7. Therefore, d3d9 API was chosen.
Image is captured using GetFrontBufferData() method.
Everything works fine, except that NO mouse cursor is captured.
How can I fix this?

This is to be expected (the cursor isn't rendered into the display surface referenced in the call to GetFrontBufferData). You have to do the composition manually:
Retrieve the current cursor shape by calling GetCursor.
Retrieve the current cursor position by calling GetCursorPos.
Find the cursor's hotspot by calling GetIconInfo. The hotspot is necessary to offset the cursor when rendering in step 4.
Render the cursor by calling DrawIconEx. If retrieving a HDC is not feasible you could also manually write the cursor info into the front buffer (tedios, but not exactly complicated either).

Related

Screenshot of the specific window (HWND, HW accelerated)

I need to capture a snapshots/screenshots of the specific window (HWND) that is using HW acceleration and record them to a video stream.
While using BitBlt or PrintWindow I'm able to capture image data only if this window is not HW accelerated, else I'm getting a black texture.
Tried using User32.dll's undocumented DwmGetDxSharedSurface to get the DirectX surface handle. But it fails with an error:
ERROR_GRAPHICS_PRESENT_REDIRECTION_DISABLED - desktop windowing
management subsystem is off
(Edit: Fails for certain applications, i.e. "calculator.exe")
Tried using Dwmapi.dll's undocumented functions DwmpDxUpdateWindowSharedSurface and DwmpDxGetWindowSharedSurface. I've managed to retrieve what looks like a valid DirectX surface handle. (it's d3dFormat, width and height information was valid) Dx's OpenSharedResource was not complaining and managed to create a valid ID3D11Texture2D. Problem is.. all bytes are zeros (getting a black texture). I might be doing something wrong here or.. undocumented DWM functionas does not work anymore on Windows 10...
Edit: I'm able to get image data for some applications like Windows
explorer, Paint, etc, but for some like i.e. Slack i get all
zeros/black image.
Edit: When capturing i.e. VLC, I get this:
Question:
Is there any other way to capture image data of the HW accelerated window?
Note: I don't want to capture the entire desktop.
You can use PrintWindow with nFlags=2
Or use Magnification API (exclude windows)
Or try to hack dwm.exe.

PrintWindow and Microsoft Edge

we have a problem with the PrintWindow function on Windows 10 (build 10166). When we call PrintWindow (https://msdn.microsoft.com/ru-ru/library/windows/desktop/dd162869(v=vs.85).aspx) to capture a image of the Microsoft Edge (Project Spartan) browser window we get a black image.
Does anyone know the reason of this and how could it be fixed/avoided? Or maybe some other way to capture image of a window, that can be in background and hided behind another windows?
UPDATE: We've tried sending WM_PRINTCLIENT and WM_PRINT messages, and calling DefWindowProc with WM_PRINT, but results are the same - just a black image. We also tried to use BitBlt to copy window's DC to a memory surface, but it's not working too. Best solution that we have now is bringing browser window to foreground, capturing the entire screen and cropping screenshot to window's client size; but it can interrupt and annoy users because of switching application that's currently in use.
If you want to take a screenshot of the page on the browser. try this JavaScript library: http://html2canvas.hertzen.com/
The script traverses through the DOM of the page it is loaded on. It gathers information on all the elements there, which it then uses to build a representation of the page. In other words, it does not actually take a screenshot of the page, but builds a representation of it based on the properties it reads from the DOM.
I just tried on my machine on Microsoft Edge and Chrome and worked on both.Hope that does the job!
I had the same problem with IE
try this.
The most stable result was with double call
PrintWindow(hWnd, hdcScreen, 0);
PrintWindow(hWnd, hdcScreen, PW_CLIENTONLY);

Mirroring a portion of the screen to an external display (in OSX)

I would like to write a program that can mirror a portion of the main display into a new window. Ideally this new window could then be displayed on an external monitor. I have seen this uiltity for a flightsim that does this on a pc (a multifunction display extractor).
CLick here for a screenshot of the program (MFD Extractor)
This would be a live window ie. constantaly updated video display not just a static graphic.
I have looked at screen magnifiers or vnc clients for ideas but I think I need to write something from scratch. I have tried to do some reading on osx programing but where do I start in terms of gaining access to the display? I somehow need to extract the graphics from a particular program. Is it best to go near the final output stage (the individual pixels sent to the display) or somewhere nearer the window management stage.
Any ideas or pointers would be much appreciated. I just need somewhere to start from.
Regards,
There are a few ways to do this:
Quartz Display Services will let you get access to the video memory for a screen.
Quartz Window Services (a.k.a. CGWindow) will let you create an image of everything that lies below a window. If you create a borderless, transparent, empty, high-level window whose frame occupies an entire screen, everything below it will be everything on that screen. (Of course, you could create a smaller window in order to copy a section of the screen.)
There's also a way to do it using OpenGL that I never fully understood. That technique is demonstrated by a couple of code samples, OpenGLScreenSnapshot and OpenGLCaptureToMovie. It's more or less obsoleted by CGWindow, though.
Each of those will get you an image that you can then show or write to a file or something.
To show an image, use NSImageView or IKImageView. If you want to magnify it, IKImageView has a zoomFactor property, but if you want nearest-neighbor scaling (like Pixie, DigitalColor Meter, or xScope), I think you'll need to write a custom view for that (but even that isn't all that hard).

How does software like GotoMeeting capture an image of the desktop?

I was wondering how do software like GotoMeeting capture desktop. I can do a full screen (or block by block) capture using GDI but that just seems too wasteful to me. Also I have looked into Mirror devices but I was wondering if there's a simpler technique or a library out there which does this.
I need fast and efficient desktop screen capture (10p15 fps) which I am eventually going to convert into a video file and integrate with my application to send the captured feed over the network or something.
Thanks!
Yes, taking a screen capture and finding the diff between previous capture would be a good way to reduce bandwidth on transmission by sending the changes across only, of course this is similar to video encoding techniques which does this block by block.
Still means you need to do a capture plus extra processing for getting the difference, i.e, encoding it.
by using the Mirror devices you can get both the updated Rectangle that are change and also pointer to the Screen. updated Rectangle pointer point to all the rectangle that are change , these rectangle are the change rectangle that are frequently changing. filter out some of the rectangle because in one second you can get 1000 of rectangles.
I would either:
Do full screen captures, and then
perform image processing to isolate
parts of the screen that have changed
to save bandwidth.
-OR-
Use a program like CamStudio.
i got 20 to 30 frame per second using memory driver i am display on my picture box but when i get full screen update then these frame are buffered. as picture box is slow and have change to my own component this is some how fast but not good on full screen as well averge i display 10 fps in full screen. i am facing problem in rendering frames i can capture 20 to 30 frames per second but my rendering is 8 to 10 full screen frames in one second . if any one has achive rendering frames in full screen please replay me.
What language?
.NET provides Graphics.CopyFromScreen.

any quick and easy way to capture a part of the screen? getPixel was slow and GetDIBits seemed a bit complcated as a start

I was trying some code to capture part of the screen using getPixel on Windows, with the device context being null (to capture screen instead of window), but it was really slow. It seems that GetDIBits() can be fast, but it seems a bit complcated... I wonder if there is a library that can put the whole region into an array, and pixel[x][y] will return the 24 bit color code of the pixel?
Or does such library exist on the Mac? Or if Ruby or Python already has such a library that can do that?
I've never done this but I'd try to:
Create a memory Device Context (DC)
using CreateCompatibleDC passing it
the Device Context of the desktop
(GetDC(NULL)).
Create a Bitmap (using
CreateCompatibleBitmap) the same
size as the region your capturing.
Select the bitmap into the DC you
created (using SelectObject).
Do a BitBlt from the
desktop DC to the DC you created (using SRCCOPY flag).
Working with Device Contexts can cause GDI leaks if you do things in the wrong order so make sure that you read the documentation on all the GDI functions you use (e.g. SelectObject, GetDC, etc.).

Resources