Получить часть скриншота окна заданного хендлом - 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; }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д