Merge remote-tracking branch 'remotes/origin/release/1.3' into new-emoji-object-in-editor

This commit is contained in:
Robin Krom 2022-10-09 21:05:38 +02:00
commit c2a5d1c961
No known key found for this signature in database
GPG key ID: BCC01364F1371490
35 changed files with 455 additions and 437 deletions

View file

@ -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

View file

@ -1,13 +1,13 @@
<Project>
<PropertyGroup>
<Copyright>Copyright © Greenshot 2004-2021</Copyright>
<Copyright>Copyright © Greenshot 2004-2022</Copyright>
<Authors>Greenshot</Authors>
<PackageIconUrl>https://getgreenshot.org/favicon.ico</PackageIconUrl>
<RepositoryUrl>https://github.com/greenshot/greenshot</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageProjectUrl>https://github.com/greenshot/greenshot</PackageProjectUrl>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
<LangVersion>9</LangVersion>
<LangVersion>latest</LangVersion>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
<RuntimeIdentifiers>win10-x64;win10-x86;win-x64;win-x86</RuntimeIdentifiers>
@ -46,7 +46,7 @@
</PropertyGroup>
<ItemGroup Condition="!$(MSBuildProjectName.Contains('Tests')) And $(MSBuildProjectName.StartsWith('Greenshot'))">
<PackageReference Include="Nerdbank.GitVersioning" Version="3.4.255">
<PackageReference Include="Nerdbank.GitVersioning" Version="3.5.113">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>

View file

@ -386,6 +386,7 @@ EndSelection:<<<<<<<4
/// <returns>IEnumerable{(MemoryStream,string)}</returns>
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;
}

View file

@ -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);
}
/// <summary>
/// Supply values we can't put as defaults
/// </summary>
/// <param name="property">The property to return a default for</param>
/// <returns>object with the default value for the supplied property</returns>
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<string>();
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<string>
{
"Firefox",
"IE",
"Chrome"
};
case nameof(TitleFixMatcher):
return new Dictionary<string, string>
{
{
"Firefox", " - Mozilla Firefox.*"
},
{
"IE", " - (Microsoft|Windows) Internet Explorer.*"
},
{
"Chrome", " - Google Chrome.*"
}
};
case nameof(TitleFixReplacer):
return new Dictionary<string, string>
{
{
"Firefox", string.Empty
},
{
"IE", string.Empty
},
{
"Chrome", string.Empty
}
};
}
return null;
}
nameof(ExcludePlugins) => new List<string>(),
nameof(IncludePlugins) => new List<string>(),
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<string> {
"Firefox",
"IE",
"Chrome"
},
nameof(TitleFixMatcher) => new Dictionary<string, string> {
{ "Firefox", " - Mozilla Firefox.*" },
{ "IE", " - (Microsoft|Windows) Internet Explorer.*" },
{ "Chrome", " - Google Chrome.*" }
},
nameof(TitleFixReplacer) => new Dictionary<string, string> {
{ "Firefox", string.Empty },
{ "IE", string.Empty },
{ "Chrome", string.Empty }
},
_ => null
};
/// <summary>
/// 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;
}

View file

@ -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<CoreConfiguration>();
private const string PathKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\";
private static readonly IDictionary<string, Image> ExeIconCache = new Dictionary<string, Image>();
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);
}
}

View file

@ -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<string> IgnoreClasses = new List<string>(new[]
{
@ -89,13 +87,7 @@ namespace Greenshot.Base.Core
private IntPtr _parentHandle = IntPtr.Zero;
private WindowDetails _parent;
private bool _frozen;
/// <summary>
/// This checks if the window is a Windows 8 App
/// For Windows 10 most normal code works, as it's hosted inside "ApplicationFrameWindow"
/// </summary>
public bool IsApp => AppWindowClass.Equals(ClassName);
/// <summary>
/// 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));
/// <summary>
/// Check if the window is the metro gutter (sizeable separator)
/// </summary>
public bool IsGutter => GutterClass.Equals(ClassName);
/// <summary>
/// Test if this window is for the App-Launcher
/// </summary>
public bool IsAppLauncher => ApplauncherClass.Equals(ClassName);
/// <summary>
/// Check if this window is the window of a metro app
/// </summary>
public bool IsMetroApp => IsAppLauncher || IsApp;
/// <summary>
/// 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();
}
/// <summary>
/// If a window is hidden (Iconic), it also has the specified dimensions.
/// </summary>
/// <param name="rect">NativeRect</param>
/// <returns>bool true if hidden</returns>
private bool IsHidden(NativeRect rect) => rect.Width == 65535 && rect.Height == 65535 && rect.Left == 32767 && rect.Top == 32767;
/// <summary>
/// Helper method to get the window size for DWM Windows
/// </summary>
@ -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<WindowDetails> 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
}
}
/// <summary>
/// Get the WindowDetails for all Metro Apps
/// These are all Windows with Classname "Windows.UI.Core.CoreWindow"
/// </summary>
/// <returns>List WindowDetails with visible metro apps</returns>
public static IEnumerable<WindowDetails> 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);
}
}
/// <summary>
/// Check if the window is a top level
/// </summary>
@ -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
/// <returns>List WindowDetails with all the top level windows</returns>
public static IEnumerable<WindowDetails> 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
}
}
/// <summary>
/// Get the AppLauncher
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// Return true if the metro-app-launcher is visible
/// </summary>
@ -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}");

