diff --git a/Greenshot/Forms/ImageEditorForm.cs b/Greenshot/Forms/ImageEditorForm.cs index 2957650c6..1be34bd95 100644 --- a/Greenshot/Forms/ImageEditorForm.cs +++ b/Greenshot/Forms/ImageEditorForm.cs @@ -1125,7 +1125,6 @@ namespace Greenshot { capture.CaptureDetails.DpiX = graphics.DpiY; capture.CaptureDetails.DpiY = graphics.DpiY; } - windowToCapture.Restore(); windowToCapture = CaptureHelper.SelectCaptureWindow(windowToCapture); if (windowToCapture != null) { capture = CaptureHelper.CaptureWindow(windowToCapture, capture, coreConf.WindowCaptureMode); diff --git a/Greenshot/Helpers/CaptureHelper.cs b/Greenshot/Helpers/CaptureHelper.cs index 9fe52c50c..f4a0e77af 100644 --- a/Greenshot/Helpers/CaptureHelper.cs +++ b/Greenshot/Helpers/CaptureHelper.cs @@ -631,12 +631,11 @@ namespace Greenshot.Helpers { // Nothing to capture, code up in the stack will capture the full screen return false; } - if (selectedCaptureWindow != null && selectedCaptureWindow.Iconic) { + if (!presupplied && selectedCaptureWindow != null && selectedCaptureWindow.Iconic) { // Restore the window making sure it's visible! // This is done mainly for a screen capture, but some applications like Excel and TOAD have weird behaviour! selectedCaptureWindow.Restore(); } - selectedCaptureWindow.ToForeground(); selectedCaptureWindow = SelectCaptureWindow(selectedCaptureWindow); if (selectedCaptureWindow == null) { LOG.Warn("No window to capture, after SelectCaptureWindow!"); @@ -657,7 +656,7 @@ namespace Greenshot.Helpers { /// WindowDetails with the target Window OR a replacement public static WindowDetails SelectCaptureWindow(WindowDetails windowToCapture) { Rectangle windowRectangle = windowToCapture.WindowRectangle; - if (windowToCapture.Iconic || windowRectangle.Width == 0 || windowRectangle.Height == 0) { + if (windowRectangle.Width == 0 || windowRectangle.Height == 0) { LOG.WarnFormat("Window {0} has nothing to capture, using workaround to find other window of same process.", windowToCapture.Text); // Trying workaround, the size 0 arrises with e.g. Toad.exe, has a different Window when minimized WindowDetails linkedWindow = WindowDetails.GetLinkedWindow(windowToCapture); @@ -706,10 +705,6 @@ namespace Greenshot.Helpers { 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(); @@ -769,40 +764,52 @@ namespace Greenshot.Helpers { bool captureTaken = false; // Try to capture while (!captureTaken) { - if (windowCaptureMode == WindowCaptureMode.GDI) { - ICapture tmpCapture = null; - if (WindowCapture.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 (WindowCapture.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; - } + 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(); + } + tmpCapture = windowToCapture.CaptureGDIWindow(captureForWindow); + } + if (tmpCapture != null) { + captureForWindow = tmpCapture; + captureTaken = true; + } else { + // A problem, try Screen + windowCaptureMode = WindowCaptureMode.Screen; + } + break; + case WindowCaptureMode.Aero: + case WindowCaptureMode.AeroTransparent: + if (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(); + } + windowRectangle.Intersect(captureForWindow.ScreenBounds); + try { + captureForWindow = WindowCapture.CaptureRectangle(captureForWindow, windowRectangle); + captureTaken = true; + } catch (Exception e) { + LOG.Error("Problem capturing", e); + return null; + } + break; } } @@ -835,11 +842,11 @@ namespace Greenshot.Helpers { // Take the captureRect, this already is specified as bitmap coordinates capture.Crop(captureRect); - // save for re-capturing later and show recapture context menu option - // Important here is that the location needs to be offsetted back to screen coordinates! - Rectangle tmpRectangle = captureRect.Clone(); - tmpRectangle.Offset(capture.ScreenBounds.Location.X, capture.ScreenBounds.Location.Y); - RuntimeConfig.LastCapturedRegion = tmpRectangle; + // save for re-capturing later and show recapture context menu option + // Important here is that the location needs to be offsetted back to screen coordinates! + Rectangle tmpRectangle = captureRect.Clone(); + tmpRectangle.Offset(capture.ScreenBounds.Location.X, capture.ScreenBounds.Location.Y); + RuntimeConfig.LastCapturedRegion = tmpRectangle; HandleCapture(); } } diff --git a/GreenshotPlugin/Controls/ThumbnailForm.cs b/GreenshotPlugin/Controls/ThumbnailForm.cs index de146a699..4c42e9fc9 100644 --- a/GreenshotPlugin/Controls/ThumbnailForm.cs +++ b/GreenshotPlugin/Controls/ThumbnailForm.cs @@ -26,92 +26,93 @@ using System.Drawing; using GreenshotPlugin.UnmanagedHelpers; namespace GreenshotPlugin.Controls { - /// - /// This form allows us to show a Thumbnail preview of a window near the context menu when selecting a window to capture. - /// Didn't make it completely "generic" yet, but at least most logic is in here so we don't have it in the mainform. - /// - public class ThumbnailForm : FormWithoutActivation { - private static CoreConfiguration conf = IniConfig.GetIniSection(); + /// + /// This form allows us to show a Thumbnail preview of a window near the context menu when selecting a window to capture. + /// Didn't make it completely "generic" yet, but at least most logic is in here so we don't have it in the mainform. + /// + public class ThumbnailForm : FormWithoutActivation { + private static CoreConfiguration conf = IniConfig.GetIniSection(); - private IntPtr thumbnailHandle = IntPtr.Zero; - private Rectangle parentMenuBounds = Rectangle.Empty; + private IntPtr thumbnailHandle = IntPtr.Zero; + private Rectangle parentMenuBounds = Rectangle.Empty; - public ThumbnailForm() { - ShowInTaskbar = false; - FormBorderStyle = FormBorderStyle.None; - TopMost = false; - Enabled = false; - if (conf.WindowCaptureMode == WindowCaptureMode.Auto || conf.WindowCaptureMode == WindowCaptureMode.Aero) { - BackColor = Color.FromArgb(255, conf.DWMBackgroundColor.R, conf.DWMBackgroundColor.G, conf.DWMBackgroundColor.B); - } else { - BackColor = Color.White; - } + public ThumbnailForm() { + ShowInTaskbar = false; + FormBorderStyle = FormBorderStyle.None; + TopMost = false; + Enabled = false; + if (conf.WindowCaptureMode == WindowCaptureMode.Auto || conf.WindowCaptureMode == WindowCaptureMode.Aero) { + BackColor = Color.FromArgb(255, conf.DWMBackgroundColor.R, conf.DWMBackgroundColor.G, conf.DWMBackgroundColor.B); + } else { + BackColor = Color.White; + } - // cleanup at close - this.FormClosing += delegate { - UnregisterThumbnail(); - }; - } + // cleanup at close + this.FormClosing += delegate { + UnregisterThumbnail(); + }; + } - public new void Hide() { - UnregisterThumbnail(); - base.Hide(); - } + public new void Hide() { + UnregisterThumbnail(); + base.Hide(); + } - private void UnregisterThumbnail() { - if (thumbnailHandle != IntPtr.Zero) { - DWM.DwmUnregisterThumbnail(thumbnailHandle); - thumbnailHandle = IntPtr.Zero; - } - } + private void UnregisterThumbnail() { + if (thumbnailHandle != IntPtr.Zero) { + DWM.DwmUnregisterThumbnail(thumbnailHandle); + thumbnailHandle = IntPtr.Zero; + } + } - /// - /// Show the thumbnail of the supplied window above (or under) the parent Control - /// - /// WindowDetails - /// Control - public void ShowThumbnail(WindowDetails window, Control parentControl) { - UnregisterThumbnail(); + /// + /// Show the thumbnail of the supplied window above (or under) the parent Control + /// + /// WindowDetails + /// Control + public void ShowThumbnail(WindowDetails window, Control parentControl) { + UnregisterThumbnail(); - DWM.DwmRegisterThumbnail(Handle, window.Handle, out thumbnailHandle); - if (thumbnailHandle != IntPtr.Zero) { - Rectangle windowRectangle = window.WindowRectangle; - int thumbnailHeight = 200; - int thumbnailWidth = (int)(thumbnailHeight * ((float)windowRectangle.Width / (float)windowRectangle.Height)); - if (parentControl != null && thumbnailWidth > parentControl.Width) { - thumbnailWidth = parentControl.Width; - thumbnailHeight = (int)(thumbnailWidth * ((float)windowRectangle.Height / (float)windowRectangle.Width)); - } - Width = thumbnailWidth; - Height = thumbnailHeight; - // Prepare the displaying of the Thumbnail - DWM_THUMBNAIL_PROPERTIES props = new DWM_THUMBNAIL_PROPERTIES(); - props.Opacity = (byte)255; - props.Visible = true; - props.SourceClientAreaOnly = false; - props.Destination = new RECT(0, 0, thumbnailWidth, thumbnailHeight); - DWM.DwmUpdateThumbnailProperties(thumbnailHandle, ref props); - if (parentControl != null) { - AlignToControl(parentControl); - } + DWM.DwmRegisterThumbnail(Handle, window.Handle, out thumbnailHandle); + if (thumbnailHandle != IntPtr.Zero) { + SIZE sourceSize; + DWM.DwmQueryThumbnailSourceSize(thumbnailHandle, out sourceSize); + int thumbnailHeight = 200; + int thumbnailWidth = (int)(thumbnailHeight * ((float)sourceSize.width / (float)sourceSize.height)); + if (parentControl != null && thumbnailWidth > parentControl.Width) { + thumbnailWidth = parentControl.Width; + thumbnailHeight = (int)(thumbnailWidth * ((float)sourceSize.height / (float)sourceSize.width)); + } + Width = thumbnailWidth; + Height = thumbnailHeight; + // Prepare the displaying of the Thumbnail + DWM_THUMBNAIL_PROPERTIES props = new DWM_THUMBNAIL_PROPERTIES(); + props.Opacity = (byte)255; + props.Visible = true; + props.SourceClientAreaOnly = false; + props.Destination = new RECT(0, 0, thumbnailWidth, thumbnailHeight); + DWM.DwmUpdateThumbnailProperties(thumbnailHandle, ref props); + if (parentControl != null) { + AlignToControl(parentControl); + } - if (!Visible) { - Show(); - } - // Make sure it's on "top"! - if (parentControl != null) { - User32.SetWindowPos(Handle, parentControl.Handle, 0, 0, 0, 0, WindowPos.SWP_NOMOVE | WindowPos.SWP_NOSIZE | WindowPos.SWP_NOACTIVATE); - } - } - } + if (!Visible) { + Show(); + } + // Make sure it's on "top"! + if (parentControl != null) { + User32.SetWindowPos(Handle, parentControl.Handle, 0, 0, 0, 0, WindowPos.SWP_NOMOVE | WindowPos.SWP_NOSIZE | WindowPos.SWP_NOACTIVATE); + } + } + } - public void AlignToControl(Control alignTo) { - Rectangle screenBounds = WindowCapture.GetScreenBounds(); - if (screenBounds.Contains(alignTo.Left, alignTo.Top - Height)) { - Location = new Point(alignTo.Left + (alignTo.Width / 2) - (Width / 2), alignTo.Top - Height); - } else { - Location = new Point(alignTo.Left + (alignTo.Width / 2) - (Width / 2), alignTo.Bottom); - } - } - } + public void AlignToControl(Control alignTo) { + Rectangle screenBounds = WindowCapture.GetScreenBounds(); + if (screenBounds.Contains(alignTo.Left, alignTo.Top - Height)) { + Location = new Point(alignTo.Left + (alignTo.Width / 2) - (Width / 2), alignTo.Top - Height); + } else { + Location = new Point(alignTo.Left + (alignTo.Width / 2) - (Width / 2), alignTo.Bottom); + } + } + } } diff --git a/GreenshotPlugin/Core/WindowsHelper.cs b/GreenshotPlugin/Core/WindowsHelper.cs index 5337df9d2..7fb99addc 100644 --- a/GreenshotPlugin/Core/WindowsHelper.cs +++ b/GreenshotPlugin/Core/WindowsHelper.cs @@ -705,7 +705,9 @@ namespace GreenshotPlugin.Core { User32.BringWindowToTop(this.hWnd); User32.SetForegroundWindow(this.hWnd); // Make sure windows has time to perform the action - Application.DoEvents(); + while(Iconic) { + Application.DoEvents(); + } } public WindowStyleFlags WindowStyle { @@ -738,7 +740,7 @@ namespace GreenshotPlugin.Core { /// /// The capture to fill /// ICapture - public ICapture CaptureWindow(ICapture capture) { + public ICapture CaptureGDIWindow(ICapture capture) { Image capturedImage = PrintWindow(); if (capturedImage != null) { capture.Image = capturedImage; @@ -772,7 +774,7 @@ namespace GreenshotPlugin.Core { SIZE sourceSize; DWM.DwmQueryThumbnailSourceSize(thumbnailHandle, out sourceSize); - if (sourceSize.cx <= 0 || sourceSize.cy <= 0) { + if (sourceSize.width <= 0 || sourceSize.height <= 0) { return null; } @@ -819,7 +821,7 @@ namespace GreenshotPlugin.Core { tempForm.Size = sourceSize.ToSize(); // Prepare rectangle to capture from the screen. - Rectangle captureRectangle = new Rectangle(formLocation.X, formLocation.Y, sourceSize.cx, sourceSize.cy); + Rectangle captureRectangle = new Rectangle(formLocation.X, formLocation.Y, sourceSize.width, sourceSize.height); if (Maximised) { // Correct capture size for maximized window by offsetting the X,Y with the border size captureRectangle.X += borderSize.Width; @@ -838,14 +840,12 @@ namespace GreenshotPlugin.Core { } } - // Make sure the to be captured window is active, important for the close/resize buttons - this.Restore(); // Prepare the displaying of the Thumbnail DWM_THUMBNAIL_PROPERTIES props = new DWM_THUMBNAIL_PROPERTIES(); props.Opacity = (byte)255; props.Visible = true; - props.Destination = new RECT(0, 0, sourceSize.cx, sourceSize.cy); + props.Destination = new RECT(0, 0, sourceSize.width, sourceSize.height); DWM.DwmUpdateThumbnailProperties(thumbnailHandle, ref props); tempForm.Show(); tempFormShown = true; @@ -1322,9 +1322,7 @@ namespace GreenshotPlugin.Core { /// As GDI+ draws it, it will be without Aero borders! /// public Image PrintWindow() { - Rectangle windowRect = Rectangle.Empty; - GetWindowRect(out windowRect); - + Rectangle windowRect = WindowRectangle; // Start the capture Exception exceptionOccured = null; Image returnImage = null; diff --git a/GreenshotPlugin/UnmanagedHelpers/Structs.cs b/GreenshotPlugin/UnmanagedHelpers/Structs.cs index d42954e8a..ad4425d22 100644 --- a/GreenshotPlugin/UnmanagedHelpers/Structs.cs +++ b/GreenshotPlugin/UnmanagedHelpers/Structs.cs @@ -25,17 +25,17 @@ using System.Runtime.InteropServices; namespace GreenshotPlugin.UnmanagedHelpers { [StructLayout(LayoutKind.Sequential), Serializable()] public struct SIZE { - public int cx; - public int cy; + public int width; + public int height; public SIZE(Size size) : this(size.Width, size.Height) { } - public SIZE(int cx, int cy) { - this.cx = cx; - this.cy = cy; + public SIZE(int width, int height) { + this.width = width; + this.height = height; } public Size ToSize() { - return new Size(cx, cy); + return new Size(width, height); } }