2009-12-07 26 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