View file

@ -5,16 +5,16 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapplo.HttpExtensions.JsonNet" Version="1.0.18" />
<PackageReference Include="Dapplo.Windows.Clipboard" Version="1.0.25" />
<PackageReference Include="Dapplo.Windows.Dpi" Version="1.0.25" />
<PackageReference Include="Dapplo.Windows.Gdi32" Version="1.0.25" />
<PackageReference Include="Dapplo.Windows.Icons" Version="1.0.25" />
<PackageReference Include="Dapplo.Windows.Kernel32" Version="1.0.25" />
<PackageReference Include="Dapplo.Windows.Multimedia" Version="1.0.25" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.42" />
<PackageReference Include="log4net" version="2.0.14" />
<PackageReference Include="Svg" Version="3.4.2" />
<PackageReference Include="Dapplo.HttpExtensions.JsonNet" Version="1.1.2" />
<PackageReference Include="Dapplo.Windows.Clipboard" Version="1.0.28" />
<PackageReference Include="Dapplo.Windows.Dpi" Version="1.0.28" />
<PackageReference Include="Dapplo.Windows.Gdi32" Version="1.0.28" />
<PackageReference Include="Dapplo.Windows.Icons" Version="1.0.28" />
<PackageReference Include="Dapplo.Windows.Kernel32" Version="1.0.28" />
<PackageReference Include="Dapplo.Windows.Multimedia" Version="1.0.28" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.46" />
<PackageReference Include="log4net" version="2.0.15" />
<PackageReference Include="Svg" Version="3.4.3" />
<Reference Include="Accessibility" />
<Reference Include="CustomMarshalers" />
</ItemGroup>

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -166,9 +166,9 @@ namespace Greenshot.Editor.Drawing
return image;
}
public ScaleHelper.ScaleOptions GetScaleOptions()
public ScaleOptions GetScaleOptions()
{
return ScaleHelper.ScaleOptions.Rational;
return ScaleOptions.Rational;
}
}
}

View file

@ -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;
}
}
}

View file

@ -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)

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
namespace Greenshot.Editor.Helpers
{
public interface IDoubleProcessor
{
double Process(double d);
}
}

View file

@ -23,6 +23,6 @@ namespace Greenshot.Editor.Helpers
{
public interface IHaveScaleOptions
{
ScaleHelper.ScaleOptions GetScaleOptions();
ScaleOptions GetScaleOptions();
}
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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;
}
}
}

View file

@ -33,26 +33,7 @@ namespace Greenshot.Editor.Helpers
/// </summary>
public static class ScaleHelper
{
[Flags]
public enum ScaleOptions
{
/// <summary>
/// Default scale behavior.
/// </summary>
Default = 0x00,
/// <summary>
/// Scale a rectangle in two our four directions, mirrored at it's center coordinates
/// </summary>
Centered = 0x01,
/// <summary>
/// Scale a rectangle maintaining it's aspect ratio
/// </summary>
Rational = 0x02
}
/// <summary>
/// calculates the Size an element must be resized to, in order to fit another element, keeping aspect ratio
/// </summary>
/// <param name="currentSize">the size of the element to be resized</param>
@ -231,16 +212,14 @@ namespace Greenshot.Editor.Helpers
/// Scale the boundsBeforeResize with the specified position and new location, using the angle angleRoundBehavior
/// </summary>
/// <param name="boundsBeforeResize">NativeRect</param>
/// <param name="gripperPosition">Positions</param>
/// <param name="cursorX">int</param>
/// <param name="cursorY">int</param>
/// <param name="angleRoundBehavior">IDoubleProcessor</param>
/// <param name="options">ScaleOptionsProcessor</param>
/// <param name="options">ScaleOptionsProcessor</param>
/// <returns>NativeRectFloat</returns>
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;
}
}
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
using System;
namespace Greenshot.Editor.Helpers
{
[Flags]
public enum ScaleOptions
{
/// <summary>
/// Default scale behavior.
/// </summary>
Default = 0x00,
/// <summary>
/// Scale a rectangle in two our four directions, mirrored at it's center coordinates
/// </summary>
Centered = 0x01,
/// <summary>
/// Scale a rectangle maintaining it's aspect ratio
/// </summary>
Rational = 0x02
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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;
}
}
}

