Я пытаюсь сделать снимок экрана окна с помощью C#.NET путем вызова Windows API. Я придумал следующий код:
public void ScreenshotWindow(IntPtr windowHandle) {
Rect Rect = new Rect();
GetWindowRect(windowHandle, out Rect);
int width = Rect.right - Rect.left;
int height = Rect.bottom - Rect.top;
IntPtr windowDeviceContext = GetWindowDC(windowHandle);
IntPtr destDeviceContext = CreateCompatibleDC(windowDeviceContext);
IntPtr bitmapHandle = CreateCompatibleBitmap(windowDeviceContext, width, height);
IntPtr oldObject = SelectObject(destDeviceContext, bitmapHandle);
BitBlt(destDeviceContext, 0, 0, width, height, windowDeviceContext, 0, 0, CAPTUREBLT | SRCCOPY);
SelectObject(destDeviceContext, oldObject);
DeleteDC(destDeviceContext);
ReleaseDC(windowHandle, destDeviceContext);
Image screenshot = Image.FromHbitmap(bitmapHandle);
DeleteObject(bitmapHandle);
screenshot.Save("C:\\Screenshots\\" + windowHandle.ToString() + ".png", System.Drawing.Imaging.ImageFormat.Png);
}
Это - общий ряд Windows API calls для получения снимка экрана окна.
Обратите внимание, что я не ищу альтернативные способы получить снимки экрана. Я хотел бы для сравнения скорости этого (фиксированного) подхода и скорости.NET Graphics.CopyFromScreen()
метод.
Проблема, когда я пытаюсь сделать снимок экрана максимизируемого окна, запускающего Windows 7, строка заголовка и граница (и иногда другие части окна) являются черными.
Я думаю, что это вызывается или фактом, окно разделено на уровни или потому что строкой заголовка окна управляет само окно, и поэтому к информации о пикселе нельзя получить доступ (поскольку я читал где-нибудь).
У кого-либо есть идея, как зафиксировать это поведение?
Вы вызываете все виды API-интерфейсов, от которых следует держаться подальше, потому что создание снимков экрана удобно в .NET framework. Это намного проще, чем вы думаете:
var screen = Screen.PrimaryScreen;
using (var bitmap = new Bitmap(screen.Bounds.Width, screen.Bounds.Height))
using (var graphics = Graphics.FromImage(bitmap))
{
graphics.CopyFromScreen(new Point(screen.Bounds.Left, screen.Bounds.Top), new Point(0, 0), screen.Bounds.Size);
bitmap.Save("Test.png", ImageFormat.Png);
}