public static Bitmap MakeSnapshot(IntPtr AppWndHandle, bool IsClientWnd) { if (AppWndHandle == IntPtr.Zero || !User32.IsWindow(AppWndHandle) || !User32.IsWindowVisible(AppWndHandle)) { return(null); } if (User32.IsIconic(AppWndHandle)) { User32.ShowWindow(AppWndHandle, WindowShowStyle.Restore);//show it } if (!User32.SetForegroundWindow(AppWndHandle)) { return(null); //can't bring it to front } System.Threading.Thread.Sleep(1000); //give it some time to redraw RECT appRect; bool res = IsClientWnd ? User32.GetClientRect(AppWndHandle, out appRect) : User32.GetWindowRect(AppWndHandle, out appRect); if (!res || appRect.Height == 0 || appRect.Width == 0) { return(null);//some hidden window } // calculate the app rectangle if (IsClientWnd) { Point lt = new Point(appRect.Left, appRect.Top); Point rb = new Point(appRect.Right, appRect.Bottom); User32.ClientToScreen(AppWndHandle, ref lt); User32.ClientToScreen(AppWndHandle, ref rb); appRect.Left = lt.X; appRect.Top = lt.Y; appRect.Right = rb.X; appRect.Bottom = rb.Y; } //Intersect with the Desktop rectangle and get what's visible IntPtr DesktopHandle = User32.GetDesktopWindow(); RECT desktopRect; User32.GetWindowRect(DesktopHandle, out desktopRect); RECT visibleRect; if (!User32.IntersectRect (out visibleRect, ref desktopRect, ref appRect)) { visibleRect = appRect; } if (User32.IsRectEmpty(ref visibleRect)) { return(null); } int Width = visibleRect.Width; int Height = visibleRect.Height; IntPtr hdcTo = IntPtr.Zero; IntPtr hdcFrom = IntPtr.Zero; IntPtr hBitmap = IntPtr.Zero; try { Bitmap clsRet = null; // get device context of the window... hdcFrom = IsClientWnd ? User32.GetDC(AppWndHandle) : User32.GetWindowDC(AppWndHandle); // create dc that we can draw to... hdcTo = GDI32.CreateCompatibleDC(hdcFrom); hBitmap = GDI32.CreateCompatibleBitmap(hdcFrom, Width, Height); // validate if (hBitmap != IntPtr.Zero) { // adjust and copy int x = appRect.Left < 0 ? -appRect.Left : 0; int y = appRect.Top < 0 ? -appRect.Top : 0; IntPtr hLocalBitmap = GDI32.SelectObject(hdcTo, hBitmap); GDI32.BitBlt(hdcTo, 0, 0, Width, Height, hdcFrom, x, y, GDI32.SRCCOPY); GDI32.SelectObject(hdcTo, hLocalBitmap); // create bitmap for window image... clsRet = System.Drawing.Image.FromHbitmap(hBitmap); } return(clsRet); } finally { // release the unmanaged resources if (hdcFrom != IntPtr.Zero) { User32.ReleaseDC(AppWndHandle, hdcFrom); } if (hdcTo != IntPtr.Zero) { GDI32.DeleteDC(hdcTo); } if (hBitmap != IntPtr.Zero) { GDI32.DeleteObject(hBitmap); } } }