How to capture a Direct3D/WPF/DWM window into a bitmap?

1.7k Views Asked by At

The normal way to capture an image of a window is to call:

HDC SharedWndDC = GetWindowDC(SharedWnd);
BitBlt(BitmapDC, 0, 0, width, height, SharedWndDC, 0, 0, SRCCOPY /* |CAPTUREBLT */);
ReleaseDC(SharedWnd, SharedWndDC);

Which on a system running DWM, nicely grabs just the window in question, even if it's being overlapped by other windows or partly off the screen, or whatnot.

But, it doesn't work right on some windows (presumably those that use WPF), and does funny things with the glass areas. Basically, the GDI capture doesn't work on non-GDI things.

I understand what I really want is to grab the Direct3D "back buffer" or "front buffer", but the numerous examples I've seen for that are for capturing the entire screen or desktop. Not knowing Direct3D, I can't find an example or simple statement of how to obtain the proper object for an existing window, which I could then grab the buffers from.

Can some kind soul at least show that missing piece?

—John

1

There are 1 best solutions below

0
On

I don't believe there is a way to capture the front buffer contents without capturing the whole screen, and the back buffer is private to the application running Direct3D. The front buffer's content can only be seen when the graphics card actually presents the data to the monitor. With GDI, Windows has access to the front and back buffers, because it is managing them itself. But with Direct3D (and I'm presuming WPF), this is no longer the case. Windows does not have access to the buffers, and as such, can't obtain the data unless the application gives it to Windows, which is impossible (there's no message defined to do so).

EDIT:

This looks like a dead question, but I'll add this anyway in case someone else comes along looking for answers. The aforementioned issues still apply to getting the window contents programmatically. However, it is possible in Windows to get the contents of a single window by utilizing the shortcut ALT+Print Screen when the window you want to capture has the keyboard focus (a.k.a. it's the active window). This may or may not help you, but it does capture the contents of just the window in question, even with DirectX stuff.