示例#1
0
        /// <summary>
        /// Capture the supplied Window
        /// </summary>
        /// <param name="windowToCapture">Window to capture</param>
        /// <param name="captureForWindow">The capture to store the details</param>
        /// <param name="windowCaptureMode">What WindowCaptureMode to use</param>
        /// <returns></returns>
        public static ICapture CaptureWindow(WindowDetails windowToCapture, ICapture captureForWindow, WindowCaptureMode windowCaptureMode)
        {
            if (captureForWindow == null) {
                captureForWindow = new Capture();
            }
            Rectangle windowRectangle = windowToCapture.WindowRectangle;

            // When Vista & DWM (Aero) enabled
            bool dwmEnabled = DWM.isDWMEnabled();
            // get process name to be able to exclude certain processes from certain capture modes
            using (Process process = windowToCapture.Process) {
                bool isAutoMode = windowCaptureMode == WindowCaptureMode.Auto;
                // For WindowCaptureMode.Auto we check:
                // 1) Is window IE, use IE Capture
                // 2) Is Windows >= Vista & DWM enabled: use DWM
                // 3) Otherwise use GDI (Screen might be also okay but might lose content)
                if (isAutoMode) {
                    if (conf.IECapture && IECaptureHelper.IsIEWindow(windowToCapture)) {
                        try {
                            ICapture ieCapture = IECaptureHelper.CaptureIE(captureForWindow, windowToCapture);
                            if (ieCapture != null) {
                                return ieCapture;
                            }
                        } catch (Exception ex) {
                            LOG.WarnFormat("Problem capturing IE, skipping to normal capture. Exception message was: {0}", ex.Message);
                        }
                    }

                    // Take default screen
                    windowCaptureMode = WindowCaptureMode.Screen;

                    // Change to GDI, if allowed
                    if (!windowToCapture.isMetroApp && WindowCapture.IsGdiAllowed(process)) {
                        if (!dwmEnabled && isWPF(process)) {
                            // do not use GDI, as DWM is not enabled and the application uses PresentationFramework.dll -> isWPF
                            LOG.InfoFormat("Not using GDI for windows of process {0}, as the process uses WPF", process.ProcessName);
                        } else {
                            windowCaptureMode = WindowCaptureMode.GDI;
                        }
                    }

                    // Change to DWM, if enabled and allowed
                    if (dwmEnabled) {
                        if (windowToCapture.isMetroApp || WindowCapture.IsDwmAllowed(process)) {
                            windowCaptureMode = WindowCaptureMode.Aero;
                        }
                    }
                } else if (windowCaptureMode == WindowCaptureMode.Aero || windowCaptureMode == WindowCaptureMode.AeroTransparent) {
                    if (!dwmEnabled || (!windowToCapture.isMetroApp && !WindowCapture.IsDwmAllowed(process))) {
                        // Take default screen
                        windowCaptureMode = WindowCaptureMode.Screen;
                        // Change to GDI, if allowed
                        if (WindowCapture.IsGdiAllowed(process)) {
                            windowCaptureMode = WindowCaptureMode.GDI;
                        }
                    }
                } else if (windowCaptureMode == WindowCaptureMode.GDI && !WindowCapture.IsGdiAllowed(process)) {
                    // GDI not allowed, take screen
                    windowCaptureMode = WindowCaptureMode.Screen;
                }

                LOG.InfoFormat("Capturing window with mode {0}", windowCaptureMode);
                bool captureTaken = false;
                windowRectangle.Intersect(captureForWindow.ScreenBounds);
                // Try to capture
                while (!captureTaken) {
                    ICapture tmpCapture = null;
                    switch (windowCaptureMode) {
                        case WindowCaptureMode.GDI:
                            if (WindowCapture.IsGdiAllowed(process)) {
                                if (windowToCapture.Iconic) {
                                    // Restore the window making sure it's visible!
                                    windowToCapture.Restore();
                                } else {
                                    windowToCapture.ToForeground();
                                }
                                tmpCapture = windowToCapture.CaptureGDIWindow(captureForWindow);
                                if (tmpCapture != null) {
                                    // check if GDI capture any good, by comparing it with the screen content
                                    int blackCountGDI = ImageHelper.CountColor(tmpCapture.Image, Color.Black, false);
                                    int GDIPixels = tmpCapture.Image.Width * tmpCapture.Image.Height;
                                    int blackPercentageGDI = (blackCountGDI * 100) / GDIPixels;
                                    if (blackPercentageGDI >= 1) {
                                        int screenPixels = windowRectangle.Width * windowRectangle.Height;
                                        using (ICapture screenCapture = new Capture()) {
                                            screenCapture.CaptureDetails = captureForWindow.CaptureDetails;
                                            if (WindowCapture.CaptureRectangleFromDesktopScreen(screenCapture, windowRectangle) != null) {
                                                int blackCountScreen = ImageHelper.CountColor(screenCapture.Image, Color.Black, false);
                                                int blackPercentageScreen = (blackCountScreen * 100) / screenPixels;
                                                if (screenPixels == GDIPixels) {
                                                    // "easy compare", both have the same size
                                                    // If GDI has more black, use the screen capture.
                                                    if (blackPercentageGDI > blackPercentageScreen) {
                                                        LOG.Debug("Using screen capture, as GDI had additional black.");
                                                        // changeing the image will automatically dispose the previous
                                                        tmpCapture.Image = screenCapture.Image;
                                                        // Make sure it's not disposed, else the picture is gone!
                                                        screenCapture.NullImage();
                                                    }
                                                } else if (screenPixels < GDIPixels) {
                                                    // Screen capture is cropped, window is outside of screen
                                                    if (blackPercentageGDI > 50 && blackPercentageGDI > blackPercentageScreen) {
                                                        LOG.Debug("Using screen capture, as GDI had additional black.");
                                                        // changeing the image will automatically dispose the previous
                                                        tmpCapture.Image = screenCapture.Image;
                                                        // Make sure it's not disposed, else the picture is gone!
                                                        screenCapture.NullImage();
                                                    }
                                                } else {
                                                    // Use the GDI capture by doing nothing
                                                    LOG.Debug("This should not happen, how can there be more screen as GDI pixels?");
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            if (tmpCapture != null) {
                                captureForWindow = tmpCapture;
                                captureTaken = true;
                            } else {
                                // A problem, try Screen
                                windowCaptureMode = WindowCaptureMode.Screen;
                            }
                            break;
                        case WindowCaptureMode.Aero:
                        case WindowCaptureMode.AeroTransparent:
                            if (windowToCapture.isMetroApp || WindowCapture.IsDwmAllowed(process)) {
                                tmpCapture = windowToCapture.CaptureDWMWindow(captureForWindow, windowCaptureMode, isAutoMode);
                            }
                            if (tmpCapture != null) {
                                captureForWindow = tmpCapture;
                                captureTaken = true;
                            } else {
                                // A problem, try GDI
                                windowCaptureMode = WindowCaptureMode.GDI;
                            }
                            break;
                        default:
                            // Screen capture
                            if (windowToCapture.Iconic) {
                                // Restore the window making sure it's visible!
                                windowToCapture.Restore();
                            } else {
                                windowToCapture.ToForeground();
                            }

                            try {
                                captureForWindow = WindowCapture.CaptureRectangleFromDesktopScreen(captureForWindow, windowRectangle);
                                captureTaken = true;
                            } catch (Exception e) {
                                LOG.Error("Problem capturing", e);
                                return null;
                            }
                            break;
                    }
                }
            }

            if (captureForWindow != null) {
                if (windowToCapture != null) {
                    captureForWindow.CaptureDetails.Title = windowToCapture.Text;
                }
            }

            return captureForWindow;
        }
        /// <summary>
        /// Capture the supplied Window
        /// </summary>
        /// <param name="windowToCapture">Window to capture</param>
        /// <param name="captureForWindow">The capture to store the details</param>
        /// <param name="windowCaptureMode">What WindowCaptureMode to use</param>
        /// <returns></returns>
        public static ICapture CaptureWindow(WindowDetails windowToCapture, ICapture captureForWindow, WindowCaptureMode windowCaptureMode)
        {
            if (captureForWindow == null)
            {
                captureForWindow = new Capture();
            }
            Rectangle windowRectangle = windowToCapture.WindowRectangle;

            if (windowToCapture.Iconic)
            {
                // Restore the window making sure it's visible!
                windowToCapture.Restore();
            }

            // When Vista & DWM (Aero) enabled
            bool dwmEnabled = DWM.isDWMEnabled();
            // get process name to be able to exclude certain processes from certain capture modes
            Process process    = windowToCapture.Process;
            bool    isAutoMode = windowCaptureMode == WindowCaptureMode.Auto;

            // For WindowCaptureMode.Auto we check:
            // 1) Is window IE, use IE Capture
            // 2) Is Windows >= Vista & DWM enabled: use DWM
            // 3) Otherwise use GDI (Screen might be also okay but might lose content)
            if (isAutoMode)
            {
                if (conf.IECapture && windowToCapture.ClassName == "IEFrame")
                {
                    try
                    {
                        ICapture ieCapture = IECaptureHelper.CaptureIE(captureForWindow);
                        if (ieCapture != null)
                        {
                            return(ieCapture);
                        }
                    }
                    catch (Exception ex)
                    {
                        LOG.WarnFormat("Problem capturing IE, skipping to normal capture. Exception message was: {0}", ex.Message);
                    }
                }

                // Take default screen
                windowCaptureMode = WindowCaptureMode.Screen;

                // Change to GDI, if allowed
                if (conf.isGDIAllowed(process))
                {
                    if (!dwmEnabled && isWPF(process))
                    {
                        // do not use GDI, as DWM is not enabled and the application uses PresentationFramework.dll -> isWPF
                        LOG.InfoFormat("Not using GDI for windows of process {0}, as the process uses WPF", process.ProcessName);
                    }
                    else
                    {
                        windowCaptureMode = WindowCaptureMode.GDI;
                    }
                }

                // Change to DWM, if enabled and allowed
                if (dwmEnabled)
                {
                    if (conf.isDWMAllowed(process))
                    {
                        windowCaptureMode = WindowCaptureMode.Aero;
                    }
                }
            }
            else if (windowCaptureMode == WindowCaptureMode.Aero || windowCaptureMode == WindowCaptureMode.AeroTransparent)
            {
                if (!dwmEnabled || !conf.isDWMAllowed(process))
                {
                    // Take default screen
                    windowCaptureMode = WindowCaptureMode.Screen;
                    // Change to GDI, if allowed
                    if (conf.isGDIAllowed(process))
                    {
                        windowCaptureMode = WindowCaptureMode.GDI;
                    }
                }
            }
            else if (windowCaptureMode == WindowCaptureMode.GDI && !conf.isGDIAllowed(process))
            {
                // GDI not allowed, take screen
                windowCaptureMode = WindowCaptureMode.Screen;
            }

            LOG.InfoFormat("Capturing window with mode {0}", windowCaptureMode);
            bool captureTaken = false;

            // Try to capture
            while (!captureTaken)
            {
                if (windowCaptureMode == WindowCaptureMode.GDI)
                {
                    ICapture tmpCapture = null;
                    if (conf.isGDIAllowed(process))
                    {
                        tmpCapture = windowToCapture.CaptureWindow(captureForWindow);
                    }
                    if (tmpCapture != null)
                    {
                        captureForWindow = tmpCapture;
                        captureTaken     = true;
                    }
                    else
                    {
                        // A problem, try Screen
                        windowCaptureMode = WindowCaptureMode.Screen;
                    }
                }
                else if (windowCaptureMode == WindowCaptureMode.Aero || windowCaptureMode == WindowCaptureMode.AeroTransparent)
                {
                    ICapture tmpCapture = null;
                    if (conf.isDWMAllowed(process))
                    {
                        tmpCapture = windowToCapture.CaptureDWMWindow(captureForWindow, windowCaptureMode, isAutoMode);
                    }
                    if (tmpCapture != null)
                    {
                        captureForWindow = tmpCapture;
                        captureTaken     = true;
                    }
                    else
                    {
                        // A problem, try GDI
                        windowCaptureMode = WindowCaptureMode.GDI;
                    }
                }
                else
                {
                    // Screen capture
                    windowRectangle.Intersect(captureForWindow.ScreenBounds);
                    try
                    {
                        captureForWindow = WindowCapture.CaptureRectangle(captureForWindow, windowRectangle);
                        captureTaken     = true;
                    }
                    catch (Exception e)
                    {
                        LOG.Error("Problem capturing", e);
                        return(null);
                    }
                }
            }

            if (captureForWindow != null && windowToCapture != null)
            {
                captureForWindow.CaptureDetails.Title = windowToCapture.Text;
                ((Bitmap)captureForWindow.Image).SetResolution(captureForWindow.CaptureDetails.DpiX, captureForWindow.CaptureDetails.DpiY);
            }

            return(captureForWindow);
        }
示例#3
0
        /// <summary>
        /// Capture the supplied Window
        /// </summary>
        /// <param name="windowToCapture">Window to capture</param>
        /// <param name="captureForWindow">The capture to store the details</param>
        /// <param name="windowCaptureMode">What WindowCaptureMode to use</param>
        /// <returns></returns>
        public static ICapture CaptureWindow(WindowDetails windowToCapture, ICapture captureForWindow, WindowCaptureMode windowCaptureMode)
        {
            if (captureForWindow == null)
             {
            captureForWindow = new Capture();
             }
             Rectangle windowRectangle = windowToCapture.ClientRectangle;
             if (windowToCapture.Iconic)
             {
            // Restore the window making sure it's visible!
            windowToCapture.Restore();
             }

             // When Vista & DWM (Aero) enabled
             bool dwmEnabled = DWM.isDWMEnabled();

             // For WindowCaptureMode.Auto we check:
             // 1) Is window IE, use IE Capture
             // 2) Is Windows >= Vista & DWM enabled: use DWM
             // 3) Otherwise use GDI (Screen might be also okay but might lose content)
             if (windowCaptureMode == WindowCaptureMode.Auto)
             {
            if (conf.IECapture && windowToCapture.ClassName == "IEFrame")
            {
               try
               {
                  ICapture ieCapture = IECaptureHelper.CaptureIE(captureForWindow);
                  if (ieCapture != null)
                  {
                     return ieCapture;
                  }
               }
               catch (Exception ex)
               {
                  LOG.WarnFormat("Problem capturing IE, skipping to normal capture. Exception message was: {0}", ex.Message);
               }
            }

            // Take default GDI
            windowCaptureMode = WindowCaptureMode.GDI;
            // Take DWM if enabled
            if (dwmEnabled)
            {
               windowCaptureMode = WindowCaptureMode.Aero;
            }
             }
             else if (windowCaptureMode == WindowCaptureMode.Aero || windowCaptureMode == WindowCaptureMode.AeroTransparent)
             {
            if (!dwmEnabled)
            {
               windowCaptureMode = WindowCaptureMode.GDI;
            }
             }
             LOG.DebugFormat("Capturing window with mode {0}", windowCaptureMode);
             switch (windowCaptureMode)
             {
            case WindowCaptureMode.GDI:
               // GDI
               captureForWindow = windowToCapture.CaptureWindow(captureForWindow);
               break;
            case WindowCaptureMode.Aero:
            case WindowCaptureMode.AeroTransparent:
               // DWM
               captureForWindow = windowToCapture.CaptureDWMWindow(captureForWindow, windowCaptureMode);
               break;
            case WindowCaptureMode.Screen:
            default:
               // Screen capture
               windowRectangle.Intersect(captureForWindow.ScreenBounds);
               try
               {
                  captureForWindow = WindowCapture.CaptureRectangle(captureForWindow, windowRectangle);
               }
               catch (Exception e)
               {
                  LOG.Error("Problem capturing", e);
                  return null;
               }
               break;
             }
             captureForWindow.CaptureDetails.Title = windowToCapture.Text;
             ((Bitmap)captureForWindow.Image).SetResolution(captureForWindow.CaptureDetails.DpiX, captureForWindow.CaptureDetails.DpiY);
             return captureForWindow;
        }
        /// <summary>
        /// Capture the supplied Window
        /// </summary>
        /// <param name="windowToCapture">Window to capture</param>
        /// <param name="captureForWindow">The capture to store the details</param>
        /// <param name="windowCaptureMode">What WindowCaptureMode to use</param>
        /// <returns></returns>
        public static ICapture CaptureWindow(WindowDetails windowToCapture, ICapture captureForWindow, WindowCaptureMode windowCaptureMode)
        {
            if (captureForWindow == null)
            {
                captureForWindow = new Capture();
            }
            Rectangle windowRectangle = windowToCapture.WindowRectangle;
            if (windowToCapture.Iconic)
            {
                // Restore the window making sure it's visible!
                windowToCapture.Restore();
            }

            // When Vista & DWM (Aero) enabled
            bool dwmEnabled = DWM.isDWMEnabled();
            // get process name to be able to exclude certain processes from certain capture modes
            Process process = windowToCapture.Process;
            bool isAutoMode = windowCaptureMode == WindowCaptureMode.Auto;
            // For WindowCaptureMode.Auto we check:
            // 1) Is window IE, use IE Capture
            // 2) Is Windows >= Vista & DWM enabled: use DWM
            // 3) Otherwise use GDI (Screen might be also okay but might lose content)
            if (isAutoMode)
            {
                if (conf.IECapture && windowToCapture.ClassName == "IEFrame")
                {
                    try
                    {
                        ICapture ieCapture = IECaptureHelper.CaptureIE(captureForWindow);
                        if (ieCapture != null)
                        {
                            return ieCapture;
                        }
                    }
                    catch (Exception ex)
                    {
                        LOG.WarnFormat("Problem capturing IE, skipping to normal capture. Exception message was: {0}", ex.Message);
                    }
                }

                // Take default screen
                windowCaptureMode = WindowCaptureMode.Screen;

                // Change to GDI, if allowed
                if (conf.isGDIAllowed(process))
                {
                    if (!dwmEnabled && isWPF(process))
                    {
                        // do not use GDI, as DWM is not enabled and the application uses PresentationFramework.dll -> isWPF
                        LOG.InfoFormat("Not using GDI for windows of process {0}, as the process uses WPF", process.ProcessName);
                    }
                    else
                    {
                        windowCaptureMode = WindowCaptureMode.GDI;
                    }
                }

                // Change to DWM, if enabled and allowed
                if (dwmEnabled)
                {
                    if (conf.isDWMAllowed(process))
                    {
                        windowCaptureMode = WindowCaptureMode.Aero;
                    }
                }
            }
            else if (windowCaptureMode == WindowCaptureMode.Aero || windowCaptureMode == WindowCaptureMode.AeroTransparent)
            {
                if (!dwmEnabled || !conf.isDWMAllowed(process))
                {
                    // Take default screen
                    windowCaptureMode = WindowCaptureMode.Screen;
                    // Change to GDI, if allowed
                    if (conf.isGDIAllowed(process))
                    {
                        windowCaptureMode = WindowCaptureMode.GDI;
                    }
                }
            }
            else if (windowCaptureMode == WindowCaptureMode.GDI && !conf.isGDIAllowed(process))
            {
                // GDI not allowed, take screen
                windowCaptureMode = WindowCaptureMode.Screen;
            }

            LOG.InfoFormat("Capturing window with mode {0}", windowCaptureMode);
            bool captureTaken = false;
            // Try to capture
            while (!captureTaken)
            {
                if (windowCaptureMode == WindowCaptureMode.GDI)
                {
                    ICapture tmpCapture = null;
                    if (conf.isGDIAllowed(process))
                    {
                        tmpCapture = windowToCapture.CaptureWindow(captureForWindow);
                    }
                    if (tmpCapture != null)
                    {
                        captureForWindow = tmpCapture;
                        captureTaken = true;
                    }
                    else
                    {
                        // A problem, try Screen
                        windowCaptureMode = WindowCaptureMode.Screen;
                    }
                }
                else if (windowCaptureMode == WindowCaptureMode.Aero || windowCaptureMode == WindowCaptureMode.AeroTransparent)
                {
                    ICapture tmpCapture = null;
                    if (conf.isDWMAllowed(process))
                    {
                        tmpCapture = windowToCapture.CaptureDWMWindow(captureForWindow, windowCaptureMode, isAutoMode);
                    }
                    if (tmpCapture != null)
                    {
                        captureForWindow = tmpCapture;
                        captureTaken = true;
                    }
                    else
                    {
                        // A problem, try GDI
                        windowCaptureMode = WindowCaptureMode.GDI;
                    }
                }
                else
                {
                    // Screen capture
                    windowRectangle.Intersect(captureForWindow.ScreenBounds);
                    try
                    {
                        captureForWindow = WindowCapture.CaptureRectangle(captureForWindow, windowRectangle);
                        captureTaken = true;
                    }
                    catch (Exception e)
                    {
                        LOG.Error("Problem capturing", e);
                        return null;
                    }
                }
            }

            if (captureForWindow != null && windowToCapture != null)
            {
                captureForWindow.CaptureDetails.Title = windowToCapture.Text;
                ((Bitmap)captureForWindow.Image).SetResolution(captureForWindow.CaptureDetails.DpiX, captureForWindow.CaptureDetails.DpiY);
            }

            return captureForWindow;
        }