示例#1
0
        internal static Bitmap MakeSnapshot(IntPtr parentWinHandle,
                                            bool isClientWnd, Win32Api.WindowShowStyle nCmdShow)
        {
            if (parentWinHandle == IntPtr.Zero || !Win32Api.IsWindow(parentWinHandle) ||
                !Win32Api.IsWindowVisible(parentWinHandle))
            {
                return(null);
            }
            if (Win32Api.IsIconic(parentWinHandle))
            {
                Win32Api.ShowWindow(parentWinHandle, nCmdShow);//show it
            }
            if (!Win32Api.SetForegroundWindow(parentWinHandle))
            {
                return(null);//can't bring it to front
            }
            Win32Api.ShowWindow(parentWinHandle, Win32Api.WindowShowStyle.ShowMinimized);
            Win32Api.ShowWindow(parentWinHandle, Win32Api.WindowShowStyle.Restore);


            var appWndHandle = parentWinHandle;

            System.Threading.Thread.Sleep(1000);//give it some time to redraw
            RECT appRect;
            bool res = Win32Api.GetWindowRect
                           (appWndHandle, out appRect);

            if (!res || appRect.Height == 0 || appRect.Width == 0)
            {
                return(null);//some hidden window
            }
            // calculate the app rectangle

            //Intersect with the Desktop rectangle and get what's visible
            IntPtr DesktopHandle = Win32Api.GetDesktopWindow();
            RECT   desktopRect;

            Win32Api.GetWindowRect(DesktopHandle, out desktopRect);
            RECT visibleRect;

            if (!Win32Api.IntersectRect
                    (out visibleRect, ref desktopRect, ref appRect))
            {
                visibleRect = appRect;
            }
            if (Win32Api.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 result = null;

                // get device context of the window...
                hdcFrom = Win32Api.GetDC(appWndHandle);

                // create dc that we can draw to...
                hdcTo   = Win32Api.CreateCompatibleDC(hdcFrom);
                hBitmap = Win32Api.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 = Win32Api.SelectObject(hdcTo, hBitmap);

                    Win32Api.BitBlt(hdcTo, 0, 0, Width, Height,
                                    hdcFrom, 0, 0, Win32Api.SRCCOPY);

                    Win32Api.SelectObject(hdcTo, hLocalBitmap);

                    //  create bitmap for window image...
                    using (var screenShot = Image.FromHbitmap(hBitmap))
                    {
                        // For some reason, the area that was reserved for the screenshot is bigger than the actual
                        // result. We remove the black borders to the right and bottom here
                        result = CropBitmap(screenShot);
                    }
                }

                return(result);
            }
            finally
            {
                //  release the unmanaged resources
                if (hdcFrom != IntPtr.Zero)
                {
                    Win32Api.ReleaseDC(appWndHandle, hdcFrom);
                }
                if (hdcTo != IntPtr.Zero)
                {
                    Win32Api.DeleteDC(hdcTo);
                }
                if (hBitmap != IntPtr.Zero)
                {
                    Win32Api.DeleteObject(hBitmap);
                }
            }
        }
示例#2
0
        /// <summary>
        /// Erzeugt einen Screenshot dieses Fensters.
        /// </summary>
        /// <param name="isClientWnd">Handelt es sich um das Handle eines Client-Fensters oder nícht.</param>
        /// <param name="nCmdShow">Der WindowShowStyle.</param>
        /// <param name="timeForRedrawing">Die Zeit, die gewartet werden soll, bis der Screenshot gemacht wird.</param>
        /// <returns>Der Screenshot oder <see langword="null" />, wenn nicht ermittelbar.</returns>
        public Bitmap MakeScreenshot(bool isClientWnd = false,
                                     Win32Api.WindowShowStyle nCmdShow = Win32Api.WindowShowStyle.Restore,
                                     TimeSpan?timeForRedrawing         = null)
        {
            var appWndHandle = this.HWnd;

            if (appWndHandle == IntPtr.Zero ||
                !Win32Api.IsWindow(appWndHandle) ||
                !Win32Api.IsWindowVisible(appWndHandle))
            {
                return(null);
            }

            if (Win32Api.IsIconic(appWndHandle))
            {
                Win32Api.ShowWindow(appWndHandle, nCmdShow);    // show it
            }

            if (!Win32Api.SetForegroundWindow(appWndHandle))
            {
                return(null);    // can't bring it to front
            }

            if (timeForRedrawing.HasValue)
            {
                // give it some time to redraw
                Thread.Sleep(timeForRedrawing.Value);
            }

            RECT appRect;
            var  res = isClientWnd ? Win32Api.GetClientRect(appWndHandle, out appRect) : Win32Api.GetWindowRect(appWndHandle, out appRect);

            if (!res ||
                appRect.Height == 0 ||
                appRect.Width == 0)
            {
                return(null);    // some hidden window
            }

            if (isClientWnd)
            {
                var lt = new Point(appRect.Left, appRect.Top);
                var rb = new Point(appRect.Right, appRect.Bottom);
                Win32Api.ClientToScreen(appWndHandle, ref lt);
                Win32Api.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
            var  desktopHandle = Win32Api.GetDesktopWindow();
            RECT desktopRect;

            Win32Api.GetWindowRect(desktopHandle, out desktopRect);

            RECT visibleRect;

            if (!Win32Api.IntersectRect(out visibleRect, ref desktopRect, ref appRect))
            {
                visibleRect = appRect;
            }

            if (Win32Api.IsRectEmpty(ref visibleRect))
            {
                return(null);
            }

            var width   = visibleRect.Width;
            var height  = visibleRect.Height;
            var hdcTo   = IntPtr.Zero;
            var hdcFrom = IntPtr.Zero;
            var hBitmap = IntPtr.Zero;

            try
            {
                Bitmap clsRet = null;

                // get device context of the window...
                hdcFrom = isClientWnd ? Win32Api.GetDC(appWndHandle) : Win32Api.GetWindowDC(appWndHandle);

                // create dc that we can draw to...
                hdcTo   = Win32Api.CreateCompatibleDC(hdcFrom);
                hBitmap = Win32Api.CreateCompatibleBitmap(hdcFrom, width, height);

                //  validate...
                if (hBitmap != IntPtr.Zero)
                {
                    // copy...
                    var x = appRect.Left < 0 ? -appRect.Left : 0;
                    var y = appRect.Top < 0 ? -appRect.Top : 0;

                    var hLocalBitmap = Win32Api.SelectObject(hdcTo, hBitmap);
                    Win32Api.BitBlt(hdcTo, 0, 0, width, height, hdcFrom, x, y, Win32Api.SRCCOPY);
                    Win32Api.SelectObject(hdcTo, hLocalBitmap);

                    // create bitmap for window image...
                    clsRet = System.Drawing.Image.FromHbitmap(hBitmap);
                }

                return(clsRet);
            }
            finally
            {
                //  release...

                if (hdcFrom != IntPtr.Zero)
                {
                    Win32Api.ReleaseDC(appWndHandle, hdcFrom);
                }

                if (hdcTo != IntPtr.Zero)
                {
                    Win32Api.DeleteDC(hdcTo);
                }

                if (hBitmap != IntPtr.Zero)
                {
                    Win32Api.DeleteObject(hBitmap);
                }
            }
        }