I am attempting to take a screenshot of a window using C# .NET by calling Windows API. I came up with the following code:
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);
}
It is a common series of Windows API calls to obtain window screenshot.
Note that I am not looking for alternative ways of obtaining screenshots. I would like to to compare speed of this (fixed) approach and the speed of .NET Graphics.CopyFromScreen()
method.
The problem is, when I attempt to take a screenshot of a maximized window running Windows 7, the titlebar and the border (and sometimes other parts of the window) are black.
I think this is caused either by the fact the window is layered or because the title bar of the window is managed by the window itself and therefore the pixel information cannot be accessed (as I have read somewhere).
Does anyone have an idea how to fix this behaviour?