diff --git a/installer/innosetup/setup.iss b/installer/innosetup/setup.iss
index 81db5e567..d85dd60f9 100644
--- a/installer/innosetup/setup.iss
+++ b/installer/innosetup/setup.iss
@@ -91,33 +91,34 @@ Source: {#LanguagesDir}\*zh-CN*; Excludes: "*installer*,*website*"; DestDir: {ap
Source: {#LanguagesDir}\*zh-TW*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\zhTW; Flags: overwritereadonly ignoreversion replacesameversion;
;Office Plugin
-Source: {#PluginDir}\Greenshot.Plugin.Office\*.dll; DestDir: {app}\Plugins\Office; Components: plugins\office; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
+Source: {#PluginDir}\Greenshot.Plugin.Office\Greenshot.Plugin.Office.dll; DestDir: {app}\Plugins\Office; Components: plugins\office; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
;JIRA Plugin
-Source: {#PluginDir}\Greenshot.Plugin.Jira\*.dll; DestDir: {app}\Plugins\Jira; Components: plugins\jira; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
+Source: {#PluginDir}\Greenshot.Plugin.Jira\*Jira*.dll; DestDir: {app}\Plugins\Jira; Components: plugins\jira; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
Source: {#BaseDir}\Greenshot.Plugin.Jira\Languages\language_jira*.xml; DestDir: {app}\Languages\Plugins\Jira; Components: plugins\jira; Flags: overwritereadonly ignoreversion replacesameversion;
;Imgur Plugin
-Source: {#PluginDir}\Greenshot.Plugin.Imgur\*.dll; DestDir: {app}\Plugins\Imgur; Components: plugins\imgur; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
+Source: {#PluginDir}\Greenshot.Plugin.Imgur\Greenshot.Plugin.Imgur.dll; DestDir: {app}\Plugins\Imgur; Components: plugins\imgur; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
Source: {#BaseDir}\Greenshot.Plugin.Imgur\Languages\language_imgur*.xml; DestDir: {app}\Languages\Plugins\Imgur; Components: plugins\imgur; Flags: overwritereadonly ignoreversion replacesameversion;
;Box Plugin
-Source: {#PluginDir}\Greenshot.Plugin.Box\*.dll; DestDir: {app}\Plugins\Box; Components: plugins\box; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
+Source: {#PluginDir}\Greenshot.Plugin.Box\Greenshot.Plugin.Box.dll; DestDir: {app}\Plugins\Box; Components: plugins\box; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
Source: {#BaseDir}\Greenshot.Plugin.Box\Languages\language_box*.xml; DestDir: {app}\Languages\Plugins\Box; Components: plugins\box; Flags: overwritereadonly ignoreversion replacesameversion;
;DropBox Plugin
-Source: {#PluginDir}\Greenshot.Plugin.DropBox\*.dll; DestDir: {app}\Plugins\DropBox; Components: plugins\dropbox; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
+Source: {#PluginDir}\Greenshot.Plugin.DropBox\Greenshot.Plugin.DropBox.dll; DestDir: {app}\Plugins\DropBox; Components: plugins\dropbox; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
Source: {#BaseDir}\Greenshot.Plugin.DropBox\Languages\language_dropbox*.xml; DestDir: {app}\Languages\Plugins\DropBox; Components: plugins\dropbox; Flags: overwritereadonly ignoreversion replacesameversion;
;Flickr Plugin
-Source: {#PluginDir}\Greenshot.Plugin.Flickr\*.dll; DestDir: {app}\Plugins\Flickr; Components: plugins\flickr; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
+Source: {#PluginDir}\Greenshot.Plugin.Flickr\Greenshot.Plugin.Flickr.dll; DestDir: {app}\Plugins\Flickr; Components: plugins\flickr; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
Source: {#BaseDir}\Greenshot.Plugin.Flickr\Languages\language_flickr*.xml; DestDir: {app}\Languages\Plugins\Flickr; Components: plugins\flickr; Flags: overwritereadonly ignoreversion replacesameversion;
;Photobucket Plugin
-Source: {#PluginDir}\Greenshot.Plugin.Photobucket\*.dll; DestDir: {app}\Plugins\Photobucket; Components: plugins\photobucket; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
+Source: {#PluginDir}\Greenshot.Plugin.Photobucket\Greenshot.Plugin.Photobucket.dll; DestDir: {app}\Plugins\Photobucket; Components: plugins\photobucket; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
Source: {#BaseDir}\Greenshot.Plugin.Photobucket\Languages\language_photo*.xml; DestDir: {app}\Languages\Plugins\Photobucket; Components: plugins\photobucket; Flags: overwritereadonly ignoreversion replacesameversion;
;Confluence Plugin
-Source: {#PluginDir}\Greenshot.Plugin.Confluence\*.dll; DestDir: {app}\Plugins\Confluence; Components: plugins\confluence; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
+Source: {#PluginDir}\Greenshot.Plugin.Confluence\Greenshot.Plugin.Confluence.dll; DestDir: {app}\Plugins\Confluence; Components: plugins\confluence; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
Source: {#BaseDir}\Greenshot.Plugin.Confluence\Languages\language_confluence*.xml; DestDir: {app}\Languages\Plugins\Confluence; Components: plugins\confluence; Flags: overwritereadonly ignoreversion replacesameversion;
;ExternalCommand Plugin
-Source: {#PluginDir}\Greenshot.Plugin.ExternalCommand\*.dll; DestDir: {app}\Plugins\ExternalCommand; Components: plugins\externalcommand; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
+Source: {#PluginDir}\Greenshot.Plugin.ExternalCommand\Greenshot.Plugin.ExternalCommand.dll; DestDir: {app}\Plugins\ExternalCommand; Components: plugins\externalcommand; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
Source: {#BaseDir}\Greenshot.Plugin.ExternalCommand\Languages\language_externalcommand*.xml; DestDir: {app}\Languages\Plugins\ExternalCommand; Components: plugins\externalcommand; Flags: overwritereadonly ignoreversion replacesameversion;
;Win 10 Plugin
-Source: {#PluginDir}\Greenshot.Plugin.Win10\*.dll; DestDir: {app}\Plugins\Win10; Components: plugins\win10; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
+Source: {#PluginDir}\Greenshot.Plugin.Win10\Greenshot.Plugin.Win10.dll; DestDir: {app}\Plugins\Win10; Components: plugins\win10; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
+Source: {#PluginDir}\Greenshot.Plugin.Win10\Microsoft.Toolkit.Uwp.Notifications.dll; DestDir: {app}\Plugins\Win10; Components: plugins\win10; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
[Setup]
; changes associations is used when the installer installs new extensions, it clears the explorer icon cache
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index b6533ddd7..131878749 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -1,13 +1,13 @@
- Copyright © Greenshot 2004-2021
+ Copyright © Greenshot 2004-2022
Greenshot
https://getgreenshot.org/favicon.ico
https://github.com/greenshot/greenshot
git
https://github.com/greenshot/greenshot
GPL-3.0-only
- 9
+ latest
true
true
win10-x64;win10-x86;win-x64;win-x86
@@ -46,7 +46,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers
diff --git a/src/Greenshot.Base/Core/ClipboardHelper.cs b/src/Greenshot.Base/Core/ClipboardHelper.cs
index 7a30a1143..bfe13c121 100644
--- a/src/Greenshot.Base/Core/ClipboardHelper.cs
+++ b/src/Greenshot.Base/Core/ClipboardHelper.cs
@@ -386,6 +386,7 @@ EndSelection:<<<<<<<4
/// IEnumerable{(MemoryStream,string)}
private static IEnumerable<(MemoryStream stream,string filename)> IterateClipboardContent(IDataObject dataObject)
{
+ if (dataObject == null) yield break;
var fileDescriptors = AvailableFileDescriptors(dataObject);
if (fileDescriptors == null) yield break;
@@ -499,6 +500,10 @@ EndSelection:<<<<<<<4
public static Image GetImage()
{
IDataObject clipboardData = GetDataObject();
+ if (clipboardData == null)
+ {
+ return null;
+ }
// Return the first image
foreach (var clipboardImage in GetImages(clipboardData))
{
@@ -520,7 +525,7 @@ EndSelection:<<<<<<<4
Bitmap singleImage = GetImage(dataObject);
if (singleImage != null)
{
- Log.InfoFormat($"Got {singleImage.GetType()} from clipboard with size {singleImage.Size}");
+ Log.Info($"Got {singleImage.GetType()} from clipboard with size {singleImage.Size}");
yield return singleImage;
yield break;
}
diff --git a/src/Greenshot.Base/Core/CoreConfiguration.cs b/src/Greenshot.Base/Core/CoreConfiguration.cs
index 580af8918..3e085bc9b 100644
--- a/src/Greenshot.Base/Core/CoreConfiguration.cs
+++ b/src/Greenshot.Base/Core/CoreConfiguration.cs
@@ -59,7 +59,7 @@ namespace Greenshot.Base.Core
[IniProperty("IEHotkey", Description = "Hotkey for starting the IE capture", DefaultValue = "Shift + Ctrl + PrintScreen")]
public string IEHotkey { get; set; }
- [IniProperty("ClipboardHotkey", Description = "Hotkey for opening the clipboard contents into the editor")]
+ [IniProperty("ClipboardHotkey", Description = "Hotkey for opening the clipboard contents into the editor", ExcludeIfNull = true)]
public string ClipboardHotkey { get; set; }
[IniProperty("IsFirstLaunch", Description = "Is this the first time launch?", DefaultValue = "true")]
@@ -388,89 +388,64 @@ namespace Greenshot.Base.Core
return ExperimentalFeatures != null && ExperimentalFeatures.Contains(experimentalFeature);
}
+ private string CreateOutputFilePath()
+ {
+ if (IniConfig.IsPortable)
+ {
+ string pafOutputFilePath = Path.Combine(Application.StartupPath, @"..\..\Documents\Pictures\Greenshots");
+ if (!Directory.Exists(pafOutputFilePath))
+ {
+ try
+ {
+ Directory.CreateDirectory(pafOutputFilePath);
+ return pafOutputFilePath;
+ }
+ catch (Exception ex)
+ {
+ // Problem creating directory, fallback to Desktop
+ LOG.Warn(ex);
+ }
+ }
+ else
+ {
+ return pafOutputFilePath;
+ }
+ }
+
+ return Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
+ }
+
///
/// Supply values we can't put as defaults
///
/// The property to return a default for
/// object with the default value for the supplied property
- public override object GetDefault(string property)
- {
- switch (property)
+ public override object GetDefault(string property) =>
+ property switch
{
- case nameof(ExcludePlugins):
- case nameof(IncludePlugins):
- return new List();
- case nameof(OutputFileAsFullpath):
- if (IniConfig.IsPortable)
- {
- return Path.Combine(Application.StartupPath, @"..\..\Documents\Pictures\Greenshots\dummy.png");
- }
-
- return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "dummy.png");
- case nameof(OutputFilePath):
- if (IniConfig.IsPortable)
- {
- string pafOutputFilePath = Path.Combine(Application.StartupPath, @"..\..\Documents\Pictures\Greenshots");
- if (!Directory.Exists(pafOutputFilePath))
- {
- try
- {
- Directory.CreateDirectory(pafOutputFilePath);
- return pafOutputFilePath;
- }
- catch (Exception ex)
- {
- LOG.Warn(ex);
- // Problem creating directory, fallback to Desktop
- }
- }
- else
- {
- return pafOutputFilePath;
- }
- }
-
- return Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
- case nameof(DWMBackgroundColor):
- return Color.Transparent;
- case nameof(ActiveTitleFixes):
- return new List
- {
- "Firefox",
- "IE",
- "Chrome"
- };
- case nameof(TitleFixMatcher):
- return new Dictionary
- {
- {
- "Firefox", " - Mozilla Firefox.*"
- },
- {
- "IE", " - (Microsoft|Windows) Internet Explorer.*"
- },
- {
- "Chrome", " - Google Chrome.*"
- }
- };
- case nameof(TitleFixReplacer):
- return new Dictionary
- {
- {
- "Firefox", string.Empty
- },
- {
- "IE", string.Empty
- },
- {
- "Chrome", string.Empty
- }
- };
- }
-
- return null;
- }
-
+ nameof(ExcludePlugins) => new List(),
+ nameof(IncludePlugins) => new List(),
+ nameof(OutputFileAsFullpath) => IniConfig.IsPortable ? Path.Combine(Application.StartupPath, @"..\..\Documents\Pictures\Greenshots\dummy.png") : Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "dummy.png"),
+ nameof(OutputFilePath) => CreateOutputFilePath(),
+ nameof(DWMBackgroundColor) => Color.Transparent,
+ nameof(ActiveTitleFixes) => new List {
+ "Firefox",
+ "IE",
+ "Chrome"
+ },
+ nameof(TitleFixMatcher) => new Dictionary {
+ { "Firefox", " - Mozilla Firefox.*" },
+ { "IE", " - (Microsoft|Windows) Internet Explorer.*" },
+ { "Chrome", " - Google Chrome.*" }
+ },
+ nameof(TitleFixReplacer) => new Dictionary {
+ { "Firefox", string.Empty },
+ { "IE", string.Empty },
+ { "Chrome", string.Empty }
+ },
+ _ => null
+ };
+
///
/// This method will be called before converting the property, making to possible to correct a certain value
/// Can be used when migration is needed
@@ -540,8 +515,9 @@ namespace Greenshot.Base.Core
OutputFileAutoReduceColors = false;
}
+ bool isUpgradeFrom12 = LastSaveWithVersion?.StartsWith("1.2") ?? false;
// Fix for excessive feed checking
- if (UpdateCheckInterval != 0 && UpdateCheckInterval <= 7 && LastSaveWithVersion.StartsWith("1.2"))
+ if (UpdateCheckInterval != 0 && UpdateCheckInterval <= 7 && isUpgradeFrom12)
{
UpdateCheckInterval = 14;
}
diff --git a/src/Greenshot.Base/Core/PluginUtils.cs b/src/Greenshot.Base/Core/PluginUtils.cs
index d41e545a5..76f08422b 100644
--- a/src/Greenshot.Base/Core/PluginUtils.cs
+++ b/src/Greenshot.Base/Core/PluginUtils.cs
@@ -24,6 +24,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
+using System.Linq;
using System.Windows.Forms;
using Dapplo.Windows.Icons;
using Greenshot.Base.IniFile;
@@ -39,9 +40,9 @@ namespace Greenshot.Base.Core
{
private static readonly ILog Log = LogManager.GetLogger(typeof(PluginUtils));
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection();
- private const string PathKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\";
private static readonly IDictionary ExeIconCache = new Dictionary();
-
+ private const string PathKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\";
+
static PluginUtils()
{
CoreConfig.PropertyChanged += OnIconSizeChanged;
@@ -84,7 +85,7 @@ namespace Greenshot.Base.Core
if (key != null)
{
// "" is the default key, which should point to the requested location
- return (string) key.GetValue(string.Empty);
+ return (string)key.GetValue(string.Empty);
}
}
diff --git a/src/Greenshot.Base/Core/WindowDetails.cs b/src/Greenshot.Base/Core/WindowDetails.cs
index 281dde6f4..9cdf5f370 100644
--- a/src/Greenshot.Base/Core/WindowDetails.cs
+++ b/src/Greenshot.Base/Core/WindowDetails.cs
@@ -42,8 +42,6 @@ namespace Greenshot.Base.Core
{
private const string AppWindowClass = "Windows.UI.Core.CoreWindow"; //Used for Windows 8(.1)
private const string AppFrameWindowClass = "ApplicationFrameWindow"; // Windows 10 uses ApplicationFrameWindow
- private const string ApplauncherClass = "ImmersiveLauncher";
- private const string GutterClass = "ImmersiveGutter";
private static readonly IList IgnoreClasses = new List(new[]
{
@@ -89,13 +87,7 @@ namespace Greenshot.Base.Core
private IntPtr _parentHandle = IntPtr.Zero;
private WindowDetails _parent;
private bool _frozen;
-
- ///
- /// This checks if the window is a Windows 8 App
- /// For Windows 10 most normal code works, as it's hosted inside "ApplicationFrameWindow"
- ///
- public bool IsApp => AppWindowClass.Equals(ClassName);
-
+
///
/// This checks if the window is a Windows 10 App
/// For Windows 10 apps are hosted inside "ApplicationFrameWindow"
@@ -108,20 +100,6 @@ namespace Greenshot.Base.Core
public bool IsBackgroundWin10App => WindowsVersion.IsWindows10OrLater && AppFrameWindowClass.Equals(ClassName) &&
!Children.Any(window => string.Equals(window.ClassName, AppWindowClass));
- ///
- /// Check if the window is the metro gutter (sizeable separator)
- ///
- public bool IsGutter => GutterClass.Equals(ClassName);
-
- ///
- /// Test if this window is for the App-Launcher
- ///
- public bool IsAppLauncher => ApplauncherClass.Equals(ClassName);
-
- ///
- /// Check if this window is the window of a metro app
- ///
- public bool IsMetroApp => IsAppLauncher || IsApp;
///
/// To allow items to be compared, the hash code
@@ -226,12 +204,6 @@ namespace Greenshot.Base.Core
Log.Warn(ex);
}
- if (IsMetroApp)
- {
- // No method yet to get the metro icon
- return null;
- }
-
try
{
return PluginUtils.GetCachedExeIcon(ProcessPath, 0);
@@ -467,11 +439,6 @@ namespace Greenshot.Base.Core
{
get
{
- if (IsMetroApp)
- {
- return !Visible;
- }
-
return User32Api.IsIconic(Handle) || Location.X <= -32000;
}
set
@@ -494,22 +461,6 @@ namespace Greenshot.Base.Core
{
get
{
- if (IsApp)
- {
- if (Visible)
- {
- foreach (var displayInfo in DisplayInfo.AllDisplayInfos)
- {
- if (WindowRectangle.Equals(displayInfo.Bounds))
- {
- return true;
- }
- }
- }
-
- return false;
- }
-
return User32Api.IsZoomed(Handle);
}
set
@@ -546,50 +497,6 @@ namespace Greenshot.Base.Core
return false;
}
- if (IsApp)
- {
- var windowRectangle = WindowRectangle;
-
- foreach (var displayInfo in DisplayInfo.AllDisplayInfos)
- {
- if (!displayInfo.Bounds.Contains(windowRectangle)) continue;
- if (windowRectangle.Equals(displayInfo.Bounds))
- {
- // Fullscreen, it's "visible" when AppVisibilityOnMonitor says yes
- // Although it might be the other App, this is not "very" important
- NativeRect rect = displayInfo.Bounds;
- IntPtr monitor = User32Api.MonitorFromRect(ref rect, MonitorFrom.DefaultToNull);
- if (monitor != IntPtr.Zero)
- {
- MONITOR_APP_VISIBILITY? monitorAppVisibility = AppVisibility?.GetAppVisibilityOnMonitor(monitor);
- //LOG.DebugFormat("App {0} visible: {1} on {2}", Text, monitorAppVisibility, screen.Bounds);
- if (monitorAppVisibility == MONITOR_APP_VISIBILITY.MAV_APP_VISIBLE)
- {
- return true;
- }
- }
- }
- else
- {
- // Is only partly on the screen, when this happens the app is always visible!
- return true;
- }
- }
-
- return false;
- }
-
- if (IsGutter)
- {
- // gutter is only made available when it's visible
- return true;
- }
-
- if (IsAppLauncher)
- {
- return IsAppLauncherVisible;
- }
-
return User32Api.IsWindowVisible(Handle);
}
}
@@ -643,69 +550,56 @@ namespace Greenshot.Base.Core
{
// Try to return a cached value
long now = DateTime.Now.Ticks;
- if (_previousWindowRectangle.IsEmpty || !_frozen)
- {
- if (!_previousWindowRectangle.IsEmpty && now - _lastWindowRectangleRetrieveTime <= CacheTime)
- {
- return _previousWindowRectangle;
- }
- NativeRect windowRect = new();
- if (DwmApi.IsDwmEnabled)
- {
- bool gotFrameBounds = GetExtendedFrameBounds(out windowRect);
- if (IsApp)
- {
- // Pre-Cache for maximized call, this is only on Windows 8 apps (full screen)
- if (gotFrameBounds)
- {
- _previousWindowRectangle = windowRect;
- _lastWindowRectangleRetrieveTime = now;
- }
- }
+ if (!_previousWindowRectangle.IsEmpty && _frozen) return _previousWindowRectangle;
- if (gotFrameBounds && WindowsVersion.IsWindows10OrLater && !Maximised)
+ if (!_previousWindowRectangle.IsEmpty && now - _lastWindowRectangleRetrieveTime <= CacheTime)
+ {
+ return _previousWindowRectangle;
+ }
+ NativeRect windowRect = new();
+ if (DwmApi.IsDwmEnabled)
+ {
+ bool gotFrameBounds = GetExtendedFrameBounds(out windowRect);
+ if (IsWin10App)
+ {
+ // Pre-Cache for maximized call, this is only on Windows 8 apps (full screen)
+ if (gotFrameBounds)
{
- // Somehow DWM doesn't calculate it correctly, there is a 1 pixel border around the capture
- // Remove this border, currently it's fixed but TODO: Make it depend on the OS?
- windowRect = windowRect.Inflate(Conf.Win10BorderCrop);
_previousWindowRectangle = windowRect;
_lastWindowRectangleRetrieveTime = now;
- return windowRect;
}
}
- if (windowRect.IsEmpty)
+ if (gotFrameBounds && WindowsVersion.IsWindows10OrLater && !Maximised)
{
- if (!GetWindowRect(out windowRect))
- {
- Win32Error error = Win32.GetLastErrorCode();
- Log.WarnFormat("Couldn't retrieve the windows rectangle: {0}", Win32.GetMessage(error));
- }
+ // Somehow DWM doesn't calculate it correctly, there is a 1 pixel border around the capture
+ // Remove this border, currently it's fixed but TODO: Make it depend on the OS?
+ windowRect = windowRect.Inflate(Conf.Win10BorderCrop);
+ _previousWindowRectangle = windowRect;
+ _lastWindowRectangleRetrieveTime = now;
+ return windowRect;
}
-
- // Correction for maximized windows, only if it's not an app
- if (!HasParent && !IsApp && Maximised)
- {
- // Only if the border size can be retrieved
- if (GetBorderSize(out var size))
- {
- windowRect = new NativeRect(windowRect.X + size.Width, windowRect.Y + size.Height, windowRect.Width - (2 * size.Width),
- windowRect.Height - (2 * size.Height));
- }
- }
-
- _lastWindowRectangleRetrieveTime = now;
- // Try to return something valid, by getting returning the previous size if the window doesn't have a NativeRect anymore
- if (windowRect.IsEmpty)
- {
- return _previousWindowRectangle;
- }
-
- _previousWindowRectangle = windowRect;
- return windowRect;
}
- return _previousWindowRectangle;
+ if (windowRect.IsEmpty)
+ {
+ if (!GetWindowRect(out windowRect))
+ {
+ Win32Error error = Win32.GetLastErrorCode();
+ Log.WarnFormat("Couldn't retrieve the windows rectangle: {0}", Win32.GetMessage(error));
+ }
+ }
+
+ _lastWindowRectangleRetrieveTime = now;
+ // Try to return something valid, by getting returning the previous size if the window doesn't have a NativeRect anymore
+ if (windowRect.IsEmpty)
+ {
+ return _previousWindowRectangle;
+ }
+
+ _previousWindowRectangle = windowRect;
+ return windowRect;
+
}
}
@@ -928,7 +822,7 @@ namespace Greenshot.Base.Core
{
// if GDI is allowed.. (a screenshot won't be better than we comes if we continue)
using Process thisWindowProcess = Process;
- if (!IsMetroApp && WindowCapture.IsGdiAllowed(thisWindowProcess))
+ if (WindowCapture.IsGdiAllowed(thisWindowProcess))
{
// we return null which causes the capturing code to try another method.
return null;
@@ -973,11 +867,8 @@ namespace Greenshot.Base.Core
tempForm.BackColor = Color.Black;
// Make sure everything is visible
tempForm.Refresh();
- if (!IsMetroApp)
- {
- // Make sure the application window is active, so the colors & buttons are right
- ToForeground();
- }
+ // Make sure the application window is active, so the colors & buttons are right
+ ToForeground();
// Make sure all changes are processed and visible
Application.DoEvents();
@@ -1013,11 +904,8 @@ namespace Greenshot.Base.Core
// Make sure everything is visible
tempForm.Refresh();
- if (!IsMetroApp)
- {
- // Make sure the application window is active, so the colors & buttons are right
- ToForeground();
- }
+ // Make sure the application window is active, so the colors & buttons are right
+ ToForeground();
// Make sure all changes are processed and visible
Application.DoEvents();
@@ -1154,6 +1042,13 @@ namespace Greenshot.Base.Core
return targetBuffer.UnlockAndReturnBitmap();
}
+ ///
+ /// If a window is hidden (Iconic), it also has the specified dimensions.
+ ///
+ /// NativeRect
+ /// bool true if hidden
+ private bool IsHidden(NativeRect rect) => rect.Width == 65535 && rect.Height == 65535 && rect.Left == 32767 && rect.Top == 32767;
+
///
/// Helper method to get the window size for DWM Windows
///
@@ -1164,6 +1059,10 @@ namespace Greenshot.Base.Core
var result = DwmApi.DwmGetWindowAttribute(Handle, DwmWindowAttributes.ExtendedFrameBounds, out NativeRect rect, Marshal.SizeOf(typeof(NativeRect)));
if (result.Succeeded())
{
+ if (IsHidden(rect))
+ {
+ rect = NativeRect.Empty;
+ }
rectangle = rect;
return true;
}
@@ -1196,7 +1095,14 @@ namespace Greenshot.Base.Core
var windowInfo = new WindowInfo();
// Get the Window Info for this window
bool result = User32Api.GetWindowInfo(Handle, ref windowInfo);
- rectangle = result ? windowInfo.Bounds : NativeRect.Empty;
+ if (IsHidden(windowInfo.Bounds))
+ {
+ rectangle = NativeRect.Empty;
+ }
+ else
+ {
+ rectangle = result ? windowInfo.Bounds : NativeRect.Empty;
+ }
return result;
}
@@ -1577,7 +1483,7 @@ namespace Greenshot.Base.Core
// Skip everything which is not rendered "normally", trying to fix BUG-2017
var exWindowStyle = window.ExtendedWindowStyle;
- if (!window.IsApp && !window.IsWin10App && (exWindowStyle & ExtendedWindowStyleFlags.WS_EX_NOREDIRECTIONBITMAP) != 0)
+ if (!window.IsWin10App && (exWindowStyle & ExtendedWindowStyleFlags.WS_EX_NOREDIRECTIONBITMAP) != 0)
{
return false;
}
@@ -1592,13 +1498,6 @@ namespace Greenshot.Base.Core
public static IEnumerable GetVisibleWindows()
{
var screenBounds = DisplayInfo.ScreenBounds;
- foreach (var window in GetAppWindows())
- {
- if (IsVisible(window, screenBounds))
- {
- yield return window;
- }
- }
foreach (var window in GetAllWindows())
{
@@ -1609,38 +1508,6 @@ namespace Greenshot.Base.Core
}
}
- ///
- /// Get the WindowDetails for all Metro Apps
- /// These are all Windows with Classname "Windows.UI.Core.CoreWindow"
- ///
- /// List WindowDetails with visible metro apps
- public static IEnumerable GetAppWindows()
- {
- // if the appVisibility != null we have Windows 8.
- if (AppVisibility == null)
- {
- yield break;
- }
-
- var nextHandle = User32Api.FindWindow(AppWindowClass, null);
- while (nextHandle != IntPtr.Zero)
- {
- var metroApp = new WindowDetails(nextHandle);
- yield return metroApp;
- // Check if we have a gutter!
- if (metroApp.Visible && !metroApp.Maximised)
- {
- var gutterHandle = User32Api.FindWindow(GutterClass, null);
- if (gutterHandle != IntPtr.Zero)
- {
- yield return new WindowDetails(gutterHandle);
- }
- }
-
- nextHandle = User32Api.FindWindowEx(IntPtr.Zero, nextHandle, AppWindowClass, null);
- }
- }
-
///
/// Check if the window is a top level
///
@@ -1671,7 +1538,7 @@ namespace Greenshot.Base.Core
}
// Skip everything which is not rendered "normally", trying to fix BUG-2017
- if (!window.IsApp && !window.IsWin10App && (exWindowStyle & ExtendedWindowStyleFlags.WS_EX_NOREDIRECTIONBITMAP) != 0)
+ if (!window.IsWin10App && (exWindowStyle & ExtendedWindowStyleFlags.WS_EX_NOREDIRECTIONBITMAP) != 0)
{
return false;
}
@@ -1707,14 +1574,6 @@ namespace Greenshot.Base.Core
/// List WindowDetails with all the top level windows
public static IEnumerable GetTopLevelWindows()
{
- foreach (var possibleTopLevel in GetAppWindows())
- {
- if (IsTopLevel(possibleTopLevel))
- {
- yield return possibleTopLevel;
- }
- }
-
foreach (var possibleTopLevel in GetAllWindows())
{
if (IsTopLevel(possibleTopLevel))
@@ -1790,27 +1649,6 @@ namespace Greenshot.Base.Core
}
}
- ///
- /// Get the AppLauncher
- ///
- ///
- public static WindowDetails GetAppLauncher()
- {
- // Only if Windows 8 (or higher)
- if (AppVisibility == null)
- {
- return null;
- }
-
- IntPtr appLauncher = User32Api.FindWindow(ApplauncherClass, null);
- if (appLauncher != IntPtr.Zero)
- {
- return new WindowDetails(appLauncher);
- }
-
- return null;
- }
-
///
/// Return true if the metro-app-launcher is visible
///
@@ -1842,7 +1680,6 @@ namespace Greenshot.Base.Core
result.AppendLine($"Size: {WindowRectangle.Size}");
result.AppendLine($"HasParent: {HasParent}");
result.AppendLine($"IsWin10App: {IsWin10App}");
- result.AppendLine($"IsApp: {IsApp}");
result.AppendLine($"Visible: {Visible}");
result.AppendLine($"IsWindowVisible: {User32Api.IsWindowVisible(Handle)}");
result.AppendLine($"IsCloaked: {IsCloaked}");
diff --git a/src/Greenshot.Base/Greenshot.Base.csproj b/src/Greenshot.Base/Greenshot.Base.csproj
index 805098491..7e55c1dbc 100644
--- a/src/Greenshot.Base/Greenshot.Base.csproj
+++ b/src/Greenshot.Base/Greenshot.Base.csproj
@@ -5,16 +5,16 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Greenshot.Editor/Drawing/Adorners/ResizeAdorner.cs b/src/Greenshot.Editor/Drawing/Adorners/ResizeAdorner.cs
index 41c7aab8a..263d5a31e 100644
--- a/src/Greenshot.Editor/Drawing/Adorners/ResizeAdorner.cs
+++ b/src/Greenshot.Editor/Drawing/Adorners/ResizeAdorner.cs
@@ -103,7 +103,7 @@ namespace Greenshot.Editor.Drawing.Adorners
var scaleOptions = (Owner as IHaveScaleOptions)?.GetScaleOptions();
// calculate scaled rectangle
- _boundsAfterResize = ScaleHelper.Scale(_boundsAfterResize, Position, new PointF(mouseEventArgs.X, mouseEventArgs.Y), scaleOptions);
+ _boundsAfterResize = ScaleHelper.Scale(_boundsAfterResize, Position, new NativePointFloat(mouseEventArgs.X, mouseEventArgs.Y), scaleOptions);
// apply scaled bounds to this DrawableContainer
Owner.ApplyBounds(_boundsAfterResize);
diff --git a/src/Greenshot.Editor/Drawing/CropContainer.cs b/src/Greenshot.Editor/Drawing/CropContainer.cs
index d450e9dd2..eb2f7179e 100644
--- a/src/Greenshot.Editor/Drawing/CropContainer.cs
+++ b/src/Greenshot.Editor/Drawing/CropContainer.cs
@@ -247,10 +247,11 @@ namespace Greenshot.Editor.Drawing
_boundsAfterResize = new NativeRectFloat(
_boundsBeforeResize.Left, _boundsBeforeResize.Top,
x - _boundsAfterResize.Left, y - _boundsAfterResize.Top);
+
+ _boundsAfterResize = ScaleHelper.Scale(_boundsAfterResize, x, y, GetAngleRoundProcessor());
break;
}
}
- _boundsAfterResize = ScaleHelper.Scale(_boundsBeforeResize, Positions.TopLeft, x, y, GetAngleRoundProcessor());
// apply scaled bounds to this DrawableContainer
ApplyBounds(_boundsAfterResize);
diff --git a/src/Greenshot.Editor/Drawing/DrawableContainer.cs b/src/Greenshot.Editor/Drawing/DrawableContainer.cs
index 164ed7177..33bc228c0 100644
--- a/src/Greenshot.Editor/Drawing/DrawableContainer.cs
+++ b/src/Greenshot.Editor/Drawing/DrawableContainer.cs
@@ -534,7 +534,7 @@ namespace Greenshot.Editor.Drawing
_boundsAfterResize = new NativeRectFloat(_boundsBeforeResize.Left, _boundsBeforeResize.Top, x - _boundsAfterResize.Left, y - _boundsAfterResize.Top);
var scaleOptions = (this as IHaveScaleOptions)?.GetScaleOptions();
- _boundsAfterResize = ScaleHelper.Scale(_boundsAfterResize, Positions.TopLeft, x, y,GetAngleRoundProcessor(), scaleOptions);
+ _boundsAfterResize = ScaleHelper.Scale(_boundsAfterResize, x, y,GetAngleRoundProcessor(), scaleOptions);
// apply scaled bounds to this DrawableContainer
ApplyBounds(_boundsAfterResize);
@@ -667,9 +667,9 @@ namespace Greenshot.Editor.Drawing
Height = points[1].Y - points[0].Y;
}
- protected virtual ScaleHelper.IDoubleProcessor GetAngleRoundProcessor()
+ protected virtual IDoubleProcessor GetAngleRoundProcessor()
{
- return ScaleHelper.ShapeAngleRoundBehavior.INSTANCE;
+ return ShapeAngleRoundBehavior.INSTANCE;
}
public virtual bool HasContextMenu => true;
diff --git a/src/Greenshot.Editor/Drawing/EmojiContainer.cs b/src/Greenshot.Editor/Drawing/EmojiContainer.cs
index bec010d24..d84c205ab 100644
--- a/src/Greenshot.Editor/Drawing/EmojiContainer.cs
+++ b/src/Greenshot.Editor/Drawing/EmojiContainer.cs
@@ -166,9 +166,9 @@ namespace Greenshot.Editor.Drawing
return image;
}
- public ScaleHelper.ScaleOptions GetScaleOptions()
+ public ScaleOptions GetScaleOptions()
{
- return ScaleHelper.ScaleOptions.Rational;
+ return ScaleOptions.Rational;
}
}
}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Drawing/LineContainer.cs b/src/Greenshot.Editor/Drawing/LineContainer.cs
index ef4a68707..f48dddec7 100644
--- a/src/Greenshot.Editor/Drawing/LineContainer.cs
+++ b/src/Greenshot.Editor/Drawing/LineContainer.cs
@@ -115,9 +115,9 @@ namespace Greenshot.Editor.Drawing
return false;
}
- protected override ScaleHelper.IDoubleProcessor GetAngleRoundProcessor()
+ protected override IDoubleProcessor GetAngleRoundProcessor()
{
- return ScaleHelper.LineAngleRoundBehavior.INSTANCE;
+ return LineAngleRoundBehavior.INSTANCE;
}
}
}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs
index ad129c4ba..b14a33bd0 100644
--- a/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs
+++ b/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs
@@ -100,8 +100,7 @@ namespace Greenshot.Editor.FileFormatHandlers
bitmap = new Bitmap(infoHeader.Width, infoHeader.Height,
-(int)(infoHeader.SizeImage / infoHeader.Height),
infoHeader.BitCount == 32 ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb,
- new IntPtr(handle.AddrOfPinnedObject().ToInt32() + infoHeader.OffsetToPixels +
- (infoHeader.Height - 1) * (int)(infoHeader.SizeImage / infoHeader.Height))
+ IntPtr.Add(handle.AddrOfPinnedObject(), (int)infoHeader.OffsetToPixels + (infoHeader.Height - 1) * (int)(infoHeader.SizeImage / infoHeader.Height))
);
}
catch (Exception ex)
diff --git a/src/Greenshot.Editor/Helpers/IDoubleProcessor.cs b/src/Greenshot.Editor/Helpers/IDoubleProcessor.cs
new file mode 100644
index 000000000..beb426c68
--- /dev/null
+++ b/src/Greenshot.Editor/Helpers/IDoubleProcessor.cs
@@ -0,0 +1,28 @@
+/*
+ * 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 .
+ */
+
+namespace Greenshot.Editor.Helpers
+{
+ public interface IDoubleProcessor
+ {
+ double Process(double d);
+ }
+}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Helpers/IHaveScaleOptions.cs b/src/Greenshot.Editor/Helpers/IHaveScaleOptions.cs
index c489e7780..aacfdbe37 100644
--- a/src/Greenshot.Editor/Helpers/IHaveScaleOptions.cs
+++ b/src/Greenshot.Editor/Helpers/IHaveScaleOptions.cs
@@ -23,6 +23,6 @@ namespace Greenshot.Editor.Helpers
{
public interface IHaveScaleOptions
{
- ScaleHelper.ScaleOptions GetScaleOptions();
+ ScaleOptions GetScaleOptions();
}
-}
+}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Helpers/LineAngleRoundBehavior.cs b/src/Greenshot.Editor/Helpers/LineAngleRoundBehavior.cs
new file mode 100644
index 000000000..6811f66cf
--- /dev/null
+++ b/src/Greenshot.Editor/Helpers/LineAngleRoundBehavior.cs
@@ -0,0 +1,39 @@
+/*
+ * 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 .
+ */
+
+using System;
+
+namespace Greenshot.Editor.Helpers
+{
+ public class LineAngleRoundBehavior : IDoubleProcessor
+ {
+ public static readonly LineAngleRoundBehavior INSTANCE = new();
+
+ private LineAngleRoundBehavior()
+ {
+ }
+
+ public double Process(double angle)
+ {
+ return Math.Round(angle / 15) * 15;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Helpers/ScaleHelper.cs b/src/Greenshot.Editor/Helpers/ScaleHelper.cs
index b5e2c61e2..bc4bd361e 100644
--- a/src/Greenshot.Editor/Helpers/ScaleHelper.cs
+++ b/src/Greenshot.Editor/Helpers/ScaleHelper.cs
@@ -33,26 +33,7 @@ namespace Greenshot.Editor.Helpers
///
public static class ScaleHelper
{
- [Flags]
- public enum ScaleOptions
- {
///
- /// Default scale behavior.
- ///
- Default = 0x00,
-
- ///
- /// Scale a rectangle in two our four directions, mirrored at it's center coordinates
- ///
- Centered = 0x01,
-
- ///
- /// Scale a rectangle maintaining it's aspect ratio
- ///
- Rational = 0x02
- }
-
- ///
/// calculates the Size an element must be resized to, in order to fit another element, keeping aspect ratio
///
/// the size of the element to be resized
@@ -231,16 +212,14 @@ namespace Greenshot.Editor.Helpers
/// Scale the boundsBeforeResize with the specified position and new location, using the angle angleRoundBehavior
///
/// NativeRect
- /// Positions
/// int
/// int
/// IDoubleProcessor
- /// ScaleOptionsProcessor
+ /// ScaleOptionsProcessor
/// NativeRectFloat
- public static NativeRectFloat Scale(NativeRect boundsBeforeResize, Positions gripperPosition, int cursorX, int cursorY, IDoubleProcessor angleRoundBehavior, ScaleOptions? options = null)
+ public static NativeRectFloat Scale(NativeRect boundsBeforeResize, int cursorX, int cursorY, IDoubleProcessor angleRoundBehavior, ScaleOptions? options = null)
{
options ??= GetScaleOptions();
-
NativeRectFloat result = boundsBeforeResize;
bool rationalScale = (options & ScaleOptions.Rational) == ScaleOptions.Rational;
bool centeredScale = (options & ScaleOptions.Centered) == ScaleOptions.Centered;
@@ -281,38 +260,5 @@ namespace Greenshot.Editor.Helpers
if (maintainAspectRatio) opts |= ScaleOptions.Rational;
return opts;
}
-
- public interface IDoubleProcessor
- {
- double Process(double d);
}
-
- public class ShapeAngleRoundBehavior : IDoubleProcessor
- {
- public static readonly ShapeAngleRoundBehavior INSTANCE = new();
-
- private ShapeAngleRoundBehavior()
- {
- }
-
- public double Process(double angle)
- {
- return Math.Round((angle + 45) / 90) * 90 - 45;
- }
- }
-
- public class LineAngleRoundBehavior : IDoubleProcessor
- {
- public static readonly LineAngleRoundBehavior INSTANCE = new();
-
- private LineAngleRoundBehavior()
- {
- }
-
- public double Process(double angle)
- {
- return Math.Round(angle / 15) * 15;
- }
- }
- }
}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Helpers/ScaleOptions.cs b/src/Greenshot.Editor/Helpers/ScaleOptions.cs
new file mode 100644
index 000000000..1f47f5c02
--- /dev/null
+++ b/src/Greenshot.Editor/Helpers/ScaleOptions.cs
@@ -0,0 +1,44 @@
+/*
+ * 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 .
+ */
+
+using System;
+
+namespace Greenshot.Editor.Helpers
+{
+ [Flags]
+ public enum ScaleOptions
+ {
+ ///
+ /// Default scale behavior.
+ ///
+ Default = 0x00,
+
+ ///
+ /// Scale a rectangle in two our four directions, mirrored at it's center coordinates
+ ///
+ Centered = 0x01,
+
+ ///
+ /// Scale a rectangle maintaining it's aspect ratio
+ ///
+ Rational = 0x02
+ }
+}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Helpers/ShapeAngleRoundBehavior.cs b/src/Greenshot.Editor/Helpers/ShapeAngleRoundBehavior.cs
new file mode 100644
index 000000000..ba173df9f
--- /dev/null
+++ b/src/Greenshot.Editor/Helpers/ShapeAngleRoundBehavior.cs
@@ -0,0 +1,39 @@
+/*
+ * 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 .
+ */
+
+using System;
+
+namespace Greenshot.Editor.Helpers
+{
+ public class ShapeAngleRoundBehavior : IDoubleProcessor
+ {
+ public static readonly ShapeAngleRoundBehavior INSTANCE = new();
+
+ private ShapeAngleRoundBehavior()
+ {
+ }
+
+ public double Process(double angle)
+ {
+ return Math.Round((angle + 45) / 90) * 90 - 45;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Greenshot.Plugin.Box/BoxConfiguration.cs b/src/Greenshot.Plugin.Box/BoxConfiguration.cs
index fdef95ae5..c745fe985 100644
--- a/src/Greenshot.Plugin.Box/BoxConfiguration.cs
+++ b/src/Greenshot.Plugin.Box/BoxConfiguration.cs
@@ -21,6 +21,7 @@
using System;
using System.Windows.Forms;
+using Greenshot.Base.Core;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.IniFile;
using Greenshot.Plugin.Box.Forms;
@@ -75,5 +76,20 @@ namespace Greenshot.Plugin.Box
return false;
}
+
+ ///
+ /// Upgrade certain values
+ ///
+ public override void AfterLoad()
+ {
+ var coreConfiguration = IniConfig.GetIniSection();
+ bool isUpgradeFrom12 = coreConfiguration.LastSaveWithVersion?.StartsWith("1.2") ?? false;
+ // Clear token when we upgrade from 1.2 to 1.3 as it is no longer valid, discussed in #421
+ if (!isUpgradeFrom12) return;
+
+ // We have an upgrade, remove all previous credentials.
+ RefreshToken = null;
+ AccessToken = null;
+ }
}
}
\ No newline at end of file
diff --git a/src/Greenshot.Plugin.Dropbox/DropboxConfiguration.cs b/src/Greenshot.Plugin.Dropbox/DropboxConfiguration.cs
index b9dd8bf0c..d79db8686 100644
--- a/src/Greenshot.Plugin.Dropbox/DropboxConfiguration.cs
+++ b/src/Greenshot.Plugin.Dropbox/DropboxConfiguration.cs
@@ -21,6 +21,7 @@
using System;
using System.Windows.Forms;
+using Greenshot.Base.Core;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.IniFile;
using Greenshot.Plugin.Dropbox.Forms;
@@ -69,5 +70,20 @@ namespace Greenshot.Plugin.Dropbox
return false;
}
+
+ ///
+ /// Upgrade certain values
+ ///
+ public override void AfterLoad()
+ {
+ var coreConfiguration = IniConfig.GetIniSection();
+ bool isUpgradeFrom12 = coreConfiguration.LastSaveWithVersion?.StartsWith("1.2") ?? false;
+ // Clear token when we upgrade from 1.2 to 1.3 as it is no longer valid, discussed in #421
+ if (!isUpgradeFrom12) return;
+
+ // We have an upgrade, remove all previous credentials.
+ RefreshToken = null;
+ AccessToken = null;
+ }
}
}
\ No newline at end of file
diff --git a/src/Greenshot.Plugin.Flickr/FlickrConfiguration.cs b/src/Greenshot.Plugin.Flickr/FlickrConfiguration.cs
index e4f602796..df5a428fa 100644
--- a/src/Greenshot.Plugin.Flickr/FlickrConfiguration.cs
+++ b/src/Greenshot.Plugin.Flickr/FlickrConfiguration.cs
@@ -20,6 +20,7 @@
*/
using System.Windows.Forms;
+using Greenshot.Base.Core;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.IniFile;
using Greenshot.Plugin.Flickr.Forms;
@@ -86,5 +87,21 @@ namespace Greenshot.Plugin.Flickr
return false;
}
+
+ ///
+ /// Upgrade certain values
+ ///
+ public override void AfterLoad()
+ {
+ var coreConfiguration = IniConfig.GetIniSection();
+ bool isUpgradeFrom12 = coreConfiguration.LastSaveWithVersion?.StartsWith("1.2") ?? false;
+ // Clear token when we upgrade from 1.2 to 1.3 as it is no longer valid, discussed in #421
+ if (!isUpgradeFrom12) return;
+
+ // We have an upgrade, remove all previous credentials.
+ FlickrToken = null;
+ FlickrTokenSecret = null;
+ }
+
}
}
\ No newline at end of file
diff --git a/src/Greenshot.Plugin.Imgur/ImgurConfiguration.cs b/src/Greenshot.Plugin.Imgur/ImgurConfiguration.cs
index 3bb695672..3dc145d0b 100644
--- a/src/Greenshot.Plugin.Imgur/ImgurConfiguration.cs
+++ b/src/Greenshot.Plugin.Imgur/ImgurConfiguration.cs
@@ -22,6 +22,7 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
+using Greenshot.Base.Core;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.IniFile;
using Greenshot.Plugin.Imgur.Forms;
@@ -84,6 +85,22 @@ namespace Greenshot.Plugin.Imgur
public Dictionary runtimeImgurHistory = new Dictionary();
public int Credits { get; set; }
+ ///
+ /// Upgrade certain values
+ ///
+ public override void AfterLoad()
+ {
+ var coreConfiguration = IniConfig.GetIniSection();
+ bool isUpgradeFrom12 = coreConfiguration.LastSaveWithVersion?.StartsWith("1.2") ?? false;
+ // Clear token when we upgrade from 1.2 to 1.3 as it is no longer valid, discussed in #421
+ if (!isUpgradeFrom12) return;
+
+ // We have an upgrade, remove all previous credentials.
+ AccessToken = null;
+ RefreshToken = null;
+ AccessTokenExpires = default;
+ }
+
///
/// Supply values we can't put as defaults
///
@@ -92,7 +109,7 @@ namespace Greenshot.Plugin.Imgur
public override object GetDefault(string property) =>
property switch
{
- "ImgurUploadHistory" => new Dictionary(),
+ nameof(ImgurUploadHistory) => new Dictionary(),
_ => null
};
diff --git a/src/Greenshot.Plugin.Jira/Greenshot.Plugin.Jira.csproj b/src/Greenshot.Plugin.Jira/Greenshot.Plugin.Jira.csproj
index 40f2caf2d..a06e33882 100644
--- a/src/Greenshot.Plugin.Jira/Greenshot.Plugin.Jira.csproj
+++ b/src/Greenshot.Plugin.Jira/Greenshot.Plugin.Jira.csproj
@@ -6,7 +6,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/src/Greenshot.Plugin.Office/Destinations/ExcelDestination.cs b/src/Greenshot.Plugin.Office/Destinations/ExcelDestination.cs
index fb1930c8c..1a671cf7a 100644
--- a/src/Greenshot.Plugin.Office/Destinations/ExcelDestination.cs
+++ b/src/Greenshot.Plugin.Office/Destinations/ExcelDestination.cs
@@ -42,7 +42,8 @@ namespace Greenshot.Plugin.Office.Destinations
static ExcelDestination()
{
- ExePath = PluginUtils.GetExePath("EXCEL.EXE");
+ ExePath = OfficeUtils.GetOfficeExePath("EXCEL.EXE") ?? PluginUtils.GetExePath("EXCEL.EXE");
+
if (ExePath != null && File.Exists(ExePath))
{
WindowDetails.AddProcessToExcludeFromFreeze("excel");
diff --git a/src/Greenshot.Plugin.Office/Destinations/OneNoteDestination.cs b/src/Greenshot.Plugin.Office/Destinations/OneNoteDestination.cs
index 387810494..5f8da7a67 100644
--- a/src/Greenshot.Plugin.Office/Destinations/OneNoteDestination.cs
+++ b/src/Greenshot.Plugin.Office/Destinations/OneNoteDestination.cs
@@ -41,7 +41,7 @@ namespace Greenshot.Plugin.Office.Destinations
static OneNoteDestination()
{
- exePath = PluginUtils.GetExePath("ONENOTE.EXE");
+ exePath = OfficeUtils.GetOfficeExePath("ONENOTE.EXE") ?? PluginUtils.GetExePath("ONENOTE.EXE");
if (exePath != null && File.Exists(exePath))
{
WindowDetails.AddProcessToExcludeFromFreeze("onenote");
diff --git a/src/Greenshot.Plugin.Office/Destinations/OutlookDestination.cs b/src/Greenshot.Plugin.Office/Destinations/OutlookDestination.cs
index 6d93c4096..3c77ea4f1 100644
--- a/src/Greenshot.Plugin.Office/Destinations/OutlookDestination.cs
+++ b/src/Greenshot.Plugin.Office/Destinations/OutlookDestination.cs
@@ -58,8 +58,7 @@ namespace Greenshot.Plugin.Office.Destinations
{
IsActiveFlag = true;
}
-
- ExePath = PluginUtils.GetExePath("OUTLOOK.EXE");
+ ExePath = OfficeUtils.GetOfficeExePath("OUTLOOK.EXE") ?? PluginUtils.GetExePath("OUTLOOK.EXE");
if (ExePath != null && File.Exists(ExePath))
{
WindowDetails.AddProcessToExcludeFromFreeze("outlook");
diff --git a/src/Greenshot.Plugin.Office/Destinations/PowerpointDestination.cs b/src/Greenshot.Plugin.Office/Destinations/PowerpointDestination.cs
index 3b9ce4bc8..010093027 100644
--- a/src/Greenshot.Plugin.Office/Destinations/PowerpointDestination.cs
+++ b/src/Greenshot.Plugin.Office/Destinations/PowerpointDestination.cs
@@ -45,7 +45,7 @@ namespace Greenshot.Plugin.Office.Destinations
static PowerpointDestination()
{
- ExePath = PluginUtils.GetExePath("POWERPNT.EXE");
+ ExePath = OfficeUtils.GetOfficeExePath("POWERPNT.EXE") ?? PluginUtils.GetExePath("POWERPNT.EXE");
if (ExePath != null && File.Exists(ExePath))
{
WindowDetails.AddProcessToExcludeFromFreeze("powerpnt");
diff --git a/src/Greenshot.Plugin.Office/Destinations/WordDestination.cs b/src/Greenshot.Plugin.Office/Destinations/WordDestination.cs
index 99cf4693c..d6220a302 100644
--- a/src/Greenshot.Plugin.Office/Destinations/WordDestination.cs
+++ b/src/Greenshot.Plugin.Office/Destinations/WordDestination.cs
@@ -46,7 +46,7 @@ namespace Greenshot.Plugin.Office.Destinations
static WordDestination()
{
- ExePath = PluginUtils.GetExePath("WINWORD.EXE");
+ ExePath = OfficeUtils.GetOfficeExePath("WINWORD.EXE") ?? PluginUtils.GetExePath("WINWORD.EXE");
if (ExePath != null && !File.Exists(ExePath))
{
ExePath = null;
@@ -118,7 +118,7 @@ namespace Greenshot.Plugin.Office.Destinations
if (!manuallyInitiated)
{
var documents = _wordExporter.GetWordDocuments().ToList();
- if (documents != null && documents.Count > 0)
+ if (documents is { Count: > 0 })
{
var destinations = new List
{
diff --git a/src/Greenshot.Plugin.Office/Greenshot.Plugin.Office.csproj b/src/Greenshot.Plugin.Office/Greenshot.Plugin.Office.csproj
index fdb555adc..347a58339 100644
--- a/src/Greenshot.Plugin.Office/Greenshot.Plugin.Office.csproj
+++ b/src/Greenshot.Plugin.Office/Greenshot.Plugin.Office.csproj
@@ -78,23 +78,23 @@
-
+
true
runtime
-
+
true
runtime
-
+
true
runtime
-
+
true
runtime
-
+
true
runtime
diff --git a/src/Greenshot.Plugin.Office/OfficeUtils.cs b/src/Greenshot.Plugin.Office/OfficeUtils.cs
new file mode 100644
index 000000000..52ca8d7cb
--- /dev/null
+++ b/src/Greenshot.Plugin.Office/OfficeUtils.cs
@@ -0,0 +1,43 @@
+using System.Linq;
+using Microsoft.Win32;
+
+namespace Greenshot.Plugin.Office;
+
+///
+/// A small utility class for helping with office
+///
+internal static class OfficeUtils
+{
+ private static readonly string[] OfficeRootKeys = { @"SOFTWARE\Microsoft\Office", @"SOFTWARE\WOW6432Node\Microsoft\Office" };
+
+ ///
+ /// Get the path to the office exe
+ ///
+ /// Name of the office executable
+ public static string GetOfficeExePath(string exeName)
+ {
+ string strKeyName = exeName switch
+ {
+ "WINWORD.EXE" => "Word",
+ "EXCEL.EXE" => "Excel",
+ "POWERPNT.EXE" => "PowerPoint",
+ "OUTLOOK.EXE" => "Outlook",
+ "ONENOTE.EXE" => "OneNote",
+ _ => ""
+ };
+
+ foreach (string strRootKey in OfficeRootKeys)
+ {
+ using RegistryKey rootKey = Registry.LocalMachine.OpenSubKey(strRootKey);
+ if (rootKey is null) continue;
+
+ foreach (string officeVersion in rootKey.GetSubKeyNames().Where(r => r.Contains(".")).Reverse())
+ {
+ using RegistryKey installRootKey = Registry.LocalMachine.OpenSubKey($@"{strRootKey}\{officeVersion}\{strKeyName}\InstallRoot");
+ if (installRootKey == null) continue;
+ return $@"{installRootKey.GetValue("Path")}\{exeName}";
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/Greenshot/App.config b/src/Greenshot/App.config
index 80b985a5c..ab8a7c40c 100644
--- a/src/Greenshot/App.config
+++ b/src/Greenshot/App.config
@@ -11,8 +11,7 @@
-
-
+
\ No newline at end of file
diff --git a/src/Greenshot/Forms/CaptureForm.cs b/src/Greenshot/Forms/CaptureForm.cs
index 68e57f040..107aa9096 100644
--- a/src/Greenshot/Forms/CaptureForm.cs
+++ b/src/Greenshot/Forms/CaptureForm.cs
@@ -197,7 +197,7 @@ namespace Greenshot.Forms
private void CaptureForm_Resize(object sender, EventArgs e)
{
Log.DebugFormat("Resize was called, new size: {0}", this.Bounds);
- if (Bounds.Equals(_capture.ScreenBounds))
+ if (_capture.ScreenBounds.Equals(Bounds))
{
// We have the correct size
return;
@@ -425,9 +425,11 @@ namespace Greenshot.Forms
else if (_captureRect.Height > 0 && _captureRect.Width > 0)
{
// correct the GUI width to real width if Region mode
- if (_captureMode == CaptureMode.Region || _captureMode == CaptureMode.Text)
+ if (_captureMode is CaptureMode.Region or CaptureMode.Text)
{
- _captureRect = _captureRect.Inflate(1, 1);
+ // Correct the rectangle size, by making it 1 pixel bigger
+ // We cannot use inflate, this would make the rect bigger to all sizes.
+ _captureRect = new NativeRect(_captureRect.Left, _captureRect.Top, _captureRect.Width+1, _captureRect.Height+1);
}
// Go and process the capture
diff --git a/src/Greenshot/Greenshot.csproj b/src/Greenshot/Greenshot.csproj
index 78fa3f6c6..fc4dd90d1 100644
--- a/src/Greenshot/Greenshot.csproj
+++ b/src/Greenshot/Greenshot.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/src/Greenshot/Helpers/CaptureHelper.cs b/src/Greenshot/Helpers/CaptureHelper.cs
index c002c62ef..e51b51ebe 100644
--- a/src/Greenshot/Helpers/CaptureHelper.cs
+++ b/src/Greenshot/Helpers/CaptureHelper.cs
@@ -564,14 +564,6 @@ namespace Greenshot.Helpers
{
_windows = new List();
- // If the App Launcher is visible, no other windows are active
- WindowDetails appLauncherWindow = WindowDetails.GetAppLauncher();
- if (appLauncherWindow != null && appLauncherWindow.Visible)
- {
- _windows.Add(appLauncherWindow);
- return null;
- }
-
Thread getWindowDetailsThread = new Thread(RetrieveWindowDetails)
{
Name = "Retrieve window details",
@@ -984,7 +976,7 @@ namespace Greenshot.Helpers
else
{
// Change to GDI, if allowed
- if (!windowToCapture.IsMetroApp && WindowCapture.IsGdiAllowed(process))
+ if (WindowCapture.IsGdiAllowed(process))
{
if (!dwmEnabled && IsWpf(process))
{
@@ -1000,7 +992,7 @@ namespace Greenshot.Helpers
// Change to DWM, if enabled and allowed
if (dwmEnabled)
{
- if (windowToCapture.IsMetroApp || WindowCapture.IsDwmAllowed(process))
+ if (WindowCapture.IsDwmAllowed(process))
{
windowCaptureMode = WindowCaptureMode.Aero;
}
@@ -1009,7 +1001,7 @@ namespace Greenshot.Helpers
}
else if (windowCaptureMode == WindowCaptureMode.Aero || windowCaptureMode == WindowCaptureMode.AeroTransparent)
{
- if (!dwmEnabled || (!windowToCapture.IsMetroApp && !WindowCapture.IsDwmAllowed(process)))
+ if (!dwmEnabled || !WindowCapture.IsDwmAllowed(process))
{
// Take default screen
windowCaptureMode = WindowCaptureMode.Screen;
@@ -1115,7 +1107,7 @@ namespace Greenshot.Helpers
break;
case WindowCaptureMode.Aero:
case WindowCaptureMode.AeroTransparent:
- if (windowToCapture.IsMetroApp || WindowCapture.IsDwmAllowed(process))
+ if (WindowCapture.IsDwmAllowed(process))
{
tmpCapture = windowToCapture.CaptureDwmWindow(captureForWindow, windowCaptureMode, isAutoMode);
}