Esempio n. 1
0
        /// <summary>
        /// Start the capture
        /// </summary>
        /// <returns>Bitmap</returns>
        public Bitmap Capture()
        {
            if (_windowScroller.NeedsFocus())
            {
                User32Api.SetForegroundWindow(_windowScroller.ScrollBarWindow.Handle);
                Application.DoEvents();
                Thread.Sleep(Delay);
                Application.DoEvents();
            }

            // Find the area which is scrolling

            // 1. Take the client bounds
            var clientBounds = _windowScroller.ScrollBarWindow.GetInfo().ClientBounds;

            // Use a region for steps 2 and 3
            using (var region = new Region(clientBounds))
            {
                // 2. exclude the children, if any
                foreach (var interopWindow in _windowScroller.ScrollBarWindow.GetChildren())
                {
                    region.Exclude(interopWindow.GetInfo().Bounds);
                }
                // 3. exclude the scrollbar, if it can be found
                if (_windowScroller.ScrollBar.HasValue)
                {
                    region.Exclude(_windowScroller.ScrollBar.Value.Bounds);
                }
                // Get the bounds of the region
                using (var screenGraphics = Graphics.FromHwnd(User32Api.GetDesktopWindow()))
                {
                    var rectangleF = region.GetBounds(screenGraphics);
                    clientBounds = new NativeRect((int)rectangleF.X, (int)rectangleF.Y, (int)rectangleF.Width, (int)rectangleF.Height);
                }
            }

            if (clientBounds.Width * clientBounds.Height <= 0)
            {
                return(null);
            }
            // Move the window to the start
            _windowScroller.Start();

            // Register a keyboard hook to make it possible to ESC the capturing
            var breakScroll  = false;
            var keyboardHook = KeyboardHook.KeyboardEvents
                               .Where(args => args.Key == VirtualKeyCodes.ESCAPE)
                               .Subscribe(args =>
            {
                args.Handled = true;
                breakScroll  = true;
            });
            Bitmap resultImage = null;

            try
            {
                // A delay to make the window move
                Application.DoEvents();
                Thread.Sleep(Delay);
                Application.DoEvents();

                if (_windowScroller.IsAtStart)
                {
                    using (var bitmapStitcher = new BitmapStitcher())
                    {
                        bitmapStitcher.AddBitmap(WindowCapture.CaptureRectangle(clientBounds));

                        // Loop as long as we are not at the end yet
                        while (!_windowScroller.IsAtEnd && !breakScroll)
                        {
                            // Next "page"
                            _windowScroller.Next();
                            // Wait a bit, so the window can update
                            Application.DoEvents();
                            Thread.Sleep(Delay);
                            Application.DoEvents();
                            // Capture inside loop
                            bitmapStitcher.AddBitmap(WindowCapture.CaptureRectangle(clientBounds));
                        }
                        resultImage = bitmapStitcher.Result();
                    }
                }
                else
                {
                    resultImage = WindowCapture.CaptureRectangle(clientBounds);
                }
            }
            catch (Exception ex)
            {
                Log.Error().WriteLine(ex);
            }
            finally
            {
                // Remove hook for escape
                keyboardHook.Dispose();
                // Try to reset location
                _windowScroller.Reset();
            }

            return(resultImage);
        }
        /// <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);
        }