View file

@ -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;
}
/// <summary>
/// Upgrade certain values
/// </summary>
public override void AfterLoad()
{
var coreConfiguration = IniConfig.GetIniSection<CoreConfiguration>();
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;
}
}
}

View file

@ -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;
}
/// <summary>
/// Upgrade certain values
/// </summary>
public override void AfterLoad()
{
var coreConfiguration = IniConfig.GetIniSection<CoreConfiguration>();
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;
}
}
}

View file

@ -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;
}
/// <summary>
/// Upgrade certain values
/// </summary>
public override void AfterLoad()
{
var coreConfiguration = IniConfig.GetIniSection<CoreConfiguration>();
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;
}
}
}

View file

@ -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<string, ImgurInfo> runtimeImgurHistory = new Dictionary<string, ImgurInfo>();
public int Credits { get; set; }
/// <summary>
/// Upgrade certain values
/// </summary>
public override void AfterLoad()
{
var coreConfiguration = IniConfig.GetIniSection<CoreConfiguration>();
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;
}
/// <summary>
/// Supply values we can't put as defaults
/// </summary>
@ -92,7 +109,7 @@ namespace Greenshot.Plugin.Imgur
public override object GetDefault(string property) =>
property switch
{
"ImgurUploadHistory" => new Dictionary<string, string>(),
nameof(ImgurUploadHistory) => new Dictionary<string, string>(),
_ => null
};

View file

@ -6,7 +6,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Greenshot.Base\Greenshot.Base.csproj" />
<PackageReference Include="Dapplo.Jira" version="1.1.44" />
<PackageReference Include="Dapplo.Jira.SvgWinForms" Version="1.1.44" />
<PackageReference Include="Dapplo.Jira" version="1.1.46" />
<PackageReference Include="Dapplo.Jira.SvgWinForms" Version="1.1.46" />
</ItemGroup>
</Project>

View file

@ -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");

View file

@ -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");

View file

@ -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");

View file

@ -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");

View file

@ -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<IDestination>
{

View file

@ -78,23 +78,23 @@
</ItemGroup>
</Target>
<ItemGroup>
<PackageReference Include="Interop.Microsoft.Office.Interop.OneNote" Version="1.1.0">
<PackageReference Include="Interop.Microsoft.Office.Interop.OneNote" Version="1.1.0.2">
<EmbedInteropTypes>true</EmbedInteropTypes>
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Office.Interop.Excel" Version="15.0.4795.1000">
<PackageReference Include="Microsoft.Office.Interop.Excel" Version="15.0.4795.1001">
<EmbedInteropTypes>true</EmbedInteropTypes>
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Office.Interop.Outlook" Version="15.0.4797.1003">
<PackageReference Include="Microsoft.Office.Interop.Outlook" Version="15.0.4797.1004">
<EmbedInteropTypes>true</EmbedInteropTypes>
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Office.Interop.PowerPoint" Version="15.0.4420.1017">
<PackageReference Include="Microsoft.Office.Interop.PowerPoint" Version="15.0.4420.1018">
<EmbedInteropTypes>true</EmbedInteropTypes>
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Office.Interop.Word" Version="15.0.4797.1003">
<PackageReference Include="Microsoft.Office.Interop.Word" Version="15.0.4797.1004">
<EmbedInteropTypes>true</EmbedInteropTypes>
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>

View file

@ -0,0 +1,43 @@
using System.Linq;
using Microsoft.Win32;
namespace Greenshot.Plugin.Office;
/// <summary>
/// A small utility class for helping with office
/// </summary>
internal static class OfficeUtils
{
private static readonly string[] OfficeRootKeys = { @"SOFTWARE\Microsoft\Office", @"SOFTWARE\WOW6432Node\Microsoft\Office" };
/// <summary>
/// Get the path to the office exe
/// </summary>
/// <param name="exeName">Name of the office executable</param>
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;
}
}

View file

@ -11,8 +11,7 @@
<loadFromRemoteSources enabled="true" />
<relativeBindForResources enabled="true" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="Addons" />
<probing privatePath="App\Greenshot" />
<probing privatePath="Addons,App\Greenshot" />
</assemblyBinding>
</runtime>
</configuration>

View file

@ -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

View file

@ -17,7 +17,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Tools.InnoSetup" version="6.2.0" GeneratePathProperty="true" />
<PackageReference Include="Tools.InnoSetup" version="6.2.1" GeneratePathProperty="true" />
</ItemGroup>
<ItemGroup>

View file

@ -564,14 +564,6 @@ namespace Greenshot.Helpers
{
_windows = new List<WindowDetails>();
// 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);
}