问题
Is it possible to render the desktop into a screen shot when using a full screen 3D-application (such as a game)? Or does windows close the rendering engine while the game is running?
I am looking for ways to render the desktop into a texture in my game. Can RDP like protocols be a solution?
Edit: To clarify, is there any deep level api mechanism to force rendering into another buffer such as when screen shots are made. Doesn't matter if it is only windows 7 or Windows 8/9.
回答1:
You can get a screenshot by calling the PrintWindow Win32 API function on the hWnd of the desktop window. I tried this on Windows 7 and Windows 8.1, it worked even when another application was running (VLC Player) on full screen, so there's a chance it will work with games as well. This will only get you the image of the desktop without the taskbar, but none of the other visible running applications will be shown on it. If you need those as well then you need to get their HWND as well (e.g. by enumerating all the running processes and getting their window handle) and then use the same method.
using System;
using System.Drawing; // add reference to the System.Drawing.dll
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
namespace DesktopScreenshot
{
class Program
{
static void Main(string[] args)
{
// get the desktop window handle without the task bar
// if you only use GetDesktopWindow() as the handle then you get and empty image
IntPtr desktopHwnd = FindWindowEx(GetDesktopWindow(), IntPtr.Zero, "Progman", "Program Manager");
// get the desktop dimensions
// if you don't get the correct values then set it manually
var rect = new Rectangle();
GetWindowRect(desktopHwnd, ref rect);
// saving the screenshot to a bitmap
var bmp = new Bitmap(rect.Width, rect.Height);
Graphics memoryGraphics = Graphics.FromImage(bmp);
IntPtr dc = memoryGraphics.GetHdc();
PrintWindow(desktopHwnd, dc, 0);
memoryGraphics.ReleaseHdc(dc);
// and now you can use it as you like
// let's just save it to the desktop folder as a png file
string desktopDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
string screenshotPath = Path.Combine(desktopDir, "desktop.png");
bmp.Save(screenshotPath, ImageFormat.Png);
}
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool PrintWindow(IntPtr hwnd, IntPtr hdc, uint nFlags);
[DllImport("user32.dll")]
static extern bool GetWindowRect(IntPtr handle, ref Rectangle rect);
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);
}
}
来源:https://stackoverflow.com/questions/25500137/get-a-screenshot-of-desktop-in-full-screen-3d-application