2010-11-14 2 views
2

Я пытаюсь создать приложение в C# .net, которое отображает скриншот текущего активного окна, включая область, которую нужно прокручивать с помощью полос прокрутки. Я нашел следующий код, чтобы сделать снимок экрана. Чтобы быть предельно ясным, я хочу, чтобы код делал снимок экрана активного окна, включая область, которая не отображается, и отображается только с помощью полос прокрутки.Как сделать снимок экрана из окна полного размера в C#

public class ScreenShot 
{ 
    /// <summary> 
    /// Captures the screenshot of the entire desktop 
    /// </summary> 
    /// <returns>Image object containing the screenshot of the desktop</returns> 
    private Image CaptureDesktop() 
    { 
     return CaptureWindow(User32.GetDesktopWindow()); 
    } 

    public Image CaptureAciveWindow() 
    { 
     return CaptureWindow(User32.GetForegroundWindow()); 
    } 

    /// <summary> 
    /// An Internal method, that captures the screenshot of any given Application window, given its Handle. 
    /// </summary> 
    /// <param name="handle">The handle of the window you want to Capture</param> 
    /// <returns>An Image object containing the screenshot of the active application window</returns> 
    private Image CaptureWindow(IntPtr handle) 
    { 
     // get te hDC of the target window 
     IntPtr hdcSrc = User32.GetWindowDC(handle); 
     // get the size 
     User32.RECT windowRect = new User32.RECT(); 
     User32.GetWindowRect(handle, ref windowRect); 
     int width = windowRect.right - windowRect.left; 
     int height = windowRect.bottom - windowRect.top; 
     // create a device context we can copy to 
     IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc); 
     // create a bitmap we can copy it to, 
     // using GetDeviceCaps to get the width/height 
     IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height); 
     // select the bitmap object 
     IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap); 
     // bitblt over 
     GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY); 
     // restore selection 
     GDI32.SelectObject(hdcDest, hOld); 
     // clean up 
     GDI32.DeleteDC(hdcDest); 
     User32.ReleaseDC(handle, hdcSrc); 
     // get a .NET image object for it 
     Image img = Image.FromHbitmap(hBitmap); 
     // free up the Bitmap object 
     GDI32.DeleteObject(hBitmap); 

     return img; 
    } 

    /// <summary> 
    /// Helper class containing Gdi32 API functions 
    /// </summary> 
    private class GDI32 
    { 
     public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter 

     [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); 
    } 

    /// <summary> 
    /// Helper class containing User32 API functions 
    /// </summary> 
    private class User32 
    { 
     [StructLayout(LayoutKind.Sequential)] 
     public struct RECT 
     { 
      public int left; 
      public int top; 
      public int right; 
      public int bottom; 
     } 

     [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 ReleaseDC(IntPtr hWnd, IntPtr hDC); 
     [DllImport("user32.dll")] 
     public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect); 
     /// <summary> 
     /// Gets the Handle for current active window 
     /// </summary> 
     /// <returns>Active windows Handle</returns> 
     [DllImport("user32.dll")] 
     public static extern IntPtr GetForegroundWindow(); 
    } 
} 

ответ

4

Вы делаете предположение, что здесь это не всегда верно: что есть что-то там уже ждут в unscrolled области. Приложение может создавать полосы прокрутки для определенной высоты или ширины и фактически не отображать ничего на поверхности до тех пор, пока пользователь не перетянет полосу прокрутки. Изображение, которое вы хотите захватить, существует только в потенциале. Это может быть использовано для повышения производительности. — думаю, что это просто вовремя, или сокращение использования памяти. Это довольно распространенная техника, и поэтому то, о чем вы просите, на самом деле не имеет смысла.

+0

Хорошо, может быть, я должен согласиться с вами. – Vamsi

3

содержимое экрана Захват без использования каких-либо API вызовов Win32, только с помощью .NET 2.0 в CodeProject.

+0

Это была отличная статья, спасибо – Vamsi

1

Вам нужно будет перерисовать все окно/форму на графический объект. Пример (простой) того, как это можно сделать, можно найти в this CodeProject article. Вам нужно будет реализовать поддержку всех элементов управления, которые вам нужны в вашем проекте. Кроме того, если вы измените размер окна в примере приложения (затмеваете некоторые элементы управления) и сделаете тестовый отпечаток, вы увидите, что основная форма, которая является просто другим элементом управления, нарисована поверх других элементов управления, что не является реальной проблемой, но не выглядит очень хорошо - вы можете просто удалить поддержку для рисования основной формы, если это проблема.

В качестве альтернативы, при использовании или переключении на WPF вы можете печатать элементы управления (включая главное окно) с помощью PrintDialog.PrintVisual().

Смежные вопросы