/// <summary>
/// Captures a screenshot of the specified window at the specified
/// bitmap size. <para/>NOTE: This method will not accurately capture controls
/// that are hidden or obstructed (partially or completely) by another control (e.g. hidden tabs,
/// or MDI child windows that are obstructed by other child windows/forms).
/// </summary>
/// <param name="windowHandle">The window handle.</param>
/// <param name="bitmapSize">The requested bitmap size.</param>
/// <returns>A screen capture of the window.</returns>
public static Bitmap GrabWindowBitmap(IntPtr windowHandle, System.Drawing.Size bitmapSize)
{
if (bitmapSize.Height <= 0 || bitmapSize.Width <= 0)
{
return(null);
}
IntPtr windowDC = IntPtr.Zero;
try
{
windowDC = HandlerNativeMethods.GetWindowDC(windowHandle);
_ = HandlerNativeMethods.GetClientSize(windowHandle, out System.Drawing.Size realWindowSize);
if (realWindowSize == System.Drawing.Size.Empty)
{
realWindowSize = new System.Drawing.Size(200, 200);
}
System.Drawing.Size size = (bitmapSize == System.Drawing.Size.Empty) ?
realWindowSize : bitmapSize;
Bitmap targetBitmap = null;
try
{
targetBitmap = new Bitmap(size.Width, size.Height);
using (var targetGr = Graphics.FromImage(targetBitmap))
{
IntPtr targetDC = targetGr.GetHdc();
uint operation = 0x00CC0020 /*SRCCOPY*/;
System.Drawing.Size ncArea = Shell.DesktopWindowManager.GetNonClientArea(windowHandle);
bool success = GDI.StretchBlt(
targetDC, 0, 0, targetBitmap.Width, targetBitmap.Height,
windowDC, ncArea.Width, ncArea.Height, realWindowSize.Width,
realWindowSize.Height, operation);
targetGr.ReleaseHdc(targetDC);
return(success ? targetBitmap : null);
}
}
catch
{
targetBitmap?.Dispose();
throw;
}
}
finally
{
if (windowDC != IntPtr.Zero)
{
_ = HandlerNativeMethods.ReleaseDC(windowHandle, windowDC);
}
}
}