mirror of
https://github.com/greenshot/greenshot
synced 2025-08-14 02:37:03 -07:00
Changed the default window capture for Windows 11 to use User32.PrintWindow (called GDI internally), which should solve #326. The background for this can be read in #373
This commit is contained in:
parent
6b90f2c3ff
commit
4f3920d61a
4 changed files with 77 additions and 27 deletions
38
src/Greenshot.Base/Core/Enums/PrintWindowFlags.cs
Normal file
38
src/Greenshot.Base/Core/Enums/PrintWindowFlags.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
* For more information see: https://getgreenshot.org/
|
||||
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Greenshot.Base.Core.Enums
|
||||
{
|
||||
[Flags]
|
||||
public enum PrintWindowFlags : uint
|
||||
{
|
||||
/// <summary>Render the entire window.</summary>
|
||||
PW_ENTIREWINDOW = 0,
|
||||
|
||||
/// <summary>Only the client area of the window is copied to hdcBlt. By default, the entire window is copied.</summary>
|
||||
PW_CLIENTONLY = 1,
|
||||
|
||||
/// <summary>Undocumented</summary>
|
||||
PW_RENDERFULLCONTENT = 0x00000002,
|
||||
}
|
||||
}
|
|
@ -1392,32 +1392,36 @@ namespace Greenshot.Base.Core
|
|||
|
||||
/// <summary>
|
||||
/// Return an Image representing the Window!
|
||||
/// As GDI+ draws it, it will be without Aero borders!
|
||||
/// For Windows 7, as GDI+ draws it, it will be without Aero borders!
|
||||
/// For Windows 10+, there is an option PW_RENDERFULLCONTENT, which makes sure the capture is "as is".
|
||||
/// </summary>
|
||||
public Image PrintWindow()
|
||||
{
|
||||
Rectangle windowRect = WindowRectangle;
|
||||
// Start the capture
|
||||
Exception exceptionOccured = null;
|
||||
Exception exceptionOccurred = null;
|
||||
Image returnImage;
|
||||
using (Region region = GetRegion())
|
||||
{
|
||||
var backgroundColor = Color.Black;
|
||||
PixelFormat pixelFormat = PixelFormat.Format24bppRgb;
|
||||
// Only use 32 bpp ARGB when the window has a region
|
||||
if (region != null)
|
||||
{
|
||||
pixelFormat = PixelFormat.Format32bppArgb;
|
||||
backgroundColor = Color.Transparent;
|
||||
}
|
||||
|
||||
returnImage = new Bitmap(windowRect.Width, windowRect.Height, pixelFormat);
|
||||
|
||||
returnImage = ImageHelper.CreateEmpty(windowRect.Width, windowRect.Height, pixelFormat, backgroundColor, 96,96);
|
||||
using Graphics graphics = Graphics.FromImage(returnImage);
|
||||
using (SafeDeviceContextHandle graphicsDc = graphics.GetSafeDeviceContext())
|
||||
{
|
||||
bool printSucceeded = User32.PrintWindow(Handle, graphicsDc.DangerousGetHandle(), 0x0);
|
||||
var pwFlags = WindowsVersion.IsWindows10OrLater ? PrintWindowFlags.PW_RENDERFULLCONTENT : PrintWindowFlags.PW_ENTIREWINDOW;
|
||||
bool printSucceeded = User32.PrintWindow(Handle, graphicsDc.DangerousGetHandle(), pwFlags);
|
||||
if (!printSucceeded)
|
||||
{
|
||||
// something went wrong, most likely a "0x80004005" (Acess Denied) when using UAC
|
||||
exceptionOccured = User32.CreateWin32Exception("PrintWindow");
|
||||
// something went wrong, most likely a "0x80004005" (Access Denied) when using UAC
|
||||
exceptionOccurred = User32.CreateWin32Exception("PrintWindow");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1432,9 +1436,9 @@ namespace Greenshot.Base.Core
|
|||
}
|
||||
|
||||
// Return null if error
|
||||
if (exceptionOccured != null)
|
||||
if (exceptionOccurred != null)
|
||||
{
|
||||
Log.ErrorFormat("Error calling print window: {0}", exceptionOccured.Message);
|
||||
Log.ErrorFormat("Error calling print window: {0}", exceptionOccurred.Message);
|
||||
returnImage.Dispose();
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ namespace Greenshot.Base.UnmanagedHelpers
|
|||
|
||||
[DllImport("user32", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool PrintWindow(IntPtr hWnd, IntPtr hDc, uint nFlags);
|
||||
public static extern bool PrintWindow(IntPtr hWnd, IntPtr hDc, PrintWindowFlags pwFlags);
|
||||
|
||||
[DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam);
|
||||
|
|
|
@ -969,26 +969,34 @@ namespace Greenshot.Helpers
|
|||
// Take default screen
|
||||
windowCaptureMode = WindowCaptureMode.Screen;
|
||||
|
||||
// Change to GDI, if allowed
|
||||
if (!windowToCapture.IsMetroApp && WindowCapture.IsGdiAllowed(process))
|
||||
// In https://github.com/greenshot/greenshot/issues/373 it was shown that PrintWindow (GDI) works great with Windows 11
|
||||
if (WindowsVersion.IsWindows11OrLater)
|
||||
{
|
||||
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;
|
||||
}
|
||||
windowCaptureMode = WindowCaptureMode.GDI;
|
||||
}
|
||||
|
||||
// Change to DWM, if enabled and allowed
|
||||
if (dwmEnabled)
|
||||
else
|
||||
{
|
||||
if (windowToCapture.IsMetroApp || WindowCapture.IsDwmAllowed(process))
|
||||
// Change to GDI, if allowed
|
||||
if (!windowToCapture.IsMetroApp && WindowCapture.IsGdiAllowed(process))
|
||||
{
|
||||
windowCaptureMode = WindowCaptureMode.Aero;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1034,7 +1042,7 @@ namespace Greenshot.Helpers
|
|||
}
|
||||
|
||||
tmpCapture = windowToCapture.CaptureGdiWindow(captureForWindow);
|
||||
if (tmpCapture != null)
|
||||
if (tmpCapture != null && !WindowsVersion.IsWindows11OrLater)
|
||||
{
|
||||
// check if GDI capture any good, by comparing it with the screen content
|
||||
int blackCountGdi = ImageHelper.CountColor(tmpCapture.Image, Color.Black, false);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue