2009-12-07 58 views
3

的窗口的屏幕截图这是一个后续问题this question保存使用C#,WPF,并且DWM

上述的解决方案使用DWM以显示活动窗口的缩略图。如果我理解正确,它可以让你指定要查看的应用程序的窗口句柄,然后让你提供一个窗口句柄和窗口上的窗口应该绘制目标窗口内容的位置。

有没有办法将窗口屏幕截图直接呈现给BitmapImage或Image,而不是直接在窗口中的某处绘制它? (基本上只需抓住窗口的屏幕截图 - 即使它被另一个窗口覆盖 - 不使用更新缩略图。)

感谢您的帮助!

+0

合并完成。 – 2011-09-01 18:53:46

回答

2

使用Control.DrawToBitmap Method

Image img = myForm.DrawToBitmap(); 
Image img = myPanel.DrawToBitmap(); 
+0

感谢您的回复。这不会需要屏幕截图先在屏幕上绘制然后保存吗?有没有办法将一个窗口的屏幕截图直接捕获到一个对象(如图像),而无需首先在屏幕上绘制它? – Evan 2009-12-07 18:23:00

+0

DrawToBitmap像您在按下PrintScreen按钮时一样获取位图(在窗体上或仅在面板上)。我不确定窗体或面板是否应该真正显示在屏幕上,可见的面板肯定是有效的,我相信隐藏的应该也可以。 位图bm =新位图(wid,hgt); '将当前窗体绘制到位图 this.DrawToBitmap(bm,new Rectangle(0,0,wid,hgt)) – serhio 2009-12-08 16:40:49

9

的Control.DrawToBitmap并不总是工作,所以我使出提供更一致的结果下面的原生API调用:

的实用工具类。调用Utilities.CaptureWindow(Control.Handle)来捕获特定的控制:

public static class Utilities 
{ 
    public static Image CaptureScreen() 
    { 
     return CaptureWindow(User32.GetDesktopWindow()); 
    } 

    public static Image CaptureWindow(IntPtr handle) 
    { 

     IntPtr hdcSrc = User32.GetWindowDC(handle); 

     RECT windowRect = new RECT(); 
     User32.GetWindowRect(handle, ref windowRect); 

     int width = windowRect.right - windowRect.left; 
     int height = windowRect.bottom - windowRect.top; 

     IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc); 
     IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height); 

     IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap); 
     Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, ApiConstants.SRCCOPY); 
     Gdi32.SelectObject(hdcDest, hOld); 
     Gdi32.DeleteDC(hdcDest); 
     User32.ReleaseDC(handle, hdcSrc); 

     Image image = Image.FromHbitmap(hBitmap); 
     Gdi32.DeleteObject(hBitmap); 

     return image; 
    } 
} 

的GDI32类:

public class Gdi32 
{ 
    [DllImport("gdi32.dll")] 
    public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjectSource, int nXSrc, int nYSrc, int dwRop); 
    [DllImport("gdi32.dll")] 
    public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight); 
    [DllImport("gdi32.dll")] 
    public static extern IntPtr CreateCompatibleDC(IntPtr hDC); 
    [DllImport("gdi32.dll")] 
    public static extern bool DeleteDC(IntPtr hDC); 
    [DllImport("gdi32.dll")] 
    public static extern bool DeleteObject(IntPtr hObject); 
    [DllImport("gdi32.dll")] 
    public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); 
} 

的USER32类:

public static class User32 
{ 
    [DllImport("user32.dll")] 
    public static extern IntPtr GetDesktopWindow(); 
    [DllImport("user32.dll")] 
    public static extern IntPtr GetWindowDC(IntPtr hWnd); 
    [DllImport("user32.dll")] 
    public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect); 
    [DllImport("user32.dll")] 
    public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC); 
} 

使用的常数:

public const int SRCCOPY = 13369376; 

T他用结构:

[StructLayout(LayoutKind.Sequential)] 
public struct RECT 
{ 
    public int left; 
    public int top; 
    public int right; 
    public int bottom; 
} 

友好的控制扩展方法:

public static class ControlExtensions 
{ 
    public static Image DrawToImage(this Control control) 
    { 
     return Utilities.CaptureWindow(control.Handle); 
    } 
} 
+0

这很有用,但我在此处发布了后续问题:http://stackoverflow.com/questions/2322217/getting-window-screenshots-but-text-parts-are-transparent – 2010-02-23 22:33:13

+0

很好,这是一个超级快速的代码。但wpf控件没有处理:( – Andreas 2011-11-16 09:28:12