diff --git a/Greenshot/Helpers/CaptureHelper.cs b/Greenshot/Helpers/CaptureHelper.cs index 161de1c43..2958a9f43 100644 --- a/Greenshot/Helpers/CaptureHelper.cs +++ b/Greenshot/Helpers/CaptureHelper.cs @@ -762,6 +762,7 @@ namespace Greenshot.Helpers { LOG.InfoFormat("Capturing window with mode {0}", windowCaptureMode); bool captureTaken = false; + windowRectangle.Intersect(captureForWindow.ScreenBounds); // Try to capture while (!captureTaken) { ICapture tmpCapture = null; @@ -771,8 +772,49 @@ namespace Greenshot.Helpers { 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((Bitmap)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.CaptureRectangle(screenCapture, windowRectangle) != null) { + int blackCountScreen = ImageHelper.CountColor((Bitmap)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; @@ -803,7 +845,7 @@ namespace Greenshot.Helpers { } else { windowToCapture.ToForeground(); } - windowRectangle.Intersect(captureForWindow.ScreenBounds); + try { captureForWindow = WindowCapture.CaptureRectangle(captureForWindow, windowRectangle); captureTaken = true; diff --git a/GreenshotPlugin/Core/WindowCapture.cs b/GreenshotPlugin/Core/WindowCapture.cs index 731a7171c..4eb63ce31 100644 --- a/GreenshotPlugin/Core/WindowCapture.cs +++ b/GreenshotPlugin/Core/WindowCapture.cs @@ -587,7 +587,9 @@ namespace GreenshotPlugin.Core { } capture.Image = CaptureRectangle(captureBounds); capture.Location = captureBounds.Location; - ((Bitmap)capture.Image).SetResolution(capture.CaptureDetails.DpiX, capture.CaptureDetails.DpiY); + if (capture.CaptureDetails != null) { + ((Bitmap)capture.Image).SetResolution(capture.CaptureDetails.DpiX, capture.CaptureDetails.DpiY); + } if (capture.Image == null) { return null; } diff --git a/GreenshotPlugin/Core/WindowsHelper.cs b/GreenshotPlugin/Core/WindowsHelper.cs index 9c4b49d51..0ce88a04e 100644 --- a/GreenshotPlugin/Core/WindowsHelper.cs +++ b/GreenshotPlugin/Core/WindowsHelper.cs @@ -1111,114 +1111,6 @@ namespace GreenshotPlugin.Core { return returnRegion; } - /// - /// PrintWindow but with VScroll loop - /// - /// Image with all the scroll contents - public Image PrintWithVScroll() { - SCROLLINFO scrollinfo = new SCROLLINFO(); - scrollinfo.cbSize = Marshal.SizeOf( scrollinfo ); - scrollinfo.fMask = (int) ScrollInfoMask.SIF_ALL; - User32.GetScrollInfo(Handle, (int) ScrollBarDirection.SB_VERT, ref scrollinfo ); - - LOG.DebugFormat("nMax {0}", scrollinfo.nMax); - LOG.DebugFormat("nMin {0}", scrollinfo.nMin); - LOG.DebugFormat("nPage {0}", scrollinfo.nPage); - LOG.DebugFormat("nPos {0}", scrollinfo.nPos); - LOG.DebugFormat("nTrackPos {0}", scrollinfo.nTrackPos); - -// WindowStyleFlags style = WindowStyle; -// LOG.InfoFormat("before: {0}", style); -// style = style.Remove(WindowStyleFlags.WS_HSCROLL); -// WindowStyle = style; -// if (!User32.SetWindowPos(Handle, IntPtr.Zero, 0,0,0,0, WindowPos.SWP_NOMOVE | WindowPos.SWP_NOSIZE | WindowPos.SWP_NOZORDER | WindowPos.SWP_FRAMECHANGED| WindowPos.SWP_DRAWFRAME | WindowPos.SWP_NOACTIVATE)) { -// Exception e = new Win32Exception(); -// LOG.Error("error with SetWindowPos", e); -// } -// style = WindowStyle; -// LOG.InfoFormat("before: {0}", style); -// style = style.Remove(WindowStyleFlags.WS_VSCROLL); -// WindowStyle = style; -// LOG.InfoFormat("After: {0}", style); -// if (!User32.SetWindowPos(Handle, IntPtr.Zero, 0,0,0,0, WindowPos.SWP_NOMOVE | WindowPos.SWP_NOSIZE | WindowPos.SWP_NOZORDER | WindowPos.SWP_FRAMECHANGED| WindowPos.SWP_DRAWFRAME | WindowPos.SWP_NOACTIVATE)) { -// Exception e = new Win32Exception(); -// LOG.Error("error with SetWindowPos", e); -// } - - Rectangle viewableRectangle = ClientRectangle; - // As we work with bitmap coordinates, recalculate the location - viewableRectangle.Offset(-WindowRectangle.X, -WindowRectangle.Y); - - int width = viewableRectangle.Width; - int height = viewableRectangle.Height * (scrollinfo.nMax / scrollinfo.nPage); - int pageSkip = scrollinfo.nPage; - if (width * height == 0) { - LOG.Error("No window content!!"); - return null; - } - Bitmap returnBitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb); - - using (Graphics graphicsTarget = Graphics.FromImage(returnBitmap)) { - int location = 0; - int y = 0; - do { - VScroll(location); - Thread.Sleep(200); - - Rectangle destination = new Rectangle(0, y, viewableRectangle.Width, viewableRectangle.Height); - using (Image printedWindow = PrintWindow()) { - if (printedWindow != null) { - graphicsTarget.DrawImage(printedWindow, destination, viewableRectangle, GraphicsUnit.Pixel); - graphicsTarget.Flush(); - y += viewableRectangle.Height; - } - } - location += pageSkip; - //if (location < scrollinfo.nMax && location > scrollinfo.nMax - scrollinfo.nPage) { - // location = scrollinfo.nMax - scrollinfo.nPage; - //} - } while (location < scrollinfo.nMax); - } - VScroll(scrollinfo.nPos); - return returnBitmap; - } - - /// - /// Does the window have a HScrollbar? - /// - /// true if a HScrollbar is available - public bool HasHScroll() { - return WindowStyle.Has(WindowStyleFlags.WS_HSCROLL); - } - - /// - /// Does the window have a VScrollbar? - /// - /// true if a VScrollbar is available - public bool HasVScroll() { - return WindowStyle.Has(WindowStyleFlags.WS_VSCROLL); - } - - /// - /// Scroll the window to the hpos location - /// - /// - public void HScroll(int hpos) { - User32.SetScrollPos(Handle, Orientation.Horizontal, hpos, true); - User32.PostMessage(Handle, (int)WindowsMessages.WM_HSCROLL, (int)ScrollbarCommand.SB_THUMBPOSITION + (hpos<<16), 0); - } - - /// - /// Scroll the window to the vpos location - /// - /// - public void VScroll(int vpos) { - User32.SetScrollPos(Handle, Orientation.Vertical, vpos, true); - int ptrWparam = (int)ScrollbarCommand.SB_THUMBTRACK + (vpos << 16); - int ptrLparam = 0; - User32.SendMessage(Handle, (int)WindowsMessages.WM_VSCROLL, ptrWparam, ptrLparam); - } - private bool CanFreezeOrUnfreeze(string titleOrProcessname) { if (string.IsNullOrEmpty(titleOrProcessname)) { return false; diff --git a/GreenshotPlugin/Interfaces/Capture.cs b/GreenshotPlugin/Interfaces/Capture.cs index deeba330c..50f1a65a2 100644 --- a/GreenshotPlugin/Interfaces/Capture.cs +++ b/GreenshotPlugin/Interfaces/Capture.cs @@ -113,6 +113,8 @@ namespace Greenshot.Plugin { get; set; } + + void NullImage(); Rectangle ScreenBounds { get;