Получить часть скриншота окна заданного хендлом - C#

Узнай цену своей работы

Формулировка задачи:

Привет всем. Нужно получить часть скриншота окна заданного хендлом. Код получения скриншота всего окна я нашел в инете. А вот как быстро получить заданную прямоугольником область этого окна. Очень желательно без попиксельного копирования (это сам смогу), т.к. это долго, как мне кажется. Код получения скриншота окна:
public class WindowImageCapture
{
    /// <summary>
    /// Получение снимка окна
    /// </summary>
    /// <param name="WindowHandle">HWND окна</param>
    /// <returns>Скриншот</returns>
    public static Image CaptureWindow(IntPtr WindowHandle)
    {
        if (WindowHandle != null)
        {
            User32.RECT windowRect = new User32.RECT();
            User32.GetWindowRect(WindowHandle, ref windowRect);
            int width = windowRect.right - windowRect.left + 1;
            int height = windowRect.bottom - windowRect.top + 1;
 
            User32.SetWindowPos(WindowHandle,
                                (System.IntPtr)User32.HWND_TOPMOST,
                                0, 0, 0, 0,
                                User32.SWP_NOMOVE |
                                User32.SWP_NOSIZE |
                                User32.SWP_FRAMECHANGED);
 
            IntPtr hdcSrc = User32.GetWindowDC(WindowHandle);
            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,
                         GDI32.SRCCOPY);
 
            User32.SetWindowPos(WindowHandle,
                                (System.IntPtr)User32.HWND_NOTOPMOST,
                                0, 0, 0, 0,
                                User32.SWP_NOMOVE |
                                User32.SWP_NOSIZE |
                                User32.SWP_FRAMECHANGED);
 
            GDI32.SelectObject(hdcDest, hOld);
            GDI32.DeleteDC(hdcDest);
            User32.ReleaseDC(WindowHandle, hdcSrc);
            Image img = Image.FromHbitmap(hBitmap);
            GDI32.DeleteObject(hBitmap);
            return img;
        }
        else
            return null;
    }
 
    private class User32
    {
 
        public const int SWP_FRAMECHANGED = 0x0020;
        public const int SWP_NOMOVE = 0x0002;
        public const int SWP_NOSIZE = 0x0001;
        public const int SWP_NOZORDER = 0x0004;
        public const int HWND_TOPMOST = -1;
        public const int HWND_NOTOPMOST = -2;
 
        [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 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);
 
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetWindowPos(IntPtr hWnd,
                                               IntPtr hWndInsertAfter,
                                               int x, int y,
                                               int cx, int cy,
                                               uint uFlags);
    }
 
    private class GDI32
    {
 
        public const int SRCCOPY = 0x00CC0020;
 
        [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);
    }
}
Использование вышеприведенного кода:
Image img = WindowImageCapture.CaptureWindow(hwnd);
Еще добавлю, окно может находиться на втором мониторе... Может можно сделать как-то проще, чем в примере?

Решение задачи: «Получить часть скриншота окна заданного хендлом»

textual
Листинг программы
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct RECT {
    public int X;
    public int Y;
    public int Right;
    public int Bottom;
 
    public Rectangle ToRectangle() {
        return new Rectangle(X, Y, Right - X, Bottom - Y);
    }
}
 
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(
    IntPtr hWnd,
    out RECT lpRect
    );
 
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
 
Bitmap GetScreenCopyFromHwnd(IntPtr hWnd, bool activate) {
    var temp = new RECT();
 
    GetWindowRect(hWnd, out temp);
    if (activate)
        SetForegroundWindow(hWnd);
 
    var rect = temp.ToRectangle();
    var bmp  = new Bitmap(rect.Width, rect.Height);
 
    using (var g = Graphics.FromImage(bmp))
        g.CopyFromScreen(rect.Location, Point.Empty, rect.Size);
 
    return bmp;
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 3.9 из 5
Похожие ответы