static Bitmap CaptureFromScreen(IntPtr hwnd, WindowInfo wi)
        {
            using (var guard = new ForegroundWindowGuard()) {
                if (guard.ForegroundWindow != hwnd)
                    Utils.ForceForegroundWindow(hwnd);

                Bitmap windowBitmap = new Bitmap(
                    wi.rcWindow.right - wi.rcWindow.left,
                    wi.rcWindow.bottom - wi.rcWindow.top,
                    System.Drawing.Imaging.PixelFormat.Format32bppRgb
                );

                Graphics graphicsWindow = Graphics.FromImage(windowBitmap);

                graphicsWindow.CopyFromScreen(
                    new Point(wi.rcWindow.left, wi.rcWindow.top),
                    Point.Empty,
                    windowBitmap.Size,
                    CopyPixelOperation.SourceCopy
                );

                return windowBitmap;
            }
        }
 static extern IntPtr GetWindowInfo(IntPtr hWnd, out WindowInfo pwi);
 public WindowBorderOnScreenFlags(WindowInfo wi, Screen s)
 {
     leftBorderOnScreen   = (wi.rcWindow.left >= s.WorkingArea.Left) && (wi.rcWindow.left < s.WorkingArea.Right);
     rightBorderOnScreen  = (wi.rcWindow.right > s.WorkingArea.Left) && (wi.rcWindow.right <= s.WorkingArea.Right);
     topBorderOnScreen    = (wi.rcWindow.top >= s.WorkingArea.Top) && (wi.rcWindow.top < s.WorkingArea.Bottom);
     bottomBorderOnScreen = (wi.rcWindow.bottom > s.WorkingArea.Top) && (wi.rcWindow.bottom <= s.WorkingArea.Bottom);
 }
        static Bitmap PrintWindow(IntPtr hwnd, WindowInfo wi, string processName)
        {
            Bitmap windowBitmap = new Bitmap(
                wi.rcWindow.right - wi.rcWindow.left,
                wi.rcWindow.bottom - wi.rcWindow.top,
                System.Drawing.Imaging.PixelFormat.Format32bppRgb
            );

            Graphics graphicsWindow = Graphics.FromImage(windowBitmap);
            IntPtr   hdc            = graphicsWindow.GetHdc();

            PrintWindow(hwnd, hdc, 0);

            if (processName == "iexplore") // HACK: for IE
                PrintWindow(hwnd, hdc, 0);

            graphicsWindow.ReleaseHdc(hdc);
            graphicsWindow.Flush();

            return windowBitmap;
        }
        static int GetWindowVisibleArea(WindowInfo wi, Screen s)
        {
            WindowBorderOnScreenFlags flags = new WindowBorderOnScreenFlags(wi, s);

            int visibleWidth  = 0;
            int visibleHeight = 0;

            if (flags.leftBorderOnScreen)
                visibleWidth = flags.rightBorderOnScreen ? wi.rcWindow.right - wi.rcWindow.left : s.WorkingArea.Right - wi.rcWindow.left;
            else if (flags.rightBorderOnScreen)
                visibleWidth = wi.rcWindow.right - s.WorkingArea.Left;

            if (flags.topBorderOnScreen)
                visibleHeight = flags.bottomBorderOnScreen ? wi.rcWindow.bottom - wi.rcWindow.top : s.WorkingArea.Bottom - wi.rcWindow.top;
            else if (flags.bottomBorderOnScreen)
                visibleHeight = wi.rcWindow.bottom - s.WorkingArea.Top;

            return visibleWidth * visibleHeight;
        }
        static Rectangle GetVisibleRectangle(WindowInfo wi, Screen s)
        {
            Rectangle resultWindowRect = new Rectangle(
                wi.rcWindow.left,
                wi.rcWindow.top,
                wi.rcWindow.right - wi.rcWindow.left,
                wi.rcWindow.bottom - wi.rcWindow.top
            );

            WindowBorderOnScreenFlags flags = new WindowBorderOnScreenFlags(wi, s);

            if (!flags.leftBorderOnScreen)
                resultWindowRect.X = s.WorkingArea.X;
            else {
                resultWindowRect.X = !flags.rightBorderOnScreen ?
                    s.WorkingArea.Right - wi.rcWindow.right + wi.rcWindow.left :
                    wi.rcWindow.left;
            }

            if (!flags.topBorderOnScreen)
                resultWindowRect.Y = s.WorkingArea.Y;
            else {
                resultWindowRect.Y = !flags.bottomBorderOnScreen ?
                    s.WorkingArea.Bottom - wi.rcWindow.bottom + wi.rcWindow.top :
                    wi.rcWindow.top;
            }

            return resultWindowRect;
        }