Esempio n. 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.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 (CoreConfig.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(false);
                            }
                            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)
            {
                captureForWindow.CaptureDetails.Title = windowToCapture.Text;
            }

            return(captureForWindow);
        }
        /// <summary>
        /// Make Capture with specified destinations
        /// </summary>
        private void MakeCapture()
        {
            // Experimental code
            if (screenCapture != null)
            {
                screenCapture.Stop();
                screenCapture = null;
                return;
            }

            LOG.Debug(String.Format("Capturing with mode {0} and using Cursor {1}", captureMode, captureMouseCursor));
            capture.CaptureDetails.CaptureMode = captureMode;

            // Get the windows details in a seperate thread
            windowDetailsThread = PrepareForCaptureWithFeedback();

            // Add destinations if no-one passed a handler
            if (capture.CaptureDetails.CaptureDestinations == null || capture.CaptureDetails.CaptureDestinations.Count == 0)
            {
                AddConfiguredDestination();
            }

            // Workaround for proble with DPI retrieval, the FromHwnd activates the window...
            WindowDetails previouslyActiveWindow = WindowDetails.GetActiveWindow();

            // Workaround for changed DPI settings in Windows 7
            using (Graphics graphics = Graphics.FromHwnd(MainForm.instance.Handle))
            {
                capture.CaptureDetails.DpiX = graphics.DpiX;
                capture.CaptureDetails.DpiY = graphics.DpiY;
            }
            if (previouslyActiveWindow != null)
            {
                // Set previouslyActiveWindow as foreground window
                previouslyActiveWindow.ToForeground();
            }

            // Delay for the Context menu
            if (conf.CaptureDelay > 0)
            {
                System.Threading.Thread.Sleep(conf.CaptureDelay);
            }
            else
            {
                conf.CaptureDelay = 0;
            }

            // Allways capture Mousecursor, only show when needed
            capture = WindowCapture.CaptureCursor(capture);
            capture.CursorVisible = false;
            // Check if needed
            if (captureMouseCursor && captureMode != CaptureMode.Clipboard && captureMode != CaptureMode.File)
            {
                capture.CursorVisible = conf.CaptureMousepointer;
            }

            switch (captureMode)
            {
            case CaptureMode.Window:
                capture = WindowCapture.CaptureScreen(capture);
                capture.CaptureDetails.AddMetaData("source", "Screen");
                CaptureWithFeedback();
                break;

            case CaptureMode.ActiveWindow:
                if (CaptureActiveWindow())
                {
                    if (windowDetailsThread != null)
                    {
                        windowDetailsThread.Join();
                    }
                    // Capture worked, offset mouse according to screen bounds and capture location
                    capture.MoveMouseLocation(capture.ScreenBounds.Location.X - capture.Location.X, capture.ScreenBounds.Location.Y - capture.Location.Y);
                    capture.MoveElements(capture.ScreenBounds.Location.X - capture.Location.X, capture.ScreenBounds.Location.Y - capture.Location.Y);
                    capture.CaptureDetails.AddMetaData("source", "Window");
                }
                else
                {
                    captureMode = CaptureMode.FullScreen;
                    capture     = WindowCapture.CaptureScreen(capture);
                    capture.CaptureDetails.AddMetaData("source", "Screen");
                    capture.CaptureDetails.Title = "Screen";
                }
                HandleCapture();
                break;

            case CaptureMode.IE:
                if (IECaptureHelper.CaptureIE(capture) != null)
                {
                    capture.CaptureDetails.AddMetaData("source", "Internet Explorer");
                    HandleCapture();
                }
                break;

            case CaptureMode.FullScreen:
                // Check how we need to capture the screen
                bool captureTaken = false;
                switch (screenCaptureMode)
                {
                case ScreenCaptureMode.Auto:
                    Point mouseLocation = WindowCapture.GetCursorLocation();
                    foreach (Screen screen in Screen.AllScreens)
                    {
                        if (screen.Bounds.Contains(mouseLocation))
                        {
                            capture      = WindowCapture.CaptureRectangle(capture, screen.Bounds);
                            captureTaken = true;
                            break;
                        }
                    }
                    break;

                case ScreenCaptureMode.Fixed:
                    if (conf.ScreenToCapture > 0 && conf.ScreenToCapture <= Screen.AllScreens.Length)
                    {
                        capture      = WindowCapture.CaptureRectangle(capture, Screen.AllScreens[conf.ScreenToCapture].Bounds);
                        captureTaken = true;
                    }
                    break;

                case ScreenCaptureMode.FullScreen:
                    // Do nothing, we take the fullscreen capture automatically
                    break;
                }
                if (!captureTaken)
                {
                    capture = WindowCapture.CaptureScreen(capture);
                }
                HandleCapture();
                break;

            case CaptureMode.Clipboard:
                Image  clipboardImage = null;
                string text           = "Clipboard";
                if (ClipboardHelper.ContainsImage())
                {
                    clipboardImage = ClipboardHelper.GetImage();
                }
                if (clipboardImage != null)
                {
                    if (capture != null)
                    {
                        capture.Image = clipboardImage;
                    }
                    else
                    {
                        capture = new Capture(clipboardImage);
                    }
                    string title = ClipboardHelper.GetText();
                    if (title == null || title.Trim().Length == 0)
                    {
                        title = "Clipboard";
                    }
                    capture.CaptureDetails.Title = title;
                    capture.CaptureDetails.AddMetaData("source", "Clipboard");
                    // Force Editor, keep picker
                    if (capture.CaptureDetails.HasDestination(Destinations.PickerDestination.DESIGNATION))
                    {
                        capture.CaptureDetails.ClearDestinations();
                        capture.CaptureDetails.AddDestination(DestinationHelper.GetDestination(Destinations.EditorDestination.DESIGNATION));
                        capture.CaptureDetails.AddDestination(DestinationHelper.GetDestination(Destinations.PickerDestination.DESIGNATION));
                    }
                    else
                    {
                        capture.CaptureDetails.ClearDestinations();
                        capture.CaptureDetails.AddDestination(DestinationHelper.GetDestination(Destinations.EditorDestination.DESIGNATION));
                    }
                    HandleCapture();
                }
                else
                {
                    MessageBox.Show("Couldn't create bitmap from : " + text);
                }
                break;

            case CaptureMode.File:
                Bitmap fileBitmap = null;
                string filename   = capture.CaptureDetails.Filename;
                if (!string.IsNullOrEmpty(filename))
                {
                    try
                    {
                        fileBitmap = ImageHelper.LoadBitmap(filename);
                    }
                    catch (Exception e)
                    {
                        LOG.Error(e.Message, e);
                        MessageBox.Show(Language.GetFormattedString(LangKey.error_openfile, filename));
                    }
                }
                if (fileBitmap != null)
                {
                    capture.CaptureDetails.Title = Path.GetFileNameWithoutExtension(filename);
                    capture.CaptureDetails.AddMetaData("file", filename);
                    capture.CaptureDetails.AddMetaData("source", "file");
                    if (capture != null)
                    {
                        capture.Image = fileBitmap;
                    }
                    else
                    {
                        capture = new Capture(fileBitmap);
                    }
                    // Force Editor, keep picker, this is currently the only usefull destination
                    if (capture.CaptureDetails.HasDestination(PickerDestination.DESIGNATION))
                    {
                        capture.CaptureDetails.ClearDestinations();
                        capture.CaptureDetails.AddDestination(DestinationHelper.GetDestination(EditorDestination.DESIGNATION));
                        capture.CaptureDetails.AddDestination(DestinationHelper.GetDestination(PickerDestination.DESIGNATION));
                    }
                    else
                    {
                        capture.CaptureDetails.ClearDestinations();
                        capture.CaptureDetails.AddDestination(DestinationHelper.GetDestination(EditorDestination.DESIGNATION));
                    }
                    HandleCapture();
                }
                break;

            case CaptureMode.LastRegion:
                if (!RuntimeConfig.LastCapturedRegion.IsEmpty)
                {
                    capture = WindowCapture.CaptureRectangle(capture, RuntimeConfig.LastCapturedRegion);
                    if (windowDetailsThread != null)
                    {
                        windowDetailsThread.Join();
                    }
                    capture.CaptureDetails.AddMetaData("source", "screen");
                    HandleCapture();
                }
                break;

            case CaptureMode.Region:
                // Check if a region is pre-supplied!
                if (Rectangle.Empty.Equals(captureRect))
                {
                    capture = WindowCapture.CaptureScreen(capture);
                    capture.CaptureDetails.AddMetaData("source", "screen");
                    CaptureWithFeedback();
                }
                else
                {
                    capture = WindowCapture.CaptureRectangle(capture, captureRect);
                    capture.CaptureDetails.AddMetaData("source", "screen");
                    HandleCapture();
                }
                break;

            case CaptureMode.Video:
                capture = WindowCapture.CaptureScreen(capture);
                // Set the capturemode to be window
                captureMode = CaptureMode.Window;
                capture.CaptureDetails.AddMetaData("source", "Video");
                CaptureWithFeedback();
                break;

            default:
                LOG.Warn("Unknown capture mode: " + captureMode);
                break;
            }
            if (windowDetailsThread != null)
            {
                windowDetailsThread.Join();
            }
            if (capture != null)
            {
                LOG.Debug("Disposing capture");
                capture.Dispose();
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Make Capture with specified destinations
        /// </summary>
        private void MakeCapture()
        {
            Thread retrieveWindowDetailsThread = null;

            // This fixes a problem when a balloon is still visible and a capture needs to be taken
            // forcefully removes the balloon!
            if (!CoreConfig.HideTrayicon)
            {
                MainForm.Instance.NotifyIcon.Visible = false;
                MainForm.Instance.NotifyIcon.Visible = true;
            }
            Log.Debug($"Capturing with mode {_captureMode} and using Cursor {_captureMouseCursor}");
            _capture.CaptureDetails.CaptureMode = _captureMode;

            // Get the windows details in a seperate thread, only for those captures that have a Feedback
            // As currently the "elements" aren't used, we don't need them yet
            switch (_captureMode)
            {
            case CaptureMode.Region:
                // Check if a region is pre-supplied!
                if (Rectangle.Empty.Equals(_captureRect))
                {
                    retrieveWindowDetailsThread = PrepareForCaptureWithFeedback();
                }
                break;

            case CaptureMode.Window:
                retrieveWindowDetailsThread = PrepareForCaptureWithFeedback();
                break;
            }

            // Add destinations if no-one passed a handler
            if (_capture.CaptureDetails.CaptureDestinations == null || _capture.CaptureDetails.CaptureDestinations.Count == 0)
            {
                AddConfiguredDestination();
            }

            // Delay for the Context menu
            if (CoreConfig.CaptureDelay > 0)
            {
                Thread.Sleep(CoreConfig.CaptureDelay);
            }
            else
            {
                CoreConfig.CaptureDelay = 0;
            }

            // Capture Mousecursor if we are not loading from file or clipboard, only show when needed
            if (_captureMode != CaptureMode.File && _captureMode != CaptureMode.Clipboard)
            {
                _capture = WindowCapture.CaptureCursor(_capture);
                _capture.CursorVisible = _captureMouseCursor && CoreConfig.CaptureMousepointer;
            }

            switch (_captureMode)
            {
            case CaptureMode.Window:
                _capture = WindowCapture.CaptureScreen(_capture);
                _capture.CaptureDetails.AddMetaData("source", "Screen");
                SetDpi();
                CaptureWithFeedback();
                break;

            case CaptureMode.ActiveWindow:
                if (CaptureActiveWindow())
                {
                    // Capture worked, offset mouse according to screen bounds and capture location
                    _capture.MoveMouseLocation(_capture.ScreenBounds.Location.X - _capture.Location.X, _capture.ScreenBounds.Location.Y - _capture.Location.Y);
                    _capture.CaptureDetails.AddMetaData("source", "Window");
                }
                else
                {
                    _captureMode = CaptureMode.FullScreen;
                    _capture     = WindowCapture.CaptureScreen(_capture);
                    _capture.CaptureDetails.AddMetaData("source", "Screen");
                    _capture.CaptureDetails.Title = "Screen";
                }
                SetDpi();
                HandleCapture();
                break;

            case CaptureMode.IE:
                if (IeCaptureHelper.CaptureIe(_capture, SelectedCaptureWindow) != null)
                {
                    _capture.CaptureDetails.AddMetaData("source", "Internet Explorer");
                    SetDpi();
                    HandleCapture();
                }
                break;

            case CaptureMode.FullScreen:
                // Check how we need to capture the screen
                bool captureTaken = false;
                switch (_screenCaptureMode)
                {
                case ScreenCaptureMode.Auto:
                    Point mouseLocation = User32.GetCursorLocation();
                    foreach (Screen screen in Screen.AllScreens)
                    {
                        if (screen.Bounds.Contains(mouseLocation))
                        {
                            _capture     = WindowCapture.CaptureRectangle(_capture, screen.Bounds);
                            captureTaken = true;
                            break;
                        }
                    }
                    break;

                case ScreenCaptureMode.Fixed:
                    if (CoreConfig.ScreenToCapture > 0 && CoreConfig.ScreenToCapture <= Screen.AllScreens.Length)
                    {
                        _capture     = WindowCapture.CaptureRectangle(_capture, Screen.AllScreens[CoreConfig.ScreenToCapture].Bounds);
                        captureTaken = true;
                    }
                    break;

                case ScreenCaptureMode.FullScreen:
                    // Do nothing, we take the fullscreen capture automatically
                    break;
                }
                if (!captureTaken)
                {
                    _capture = WindowCapture.CaptureScreen(_capture);
                }
                SetDpi();
                HandleCapture();
                break;

            case CaptureMode.Clipboard:
                Image clipboardImage = ClipboardHelper.GetImage();
                if (clipboardImage != null)
                {
                    if (_capture != null)
                    {
                        _capture.Image = clipboardImage;
                    }
                    else
                    {
                        _capture = new Capture(clipboardImage);
                    }
                    _capture.CaptureDetails.Title = "Clipboard";
                    _capture.CaptureDetails.AddMetaData("source", "Clipboard");
                    // Force Editor, keep picker
                    if (_capture.CaptureDetails.HasDestination(PickerDestination.DESIGNATION))
                    {
                        _capture.CaptureDetails.ClearDestinations();
                        _capture.CaptureDetails.AddDestination(DestinationHelper.GetDestination(EditorDestination.DESIGNATION));
                        _capture.CaptureDetails.AddDestination(DestinationHelper.GetDestination(PickerDestination.DESIGNATION));
                    }
                    else
                    {
                        _capture.CaptureDetails.ClearDestinations();
                        _capture.CaptureDetails.AddDestination(DestinationHelper.GetDestination(EditorDestination.DESIGNATION));
                    }
                    HandleCapture();
                }
                else
                {
                    MessageBox.Show(Language.GetString("clipboard_noimage"));
                }
                break;

            case CaptureMode.File:
                Image  fileImage = null;
                string filename  = _capture.CaptureDetails.Filename;

                if (!string.IsNullOrEmpty(filename))
                {
                    try {
                        if (filename.ToLower().EndsWith("." + OutputFormat.greenshot))
                        {
                            ISurface surface = new Surface();
                            surface = ImageOutput.LoadGreenshotSurface(filename, surface);
                            surface.CaptureDetails = _capture.CaptureDetails;
                            DestinationHelper.GetDestination(EditorDestination.DESIGNATION).ExportCapture(true, surface, _capture.CaptureDetails);
                            break;
                        }
                    } catch (Exception e) {
                        Log.Error(e.Message, e);
                        MessageBox.Show(Language.GetFormattedString(LangKey.error_openfile, filename));
                    }
                    try {
                        fileImage = ImageHelper.LoadImage(filename);
                    } catch (Exception e) {
                        Log.Error(e.Message, e);
                        MessageBox.Show(Language.GetFormattedString(LangKey.error_openfile, filename));
                    }
                }
                if (fileImage != null)
                {
                    _capture.CaptureDetails.Title = Path.GetFileNameWithoutExtension(filename);
                    _capture.CaptureDetails.AddMetaData("file", filename);
                    _capture.CaptureDetails.AddMetaData("source", "file");
                    if (_capture != null)
                    {
                        _capture.Image = fileImage;
                    }
                    else
                    {
                        _capture = new Capture(fileImage);
                    }
                    // Force Editor, keep picker, this is currently the only usefull destination
                    if (_capture.CaptureDetails.HasDestination(PickerDestination.DESIGNATION))
                    {
                        _capture.CaptureDetails.ClearDestinations();
                        _capture.CaptureDetails.AddDestination(DestinationHelper.GetDestination(EditorDestination.DESIGNATION));
                        _capture.CaptureDetails.AddDestination(DestinationHelper.GetDestination(PickerDestination.DESIGNATION));
                    }
                    else
                    {
                        _capture.CaptureDetails.ClearDestinations();
                        _capture.CaptureDetails.AddDestination(DestinationHelper.GetDestination(EditorDestination.DESIGNATION));
                    }
                    HandleCapture();
                }
                break;

            case CaptureMode.LastRegion:
                if (!CoreConfig.LastCapturedRegion.IsEmpty)
                {
                    _capture = WindowCapture.CaptureRectangle(_capture, CoreConfig.LastCapturedRegion);
                    // TODO: Reactive / check if the elements code is activated
                    //if (windowDetailsThread != null) {
                    //	windowDetailsThread.Join();
                    //}

                    // Set capture title, fixing bug #3569703
                    foreach (WindowDetails window in WindowDetails.GetVisibleWindows())
                    {
                        Point estimatedLocation = new Point(CoreConfig.LastCapturedRegion.X + CoreConfig.LastCapturedRegion.Width / 2, CoreConfig.LastCapturedRegion.Y + CoreConfig.LastCapturedRegion.Height / 2);
                        if (window.Contains(estimatedLocation))
                        {
                            _selectedCaptureWindow        = window;
                            _capture.CaptureDetails.Title = _selectedCaptureWindow.Text;
                            break;
                        }
                    }
                    // Move cursor, fixing bug #3569703
                    _capture.MoveMouseLocation(_capture.ScreenBounds.Location.X - _capture.Location.X, _capture.ScreenBounds.Location.Y - _capture.Location.Y);
                    //capture.MoveElements(capture.ScreenBounds.Location.X - capture.Location.X, capture.ScreenBounds.Location.Y - capture.Location.Y);

                    _capture.CaptureDetails.AddMetaData("source", "screen");
                    SetDpi();
                    HandleCapture();
                }
                break;

            case CaptureMode.Region:
                // Check if a region is pre-supplied!
                if (Rectangle.Empty.Equals(_captureRect))
                {
                    _capture = WindowCapture.CaptureScreen(_capture);
                    _capture.CaptureDetails.AddMetaData("source", "screen");
                    SetDpi();
                    CaptureWithFeedback();
                }
                else
                {
                    _capture = WindowCapture.CaptureRectangle(_capture, _captureRect);
                    _capture.CaptureDetails.AddMetaData("source", "screen");
                    SetDpi();
                    HandleCapture();
                }
                break;

            default:
                Log.Warn("Unknown capture mode: " + _captureMode);
                break;
            }
            // Wait for thread, otherwise we can't dipose the CaptureHelper
            retrieveWindowDetailsThread?.Join();
            if (_capture != null)
            {
                Log.Debug("Disposing capture");
                _capture.Dispose();
            }
        }