1

我正在尝试通过调用 Windows API 使用 C# .NET 截取窗口的屏幕截图。我想出了以下代码:

    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 调用。

请注意,我不是在寻找获取屏幕截图的替代方法。我想比较这种(固定)方法的速度和 .NETGraphics.CopyFromScreen()方法的速度。

问题是,当我尝试截取运行 Windows 7 的最大化窗口的屏幕截图时,标题栏和边框(有时还有窗口的其他部分)为 black

我认为这是由于窗口是分层的,或者是因为窗口的标题栏由窗口本身管理,因此无法访问像素信息(正如我在某处读过的那样)。

有谁知道如何解决这种行为?

4

1 回答 1

2

您正在调用您应该远离的各种 API,因为在 .NET 框架中可以轻松地进行截图。它比你想象的要简单得多:

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);
}
于 2010-07-26T11:42:40.280 回答