mirror of
https://github.com/greenshot/greenshot
synced 2025-07-12 16:13:53 -07:00
This should fix most icon scaling issues
Improved the IniReader a bit and replaced some old code.
This commit is contained in:
parent
41baf27d84
commit
4a958be8b5
35 changed files with 2767 additions and 301 deletions
|
@ -16,7 +16,7 @@
|
|||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<!-- Optional: Embed source files that are not tracked by the source control manager in the PDB -->
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<TargetFramework>net471</TargetFramework>
|
||||
<TargetFramework>net471</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- ILLinker and single file settings -->
|
||||
|
@ -25,8 +25,8 @@
|
|||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="$(MSBuildProjectName) == 'Greenshot'">
|
||||
<IncludeSymbolsInSingleFile>false</IncludeSymbolsInSingleFile>
|
||||
<ShowLinkerSizeComparison>true</ShowLinkerSizeComparison>
|
||||
<IncludeSymbolsInSingleFile>false</IncludeSymbolsInSingleFile>
|
||||
<ShowLinkerSizeComparison>true</ShowLinkerSizeComparison>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' != 'Debug' And !$(MSBuildProjectName.Contains('Test')) And !$(MSBuildProjectName.Contains('Demo'))">
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
*
|
||||
* For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -33,9 +33,9 @@ namespace Greenshot.Controls {
|
|||
private static Image _scaledCheckbox;
|
||||
|
||||
protected override void OnRenderItemCheck(ToolStripItemImageRenderEventArgs e) {
|
||||
if (_scaledCheckbox == null || _scaledCheckbox.Size != CoreConfig.IconSize) {
|
||||
if (_scaledCheckbox == null || _scaledCheckbox.Size != CoreConfig.ScaledIconSize) {
|
||||
_scaledCheckbox?.Dispose();
|
||||
_scaledCheckbox = ImageHelper.ResizeImage(e.Image, true, CoreConfig.IconSize.Width, CoreConfig.IconSize.Height, null);
|
||||
_scaledCheckbox = ImageHelper.ResizeImage(e.Image, true, CoreConfig.ScaledIconSize.Width, CoreConfig.ScaledIconSize.Height, null);
|
||||
}
|
||||
Rectangle old = e.ImageRectangle;
|
||||
ToolStripItemImageRenderEventArgs clone = new ToolStripItemImageRenderEventArgs(e.Graphics, e.Item, _scaledCheckbox, new Rectangle(old.X, 0, old.Width, old.Height));
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
*
|
||||
* For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -32,10 +32,10 @@ namespace Greenshot.Drawing {
|
|||
/// <summary>
|
||||
/// Description of LineContainer.
|
||||
/// </summary>
|
||||
[Serializable()]
|
||||
[Serializable()]
|
||||
public class LineContainer : DrawableContainer {
|
||||
public static readonly int MAX_CLICK_DISTANCE_TOLERANCE = 10;
|
||||
|
||||
|
||||
public LineContainer(Surface parent) : base(parent) {
|
||||
Init();
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ namespace Greenshot.Drawing {
|
|||
AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
|
||||
AddField(GetType(), FieldType.SHADOW, true);
|
||||
}
|
||||
|
||||
|
||||
protected override void OnDeserialized(StreamingContext context)
|
||||
{
|
||||
Init();
|
||||
|
@ -55,7 +55,7 @@ namespace Greenshot.Drawing {
|
|||
Adorners.Add(new MoveAdorner(this, Positions.TopLeft));
|
||||
Adorners.Add(new MoveAdorner(this, Positions.BottomRight));
|
||||
}
|
||||
|
||||
|
||||
public override void Draw(Graphics graphics, RenderMode rm) {
|
||||
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||
graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
|
||||
|
@ -91,7 +91,7 @@ namespace Greenshot.Drawing {
|
|||
graphics.DrawLine(pen, Left, Top, Left + Width, Top + Height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override bool ClickableAt(int x, int y) {
|
||||
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS) +5;
|
||||
if (lineThickness > 0)
|
||||
|
@ -102,13 +102,13 @@ namespace Greenshot.Drawing {
|
|||
};
|
||||
using GraphicsPath path = new GraphicsPath();
|
||||
path.AddLine(Left, Top, Left + Width, Top + Height);
|
||||
return path.IsOutlineVisible(x, y, pen);
|
||||
return path.IsOutlineVisible(x, y, pen);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected override ScaleHelper.IDoubleProcessor GetAngleRoundProcessor() {
|
||||
return ScaleHelper.LineAngleRoundBehavior.Instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
Greenshot/Forms/ImageEditorForm.Designer.cs
generated
10
Greenshot/Forms/ImageEditorForm.Designer.cs
generated
|
@ -293,7 +293,7 @@ namespace Greenshot {
|
|||
// toolsToolStrip
|
||||
//
|
||||
this.toolsToolStrip.ClickThrough = true;
|
||||
this.toolsToolStrip.ImageScalingSize = coreConfiguration.IconSize;
|
||||
this.toolsToolStrip.ImageScalingSize = coreConfiguration.ScaledIconSize;
|
||||
this.toolsToolStrip.Dock = System.Windows.Forms.DockStyle.None;
|
||||
this.toolsToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
|
||||
this.toolsToolStrip.Renderer = new CustomToolStripProfessionalRenderer();
|
||||
|
@ -529,7 +529,7 @@ namespace Greenshot {
|
|||
// menuStrip1
|
||||
//
|
||||
this.menuStrip1.ClickThrough = true;
|
||||
this.menuStrip1.ImageScalingSize = coreConfiguration.IconSize;
|
||||
this.menuStrip1.ImageScalingSize = coreConfiguration.ScaledIconSize;
|
||||
this.menuStrip1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.menuStrip1.Stretch = true;
|
||||
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
|
@ -858,7 +858,7 @@ namespace Greenshot {
|
|||
// destinationsToolStrip
|
||||
//
|
||||
this.destinationsToolStrip.ClickThrough = true;
|
||||
this.destinationsToolStrip.ImageScalingSize = coreConfiguration.IconSize;
|
||||
this.destinationsToolStrip.ImageScalingSize = coreConfiguration.ScaledIconSize;
|
||||
this.destinationsToolStrip.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.destinationsToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
|
||||
this.destinationsToolStrip.Name = "toolStrip1";
|
||||
|
@ -1014,10 +1014,10 @@ namespace Greenshot {
|
|||
//
|
||||
this.propertiesToolStrip.AutoSize = false;
|
||||
this.propertiesToolStrip.ClickThrough = true;
|
||||
this.propertiesToolStrip.ImageScalingSize = coreConfiguration.IconSize;
|
||||
this.propertiesToolStrip.ImageScalingSize = coreConfiguration.ScaledIconSize;
|
||||
this.propertiesToolStrip.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.propertiesToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
|
||||
this.propertiesToolStrip.MinimumSize = new System.Drawing.Size(150, coreConfiguration.IconSize.Height + 10);
|
||||
this.propertiesToolStrip.MinimumSize = new System.Drawing.Size(150, coreConfiguration.ScaledIconSize.Height + 10);
|
||||
this.propertiesToolStrip.Name = "propertiesToolStrip";
|
||||
this.propertiesToolStrip.Stretch = true;
|
||||
this.propertiesToolStrip.TabIndex = 2;
|
||||
|
|
2
Greenshot/Forms/MainForm.Designer.cs
generated
2
Greenshot/Forms/MainForm.Designer.cs
generated
|
@ -203,7 +203,7 @@ namespace Greenshot {
|
|||
// contextmenu_quicksettings
|
||||
//
|
||||
this.contextmenu_quicksettings.Name = "contextmenu_quicksettings";
|
||||
this.contextmenu_quicksettings.Size = new System.Drawing.Size(170, coreConfiguration.IconSize.Height + 8);
|
||||
this.contextmenu_quicksettings.Size = new System.Drawing.Size(170, coreConfiguration.ScaledIconSize.Height + 8);
|
||||
//
|
||||
// contextmenu_settings
|
||||
//
|
||||
|
|
|
@ -549,7 +549,7 @@ namespace Greenshot {
|
|||
/// <param name="e"></param>
|
||||
private void OnIconSizeChanged(object sender, PropertyChangedEventArgs e) {
|
||||
if (e.PropertyName == "IconSize") {
|
||||
contextMenu.ImageScalingSize = coreConfiguration.IconSize;
|
||||
contextMenu.ImageScalingSize = coreConfiguration.ScaledIconSize;
|
||||
string ieExePath = PluginUtils.GetExePath("iexplore.exe");
|
||||
if (!string.IsNullOrEmpty(ieExePath)) {
|
||||
contextmenu_captureie.Image = PluginUtils.GetCachedExeIcon(ieExePath, 0);
|
||||
|
@ -614,7 +614,7 @@ namespace Greenshot {
|
|||
/// <returns>true if onedrive has hotkeys turned on</returns>
|
||||
private static bool IsOneDriveBlockingHotkey()
|
||||
{
|
||||
if (!Environment.OSVersion.IsWindows10())
|
||||
if (!WindowsVersion.IsWindows10OrLater)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
*
|
||||
* For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -50,7 +50,7 @@ namespace Greenshot {
|
|||
|
||||
public SettingsForm() {
|
||||
InitializeComponent();
|
||||
|
||||
|
||||
// Make sure the store isn't called to early, that's why we do it manually
|
||||
ManualStoreFields = true;
|
||||
}
|
||||
|
@ -154,8 +154,8 @@ namespace Greenshot {
|
|||
}
|
||||
comboBox.SelectedItem = Language.Translate(selectedValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the selected enum value from the combobox, uses generics
|
||||
/// </summary>
|
||||
|
@ -175,7 +175,7 @@ namespace Greenshot {
|
|||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
private void SetWindowCaptureMode(WindowCaptureMode selectedWindowCaptureMode) {
|
||||
WindowCaptureMode[] availableModes;
|
||||
if (!DWM.IsDwmEnabled()) {
|
||||
|
@ -189,7 +189,7 @@ namespace Greenshot {
|
|||
}
|
||||
PopulateComboBox(combobox_window_capture_mode, availableModes, selectedWindowCaptureMode);
|
||||
}
|
||||
|
||||
|
||||
private void DisplayPluginTab() {
|
||||
if (!PluginHelper.Instance.HasPlugins()) {
|
||||
tabcontrol.TabPages.Remove(tab_plugins);
|
||||
|
@ -199,9 +199,9 @@ namespace Greenshot {
|
|||
listview_plugins.Items.Clear();
|
||||
listview_plugins.Columns.Clear();
|
||||
string[] columns = {
|
||||
Language.GetString("settings_plugins_name"),
|
||||
Language.GetString("settings_plugins_version"),
|
||||
Language.GetString("settings_plugins_createdby"),
|
||||
Language.GetString("settings_plugins_name"),
|
||||
Language.GetString("settings_plugins_version"),
|
||||
Language.GetString("settings_plugins_createdby"),
|
||||
Language.GetString("settings_plugins_dllpath")};
|
||||
foreach (string column in columns) {
|
||||
listview_plugins.Columns.Add(column);
|
||||
|
@ -218,7 +218,7 @@ namespace Greenshot {
|
|||
}
|
||||
listview_plugins.EndUpdate();
|
||||
listview_plugins.Refresh();
|
||||
|
||||
|
||||
// Disable the configure button, it will be enabled when a plugin is selected AND isConfigurable
|
||||
button_pluginconfigure.Enabled = false;
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ namespace Greenshot {
|
|||
UpdateDestinationDescriptions();
|
||||
UpdateClipboardFormatDescriptions();
|
||||
}
|
||||
|
||||
|
||||
// Check the settings and somehow visibly mark when something is incorrect
|
||||
private bool CheckSettings() {
|
||||
return CheckFilenamePattern() && CheckStorageLocationPath();
|
||||
|
@ -273,21 +273,21 @@ namespace Greenshot {
|
|||
}
|
||||
|
||||
DisplayTextBoxValidity(textbox_screenshotname, settingsOk);
|
||||
|
||||
|
||||
return settingsOk;
|
||||
}
|
||||
|
||||
private bool CheckStorageLocationPath() {
|
||||
bool settingsOk = Directory.Exists(FilenameHelper.FillVariables(textbox_storagelocation.Text, false));
|
||||
bool settingsOk = Directory.Exists(FilenameHelper.FillVariables(textbox_storagelocation.Text, false));
|
||||
DisplayTextBoxValidity(textbox_storagelocation, settingsOk);
|
||||
return settingsOk;
|
||||
}
|
||||
|
||||
private void DisplayTextBoxValidity(GreenshotTextBox textbox, bool valid) {
|
||||
if (valid) {
|
||||
if (valid) {
|
||||
// "Added" feature #3547158
|
||||
textbox.BackColor = Environment.OSVersion.Version.Major >= 6 ? SystemColors.Window : SystemColors.Control;
|
||||
} else {
|
||||
} else {
|
||||
textbox.BackColor = Color.Red;
|
||||
}
|
||||
}
|
||||
|
@ -334,6 +334,7 @@ namespace Greenshot {
|
|||
listview_destinations.Items.Clear();
|
||||
listview_destinations.ListViewItemSorter = new ListviewWithDestinationComparer();
|
||||
ImageList imageList = new ImageList();
|
||||
imageList.ImageSize = coreConfiguration.ScaledIconSize;
|
||||
listview_destinations.SmallImageList = imageList;
|
||||
int imageNr = -1;
|
||||
foreach (IDestination currentDestination in DestinationHelper.GetAllDestinations()) {
|
||||
|
@ -376,7 +377,7 @@ namespace Greenshot {
|
|||
item.Tag = clipboardFormat;
|
||||
item.Checked = coreConfiguration.ClipboardFormats.Contains(clipboardFormat);
|
||||
}
|
||||
|
||||
|
||||
if (Language.CurrentLanguage != null) {
|
||||
combobox_language.SelectedValue = Language.CurrentLanguage;
|
||||
}
|
||||
|
@ -419,10 +420,10 @@ namespace Greenshot {
|
|||
checkbox_autostartshortcut.Checked = StartupHelper.HasRunUser();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
numericUpDown_daysbetweencheck.Value = coreConfiguration.UpdateCheckInterval;
|
||||
numericUpDown_daysbetweencheck.Enabled = !coreConfiguration.Values["UpdateCheckInterval"].IsFixed;
|
||||
numericUpdownIconSize.Value = coreConfiguration.IconSize.Width /16 * 16;
|
||||
numericUpdownIconSize.Value = coreConfiguration.ScaledIconSize.Width /16 * 16;
|
||||
CheckDestinationSettings();
|
||||
}
|
||||
|
||||
|
@ -570,7 +571,7 @@ namespace Greenshot {
|
|||
}
|
||||
colorButton_window_background.Visible = false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check the destination settings
|
||||
/// </summary>
|
||||
|
@ -582,7 +583,7 @@ namespace Greenshot {
|
|||
destinationsEnabled = !coreConfiguration.Values["Destinations"].IsFixed;
|
||||
}
|
||||
listview_destinations.Enabled = destinationsEnabled;
|
||||
|
||||
|
||||
foreach(int index in listview_destinations.CheckedIndices) {
|
||||
ListViewItem item = listview_destinations.Items[index];
|
||||
if (item.Tag is IDestination destinationFromTag && destinationFromTag.Designation.Equals(ClipboardDestination.DESIGNATION)) {
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
*
|
||||
* For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -50,9 +50,9 @@ namespace Greenshot.Forms {
|
|||
Identifier = identifier;
|
||||
CheckOnClick = false;
|
||||
_multiCheckAllowed = allowMultiCheck;
|
||||
if (_defaultImage == null || _defaultImage.Size != CoreConfig.IconSize) {
|
||||
if (_defaultImage == null || _defaultImage.Size != CoreConfig.ScaledIconSize) {
|
||||
_defaultImage?.Dispose();
|
||||
_defaultImage = ImageHelper.CreateEmpty(CoreConfig.IconSize.Width, CoreConfig.IconSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb, Color.Transparent, 96f, 96f);
|
||||
_defaultImage = ImageHelper.CreateEmpty(CoreConfig.ScaledIconSize.Width, CoreConfig.ScaledIconSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb, Color.Transparent, 96f, 96f);
|
||||
}
|
||||
Image = _defaultImage;
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ namespace Greenshot.Forms {
|
|||
/// gets or sets the currently checked item
|
||||
/// </summary>
|
||||
public ToolStripMenuSelectListItem CheckedItem {
|
||||
|
||||
|
||||
get {
|
||||
IEnumerator items = DropDownItems.GetEnumerator();
|
||||
while (items.MoveNext()) {
|
||||
|
@ -86,7 +86,7 @@ namespace Greenshot.Forms {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// gets or sets the currently checked items
|
||||
/// </summary>
|
||||
|
@ -126,7 +126,7 @@ namespace Greenshot.Forms {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ItemCheckStateChanged(object sender, EventArgs e) {
|
||||
if (_updateInProgress) {
|
||||
return;
|
||||
|
@ -140,7 +140,7 @@ namespace Greenshot.Forms {
|
|||
_updateInProgress = false;
|
||||
CheckedChanged?.Invoke(this, new ItemCheckedChangedEventArgs(toolStripMenuSelectListItem));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// adds an item to the select list
|
||||
/// </summary>
|
||||
|
@ -171,7 +171,7 @@ namespace Greenshot.Forms {
|
|||
}
|
||||
DropDownItems.Add(toolStripMenuSelectListItem);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// adds an item to the select list
|
||||
/// </summary>
|
||||
|
@ -180,7 +180,7 @@ namespace Greenshot.Forms {
|
|||
public void AddItem(string label, Image image) {
|
||||
AddItem(label, image, null, false);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// adds an item to the select list
|
||||
/// </summary>
|
||||
|
@ -189,7 +189,7 @@ namespace Greenshot.Forms {
|
|||
public void AddItem(string label, object data) {
|
||||
AddItem(label, null, data, false);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// adds an item to the select list
|
||||
/// </summary>
|
||||
|
@ -197,8 +197,8 @@ namespace Greenshot.Forms {
|
|||
public void AddItem(string label) {
|
||||
AddItem(label, null, null, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// adds an item to the select list
|
||||
/// </summary>
|
||||
|
@ -208,7 +208,7 @@ namespace Greenshot.Forms {
|
|||
public void AddItem(string label, Image image, bool isChecked) {
|
||||
AddItem(label, image, null, isChecked);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// adds an item to the select list
|
||||
/// </summary>
|
||||
|
@ -218,7 +218,7 @@ namespace Greenshot.Forms {
|
|||
public void AddItem(string label, object data, bool isChecked) {
|
||||
AddItem(label, null, data, isChecked);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// adds an item to the select list
|
||||
/// </summary>
|
||||
|
@ -227,7 +227,7 @@ namespace Greenshot.Forms {
|
|||
public void AddItem(string label, bool isChecked) {
|
||||
AddItem(label, null, null, isChecked);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// unchecks all items of the list
|
||||
/// </summary>
|
||||
|
@ -243,7 +243,7 @@ namespace Greenshot.Forms {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Event class for the CheckedChanged event in the ToolStripMenuSelectList
|
||||
/// </summary>
|
||||
|
@ -256,7 +256,7 @@ namespace Greenshot.Forms {
|
|||
Item = item;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper around the ToolStripMenuItem, which can contain an object
|
||||
/// Also the Checked property hides the normal checked property so we can render our own check
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
*
|
||||
* For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -115,7 +115,7 @@ namespace GreenshotJiraPlugin.Forms {
|
|||
public async Task UploadAsync(IBinaryContainer attachment) {
|
||||
attachment.Filename = jiraFilenameBox.Text;
|
||||
await _jiraConnector.AttachAsync(_selectedIssue.Key, attachment);
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(jiraCommentBox.Text)) {
|
||||
await _jiraConnector.AddCommentAsync(_selectedIssue.Key, jiraCommentBox.Text);
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ namespace GreenshotJiraPlugin.Forms {
|
|||
jiraListView.Columns.Add(translation);
|
||||
}
|
||||
var imageList = new ImageList {
|
||||
ImageSize = CoreConfig.IconSize
|
||||
ImageSize = CoreConfig.ScaledIconSize
|
||||
};
|
||||
jiraListView.SmallImageList = imageList;
|
||||
jiraListView.LargeImageList = imageList;
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
*
|
||||
* For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -56,7 +56,7 @@ namespace GreenshotJiraPlugin {
|
|||
{
|
||||
if (args.PropertyName == nameof(CoreConfig.IconSize))
|
||||
{
|
||||
JiraPlugin.Instance.JiraConnector._jiraClient?.Behaviour.SetConfig(new SvgConfiguration { Width = CoreConfig.IconSize.Width, Height = CoreConfig.IconSize.Height });
|
||||
JiraPlugin.Instance.JiraConnector._jiraClient?.Behaviour.SetConfig(new SvgConfiguration { Width = CoreConfig.ScaledIconSize.Width, Height = CoreConfig.ScaledIconSize.Height });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -99,7 +99,7 @@ namespace GreenshotJiraPlugin {
|
|||
return false;
|
||||
}
|
||||
_jiraClient = JiraClient.Create(new Uri(JiraConfig.Url));
|
||||
_jiraClient.Behaviour.SetConfig(new SvgConfiguration { Width = CoreConfig.IconSize.Width, Height = CoreConfig.IconSize.Height });
|
||||
_jiraClient.Behaviour.SetConfig(new SvgConfiguration { Width = CoreConfig.ScaledIconSize.Width, Height = CoreConfig.ScaledIconSize.Height });
|
||||
_jiraClient.SetBasicAuthentication(user, password);
|
||||
|
||||
_issueTypeBitmapCache = new IssueTypeBitmapCache(_jiraClient);
|
||||
|
@ -127,7 +127,7 @@ namespace GreenshotJiraPlugin {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Use the credentials dialog, this will show if there are not correct credentials.
|
||||
/// If there are credentials, call the real login.
|
||||
|
@ -189,7 +189,7 @@ namespace GreenshotJiraPlugin {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the favorite filters
|
||||
/// Get the favorite filters
|
||||
/// </summary>
|
||||
/// <returns>List with filters</returns>
|
||||
public async Task<IList<Filter>> GetFavoriteFiltersAsync(CancellationToken cancellationToken = default)
|
||||
|
|
|
@ -14,18 +14,36 @@
|
|||
<ItemGroup>
|
||||
<ProjectReference Include="..\GreenshotPlugin\GreenshotPlugin.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Interop.Microsoft.Office.Interop.OneNote" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.Office.Interop.Excel" Version="15.0.4795.1000" />
|
||||
<PackageReference Include="Microsoft.Office.Interop.Outlook" Version="15.0.4797.1003" />
|
||||
<PackageReference Include="Microsoft.Office.Interop.PowerPoint" Version="15.0.4420.1017" />
|
||||
<PackageReference Include="Microsoft.Office.Interop.Word" Version="15.0.4797.1003" />
|
||||
<PackageReference Include="MicrosoftOfficeCore" Version="15.0.0" />
|
||||
<PackageReference Include="Interop.Microsoft.Office.Interop.OneNote" Version="1.1.0">
|
||||
<EmbedInteropTypes>true</EmbedInteropTypes>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Office.Interop.Excel" Version="15.0.4795.1000">
|
||||
<EmbedInteropTypes>true</EmbedInteropTypes>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Office.Interop.Outlook" Version="15.0.4797.1003">
|
||||
<EmbedInteropTypes>true</EmbedInteropTypes>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Office.Interop.PowerPoint" Version="15.0.4420.1017">
|
||||
<EmbedInteropTypes>true</EmbedInteropTypes>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Office.Interop.Word" Version="15.0.4797.1003">
|
||||
<EmbedInteropTypes>true</EmbedInteropTypes>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MicrosoftOfficeCore" Version="15.0.0">
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Unofficial.Microsoft.mshtml" Version="7.0.3300">
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="log4net" Version="2.0.8" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
*
|
||||
* For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -35,7 +35,7 @@ namespace GreenshotPlugin.Core {
|
|||
public abstract class AbstractDestination : IDestination {
|
||||
private static readonly ILog Log = LogManager.GetLogger(typeof(AbstractDestination));
|
||||
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
|
||||
|
||||
|
||||
public virtual int CompareTo(object obj) {
|
||||
if (!(obj is IDestination other)) {
|
||||
return 1;
|
||||
|
@ -150,7 +150,7 @@ namespace GreenshotPlugin.Core {
|
|||
ExportInformation exportInformation = new ExportInformation(Designation, Language.GetString("settings_destination_picker"));
|
||||
var menu = new ContextMenuStrip
|
||||
{
|
||||
ImageScalingSize = CoreConfig.IconSize,
|
||||
ImageScalingSize = CoreConfig.ScaledIconSize,
|
||||
Tag = null,
|
||||
TopLevel = true
|
||||
};
|
||||
|
@ -292,7 +292,7 @@ namespace GreenshotPlugin.Core {
|
|||
};
|
||||
AddTagEvents(basisMenuItem, menu, Description);
|
||||
basisMenuItem.Click -= destinationClickHandler;
|
||||
basisMenuItem.Click += destinationClickHandler;
|
||||
basisMenuItem.Click += destinationClickHandler;
|
||||
|
||||
if (IsDynamic && addDynamics) {
|
||||
basisMenuItem.DropDownOpening += delegate
|
||||
|
@ -330,6 +330,6 @@ namespace GreenshotPlugin.Core {
|
|||
|
||||
return basisMenuItem;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
*
|
||||
* For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -45,7 +45,7 @@ namespace GreenshotPlugin.Core {
|
|||
RELEASE_CANDIDATE,
|
||||
RELEASE
|
||||
}
|
||||
|
||||
|
||||
public enum ClickActions {
|
||||
DO_NOTHING,
|
||||
OPEN_LAST_IN_EXPLORER,
|
||||
|
@ -104,7 +104,7 @@ namespace GreenshotPlugin.Core {
|
|||
public bool PlayCameraSound { get; set; } = false;
|
||||
[IniProperty("ShowTrayNotification", LanguageKey="settings_shownotify",Description="Show a notification from the systray when a capture is taken.", DefaultValue="true")]
|
||||
public bool ShowTrayNotification { get; set; } = true;
|
||||
|
||||
|
||||
[IniProperty("OutputFilePath", Description="Output file path.")]
|
||||
public string OutputFilePath { get; set; }
|
||||
[IniProperty("OutputFileAllowOverwrite", Description = "If the target file already exists True will make Greenshot always overwrite and False will display a 'Save-As' dialog.", DefaultValue = "true")]
|
||||
|
@ -267,7 +267,7 @@ namespace GreenshotPlugin.Core {
|
|||
public Size Win10BorderCrop { get; set; }
|
||||
|
||||
private Size _iconSize;
|
||||
[IniProperty("IconSize", Description = "Defines the size of the icons (e.g. for the buttons in the editor), default value 16,16 anything bigger will cause scaling", DefaultValue = "16,16")]
|
||||
[IniProperty("BaseIconSize", Description = "Defines the base size of the icons (e.g. for the buttons in the editor), default value 16,16 and it's scaled to the current DPI", DefaultValue = "16,16")]
|
||||
public Size IconSize {
|
||||
get {
|
||||
return _iconSize;
|
||||
|
@ -295,6 +295,8 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
}
|
||||
|
||||
public Size ScaledIconSize => DpiHelper.ScaleWithCurrentDpi(_iconSize);
|
||||
|
||||
[IniProperty("WebRequestTimeout", Description = "The connect timeout value for webrequets, these are seconds", DefaultValue = "100")]
|
||||
public int WebRequestTimeout { get; set; }
|
||||
[IniProperty("WebRequestReadWriteTimeout", Description = "The read/write timeout value for webrequets, these are seconds", DefaultValue = "100")]
|
||||
|
@ -371,7 +373,7 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
return 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
|
||||
|
@ -494,7 +496,7 @@ namespace GreenshotPlugin.Core {
|
|||
NoDWMCaptureForProduct[i] = NoDWMCaptureForProduct[i].ToLower();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (AutoCropDifference < 0) {
|
||||
AutoCropDifference = 0;
|
||||
}
|
||||
|
|
711
GreenshotPlugin/Core/DpiHelper.cs
Normal file
711
GreenshotPlugin/Core/DpiHelper.cs
Normal file
|
@ -0,0 +1,711 @@
|
|||
using GreenshotPlugin.Core.Enums;
|
||||
using GreenshotPlugin.UnmanagedHelpers;
|
||||
using log4net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GreenshotPlugin.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// This handles DPI changes see
|
||||
/// <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266.aspx">Writing DPI-Aware Desktop and Win32 Applications</a>
|
||||
/// </summary>
|
||||
public static class DpiHelper
|
||||
{
|
||||
private static readonly ILog Log = LogManager.GetLogger(typeof(DpiHelper));
|
||||
|
||||
/// <summary>
|
||||
/// This is the default DPI for the screen
|
||||
/// </summary>
|
||||
public const uint DefaultScreenDpi = 96;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the current DPI for the UI element which is related to this DpiHandler
|
||||
/// </summary>
|
||||
public static uint Dpi { get; private set; } = GetDpiForSystem();
|
||||
|
||||
/// <summary>
|
||||
/// Calculate a DPI scale factor
|
||||
/// </summary>
|
||||
/// <param name="dpi">uint</param>
|
||||
/// <returns>double</returns>
|
||||
public static float DpiScaleFactor(uint dpi)
|
||||
{
|
||||
return (float)dpi / DefaultScreenDpi;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale the supplied number according to the supplied dpi
|
||||
/// </summary>
|
||||
/// <param name="someNumber">double with e.g. the width 16 for 16x16 images</param>
|
||||
/// <param name="dpi">current dpi, normal is 96.</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>double with the scaled number</returns>
|
||||
public static float ScaleWithDpi(float someNumber, uint dpi, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
var dpiScaleFactor = DpiScaleFactor(dpi);
|
||||
if (scaleModifier != null)
|
||||
{
|
||||
dpiScaleFactor = scaleModifier(dpiScaleFactor);
|
||||
}
|
||||
return dpiScaleFactor * someNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale the supplied number according to the supplied dpi
|
||||
/// </summary>
|
||||
/// <param name="number">int with e.g. 16 for 16x16 images</param>
|
||||
/// <param name="dpi">current dpi, normal is 96.</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>Scaled width</returns>
|
||||
public static int ScaleWithDpi(int number, uint dpi, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
var dpiScaleFactor = DpiScaleFactor(dpi);
|
||||
if (scaleModifier != null)
|
||||
{
|
||||
dpiScaleFactor = scaleModifier(dpiScaleFactor);
|
||||
}
|
||||
return (int)(dpiScaleFactor * number);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale the supplied Size according to the supplied dpi
|
||||
/// </summary>
|
||||
/// <param name="size">Size to resize</param>
|
||||
/// <param name="dpi">current dpi, normal is 96.</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>NativeSize scaled</returns>
|
||||
public static Size ScaleWithDpi(Size size, uint dpi, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
var dpiScaleFactor = DpiScaleFactor(dpi);
|
||||
if (scaleModifier != null)
|
||||
{
|
||||
dpiScaleFactor = scaleModifier(dpiScaleFactor);
|
||||
}
|
||||
return new Size((int)(dpiScaleFactor * size.Width), (int)(dpiScaleFactor * size.Height));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale the supplied NativePoint according to the supplied dpi
|
||||
/// </summary>
|
||||
/// <param name="size">NativePoint to resize</param>
|
||||
/// <param name="dpi">current dpi, normal is 96.</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>NativePoint scaled</returns>
|
||||
public static Point ScaleWithDpi(Point size, uint dpi, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
var dpiScaleFactor = DpiScaleFactor(dpi);
|
||||
if (scaleModifier != null)
|
||||
{
|
||||
dpiScaleFactor = scaleModifier(dpiScaleFactor);
|
||||
}
|
||||
return new Point((int)(dpiScaleFactor * size.X), (int)(dpiScaleFactor * size.Y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale the supplied NativeSizeFloat according to the supplied dpi
|
||||
/// </summary>
|
||||
/// <param name="point">PointF</param>
|
||||
/// <param name="dpi">current dpi, normal is 96.</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>PointF</returns>
|
||||
public static PointF ScaleWithDpi(PointF point, uint dpi, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
var dpiScaleFactor = DpiScaleFactor(dpi);
|
||||
if (scaleModifier != null)
|
||||
{
|
||||
dpiScaleFactor = scaleModifier(dpiScaleFactor);
|
||||
}
|
||||
return new PointF(dpiScaleFactor * point.X, dpiScaleFactor * point.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale the supplied NativeSizeFloat according to the supplied dpi
|
||||
/// </summary>
|
||||
/// <param name="size">NativeSizeFloat to resize</param>
|
||||
/// <param name="dpi">current dpi, normal is 96.</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>NativeSize scaled</returns>
|
||||
public static SizeF ScaleWithDpi(SizeF size, uint dpi, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
var dpiScaleFactor = DpiScaleFactor(dpi);
|
||||
if (scaleModifier != null)
|
||||
{
|
||||
dpiScaleFactor = scaleModifier(dpiScaleFactor);
|
||||
}
|
||||
return new SizeF(dpiScaleFactor * size.Width, dpiScaleFactor * size.Height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale the supplied number to the current dpi
|
||||
/// </summary>
|
||||
/// <param name="someNumber">double with e.g. a width like 16 for 16x16 images</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>double with scaled number</returns>
|
||||
public static float ScaleWithCurrentDpi(float someNumber, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
return ScaleWithDpi(someNumber, Dpi, scaleModifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale the supplied number to the current dpi
|
||||
/// </summary>
|
||||
/// <param name="someNumber">int with e.g. a width like 16 for 16x16 images</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>int with scaled number</returns>
|
||||
public static int ScaleWithCurrentDpi(int someNumber, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
return ScaleWithDpi(someNumber, Dpi, scaleModifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale the supplied NativeSize to the current dpi
|
||||
/// </summary>
|
||||
/// <param name="size">NativeSize to scale</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>NativeSize scaled</returns>
|
||||
public static Size ScaleWithCurrentDpi(Size size, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
return ScaleWithDpi(size, Dpi, scaleModifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale the supplied NativeSizeFloat to the current dpi
|
||||
/// </summary>
|
||||
/// <param name="size">NativeSizeFloat to scale</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>NativeSizeFloat scaled</returns>
|
||||
public static SizeF ScaleWithCurrentDpi(SizeF size, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
return ScaleWithDpi(size, Dpi, scaleModifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale the supplied NativePoint to the current dpi
|
||||
/// </summary>
|
||||
/// <param name="point">NativePoint to scale</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>NativePoint scaled</returns>
|
||||
public static Point ScaleWithCurrentDpi(Point point, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
return ScaleWithDpi(point, Dpi, scaleModifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale the supplied PointF to the current dpi
|
||||
/// </summary>
|
||||
/// <param name="point">PointF to scale</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>PointF scaled</returns>
|
||||
public static PointF ScaleWithCurrentDpi(PointF point, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
return ScaleWithDpi(point, Dpi, scaleModifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate a DPI unscale factor
|
||||
/// </summary>
|
||||
/// <param name="dpi">uint</param>
|
||||
/// <returns>float</returns>
|
||||
public static float DpiUnscaleFactor(uint dpi)
|
||||
{
|
||||
return (float)DefaultScreenDpi / dpi;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unscale the supplied number according to the supplied dpi
|
||||
/// </summary>
|
||||
/// <param name="someNumber">double with e.g. the scaled width</param>
|
||||
/// <param name="dpi">current dpi, normal is 96.</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>double with the unscaled number</returns>
|
||||
public static float UnscaleWithDpi(float someNumber, uint dpi, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
var dpiUnscaleFactor = DpiUnscaleFactor(dpi);
|
||||
if (scaleModifier != null)
|
||||
{
|
||||
dpiUnscaleFactor = scaleModifier(dpiUnscaleFactor);
|
||||
}
|
||||
return dpiUnscaleFactor * someNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unscale the supplied number according to the supplied dpi
|
||||
/// </summary>
|
||||
/// <param name="number">int with a scaled width</param>
|
||||
/// <param name="dpi">current dpi, normal is 96.</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>Unscaled width</returns>
|
||||
public static int UnscaleWithDpi(int number, uint dpi, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
var dpiUnscaleFactor = DpiUnscaleFactor(dpi);
|
||||
if (scaleModifier != null)
|
||||
{
|
||||
dpiUnscaleFactor = scaleModifier(dpiUnscaleFactor);
|
||||
}
|
||||
return (int)(dpiUnscaleFactor * number);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unscale the supplied NativeSize according to the supplied dpi
|
||||
/// </summary>
|
||||
/// <param name="size">NativeSize to unscale</param>
|
||||
/// <param name="dpi">current dpi, normal is 96.</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>Size unscaled</returns>
|
||||
public static Size UnscaleWithDpi(Size size, uint dpi, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
var dpiUnscaleFactor = DpiUnscaleFactor(dpi);
|
||||
if (scaleModifier != null)
|
||||
{
|
||||
dpiUnscaleFactor = scaleModifier(dpiUnscaleFactor);
|
||||
}
|
||||
return new Size((int)(dpiUnscaleFactor * size.Width), (int)(dpiUnscaleFactor * size.Height));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unscale the supplied Point according to the supplied dpi
|
||||
/// </summary>
|
||||
/// <param name="size">Point to unscale</param>
|
||||
/// <param name="dpi">current dpi, normal is 96.</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>Point unscaled</returns>
|
||||
public static Point UnscaleWithDpi(Point point, uint dpi, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
var dpiUnscaleFactor = DpiUnscaleFactor(dpi);
|
||||
if (scaleModifier != null)
|
||||
{
|
||||
dpiUnscaleFactor = scaleModifier(dpiUnscaleFactor);
|
||||
}
|
||||
return new Point((int)(dpiUnscaleFactor * point.X), (int)(dpiUnscaleFactor * point.Y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// unscale the supplied NativeSizeFloat according to the supplied dpi
|
||||
/// </summary>
|
||||
/// <param name="size">NativeSizeFloat to resize</param>
|
||||
/// <param name="dpi">current dpi, normal is 96.</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>SizeF unscaled</returns>
|
||||
public static SizeF UnscaleWithDpi(SizeF size, uint dpi, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
float dpiUnscaleFactor = DpiUnscaleFactor(dpi);
|
||||
if (scaleModifier != null)
|
||||
{
|
||||
dpiUnscaleFactor = scaleModifier(dpiUnscaleFactor);
|
||||
}
|
||||
return new SizeF(dpiUnscaleFactor * size.Width, dpiUnscaleFactor * size.Height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unscale the supplied number to the current dpi
|
||||
/// </summary>
|
||||
/// <param name="someNumber">double with e.g. a width like 16 for 16x16 images</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>double with unscaled number</returns>
|
||||
public static float UnscaleWithCurrentDpi(float someNumber, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
return UnscaleWithDpi(someNumber, Dpi, scaleModifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unscale the supplied number to the current dpi
|
||||
/// </summary>
|
||||
/// <param name="someNumber">int with e.g. a width like 16 for 16x16 images</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>int with unscaled number</returns>
|
||||
public static int UnscaleWithCurrentDpi(int someNumber, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
return UnscaleWithDpi(someNumber, Dpi, scaleModifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unscale the supplied NativeSize to the current dpi
|
||||
/// </summary>
|
||||
/// <param name="size">Size to unscale</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>Size unscaled</returns>
|
||||
public static Size UnscaleWithCurrentDpi(Size size, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
return UnscaleWithDpi(size, Dpi, scaleModifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unscale the supplied NativeSizeFloat to the current dpi
|
||||
/// </summary>
|
||||
/// <param name="size">NativeSizeFloat to unscale</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>NativeSizeFloat unscaled</returns>
|
||||
public static SizeF UnscaleWithCurrentDpi(SizeF size, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
return UnscaleWithDpi(size, Dpi, scaleModifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unscale the supplied NativePoint to the current dpi
|
||||
/// </summary>
|
||||
/// <param name="point">NativePoint to unscale</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>NativePoint unscaled</returns>
|
||||
public static Point UnscaleWithCurrentDpi(Point point, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
return UnscaleWithDpi(point, Dpi, scaleModifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unscale the supplied NativePointFloat to the current dpi
|
||||
/// </summary>
|
||||
/// <param name="point">NativePointFloat to unscale</param>
|
||||
/// <param name="scaleModifier">A function which can modify the scale factor</param>
|
||||
/// <returns>NativePointFloat unscaled</returns>
|
||||
public static PointF UnscaleWithCurrentDpi(PointF point, Func<float, float> scaleModifier = null)
|
||||
{
|
||||
return ScaleWithDpi(point, Dpi, scaleModifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// public wrapper for EnableNonClientDpiScaling, this also checks if the function is available.
|
||||
/// </summary>
|
||||
/// <param name="hWnd">IntPtr</param>
|
||||
/// <returns>true if it worked</returns>
|
||||
public static bool TryEnableNonClientDpiScaling(IntPtr hWnd)
|
||||
{
|
||||
// EnableNonClientDpiScaling is only available on Windows 10 and later
|
||||
if (!WindowsVersion.IsWindows10OrLater)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var result = EnableNonClientDpiScaling(hWnd);
|
||||
if (result.Succeeded())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var error = Win32.GetLastErrorCode();
|
||||
if (Log.IsDebugEnabled)
|
||||
{
|
||||
Log.DebugFormat("Error enabling non client dpi scaling : {0}", Win32.GetMessage(error));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make the current process DPI Aware, this should be done via the manifest but sometimes this is not possible.
|
||||
/// </summary>
|
||||
/// <returns>bool true if it was possible to change the DPI awareness</returns>
|
||||
public static bool EnableDpiAware()
|
||||
{
|
||||
// We can only test this for Windows 8.1 or later
|
||||
if (!WindowsVersion.IsWindows81OrLater)
|
||||
{
|
||||
Log.Debug("An application can only be DPI aware starting with Window 8.1 and later.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (WindowsVersion.IsWindows10BuildOrLater(15063))
|
||||
{
|
||||
if (IsValidDpiAwarenessContext(DpiAwarenessContext.PerMonitorAwareV2))
|
||||
{
|
||||
SetProcessDpiAwarenessContext(DpiAwarenessContext.PerMonitorAwareV2);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetProcessDpiAwarenessContext(DpiAwarenessContext.PerMonitorAwareV2);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return SetProcessDpiAwareness(DpiAwareness.PerMonitorAware).Succeeded();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the process is DPI Aware, an DpiHandler doesn't make sense if not.
|
||||
/// </summary>
|
||||
public static bool IsDpiAware
|
||||
{
|
||||
get
|
||||
{
|
||||
// We can only test this for Windows 8.1 or later
|
||||
if (!WindowsVersion.IsWindows81OrLater)
|
||||
{
|
||||
Log.Debug("An application can only be DPI aware starting with Window 8.1 and later.");
|
||||
return false;
|
||||
}
|
||||
|
||||
using var process = Process.GetCurrentProcess();
|
||||
GetProcessDpiAwareness(process.Handle, out var dpiAwareness);
|
||||
if (Log.IsDebugEnabled)
|
||||
{
|
||||
Log.DebugFormat("Process {0} has a Dpi awareness {1}", process.ProcessName, dpiAwareness);
|
||||
}
|
||||
|
||||
return dpiAwareness != DpiAwareness.Unaware && dpiAwareness != DpiAwareness.Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the DPI value for the supplied window handle
|
||||
/// </summary>
|
||||
/// <param name="hWnd">IntPtr</param>
|
||||
/// <returns>dpi value</returns>
|
||||
public static uint GetDpi(IntPtr hWnd)
|
||||
{
|
||||
if (!User32.IsWindow(hWnd))
|
||||
{
|
||||
return DefaultScreenDpi;
|
||||
}
|
||||
|
||||
// Use the easiest method, but this only works for Windows 10
|
||||
if (WindowsVersion.IsWindows10OrLater)
|
||||
{
|
||||
return GetDpiForWindow(hWnd);
|
||||
}
|
||||
|
||||
// Use the second easiest method, but this only works for Windows 8.1 or later
|
||||
if (WindowsVersion.IsWindows81OrLater)
|
||||
{
|
||||
var hMonitor = User32.MonitorFromWindow(hWnd, MonitorFrom.DefaultToNearest);
|
||||
// ReSharper disable once UnusedVariable
|
||||
if (GetDpiForMonitor(hMonitor, MonitorDpiType.EffectiveDpi, out var dpiX, out var dpiY))
|
||||
{
|
||||
return dpiX;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to the global DPI settings
|
||||
using var hdc = SafeWindowDcHandle.FromWindow(hWnd);
|
||||
if (hdc == null)
|
||||
{
|
||||
return DefaultScreenDpi;
|
||||
}
|
||||
return (uint)GDI32.GetDeviceCaps(hdc, DeviceCaps.LOGPIXELSX);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See details <a hef="https://msdn.microsoft.com/en-us/library/windows/desktop/dn302113(v=vs.85).aspx">GetProcessDpiAwareness function</a>
|
||||
/// Retrieves the dots per inch (dpi) awareness of the specified process.
|
||||
/// </summary>
|
||||
/// <param name="processHandle">IntPtr with handle of the process that is being queried. If this parameter is NULL, the current process is queried.</param>
|
||||
/// <param name="value">out DpiAwareness - The DPI awareness of the specified process. Possible values are from the PROCESS_DPI_AWARENESS enumeration.</param>
|
||||
/// <returns>HResult</returns>
|
||||
[DllImport("shcore")]
|
||||
private static extern HResult GetProcessDpiAwareness(IntPtr processHandle, out DpiAwareness value);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current process to a specified dots per inch (dpi) awareness level. The DPI awareness levels are from the PROCESS_DPI_AWARENESS enumeration.
|
||||
/// See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dn302122(v=vs.85).aspx">SetProcessDpiAwareness function</a>
|
||||
/// </summary>
|
||||
/// <param name="dpiAwareness">DpiAwareness</param>
|
||||
/// <returns>HResult</returns>
|
||||
[DllImport("shcore")]
|
||||
private static extern HResult SetProcessDpiAwareness(DpiAwareness dpiAwareness);
|
||||
|
||||
/// <summary>
|
||||
/// It is recommended that you set the process-default DPI awareness via application manifest. See Setting the default DPI awareness for a process for more information. Setting the process-default DPI awareness via API call can lead to unexpected application behavior.
|
||||
///
|
||||
/// Sets the current process to a specified dots per inch (dpi) awareness context. The DPI awareness contexts are from the DPI_AWARENESS_CONTEXT value.
|
||||
/// Remarks:
|
||||
/// This API is a more advanced version of the previously existing SetProcessDpiAwareness API, allowing for the process default to be set to the finer-grained DPI_AWARENESS_CONTEXT values. Most importantly, this allows you to programmatically set Per Monitor v2 as the process default value, which is not possible with the previous API.
|
||||
///
|
||||
/// This method sets the default DPI_AWARENESS_CONTEXT for all threads within an application. Individual threads can have their DPI awareness changed from the default with the SetThreadDpiAwarenessContext method.
|
||||
/// See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt807676(v=vs.85).aspx">SetProcessDpiAwarenessContext function</a>
|
||||
/// </summary>
|
||||
/// <param name="dpiAwarenessContext">DpiAwarenessContext</param>
|
||||
/// <returns>bool</returns>
|
||||
[DllImport("User32.dll", SetLastError = true)]
|
||||
private static extern bool SetProcessDpiAwarenessContext(DpiAwarenessContext dpiAwarenessContext);
|
||||
|
||||
/// <summary>
|
||||
/// See more at <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt748624(v=vs.85).aspx">GetDpiForWindow function</a>
|
||||
/// Returns the dots per inch (dpi) value for the associated window.
|
||||
/// </summary>
|
||||
/// <param name="hWnd">IntPtr</param>
|
||||
/// <returns>uint with dpi</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern uint GetDpiForWindow(IntPtr hWnd);
|
||||
|
||||
/// <summary>
|
||||
/// See
|
||||
/// <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dn280510(v=vs.85).aspx">GetDpiForMonitor function</a>
|
||||
/// Queries the dots per inch (dpi) of a display.
|
||||
/// </summary>
|
||||
/// <param name="hMonitor">IntPtr</param>
|
||||
/// <param name="dpiType">MonitorDpiType</param>
|
||||
/// <param name="dpiX">out int for the horizontal dpi</param>
|
||||
/// <param name="dpiY">out int for the vertical dpi</param>
|
||||
/// <returns>true if all okay</returns>
|
||||
[DllImport("shcore")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool GetDpiForMonitor(IntPtr hMonitor, MonitorDpiType dpiType, out uint dpiX, out uint dpiY);
|
||||
|
||||
/// <summary>
|
||||
/// See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt748621(v=vs.85).aspx">EnableNonClientDpiScaling function</a>
|
||||
/// </summary>
|
||||
/// <param name="hWnd">IntPtr</param>
|
||||
/// <returns>bool</returns>
|
||||
[DllImport("User32.dll", SetLastError = true)]
|
||||
private static extern HResult EnableNonClientDpiScaling(IntPtr hWnd);
|
||||
|
||||
/// <summary>
|
||||
/// See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt748623(v=vs.85).aspx">GetDpiForSystem function</a>
|
||||
/// Returns the system DPI.
|
||||
/// </summary>
|
||||
/// <returns>uint with the system DPI</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern uint GetDpiForSystem();
|
||||
|
||||
/// <summary>
|
||||
/// Converts a point in a window from logical coordinates into physical coordinates, regardless of the dots per inch (dpi) awareness of the caller. For more information about DPI awareness levels, see PROCESS_DPI_AWARENESS.
|
||||
/// See more at <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dn384110(v=vs.85).aspx">LogicalToPhysicalPointForPerMonitorDPI function</a>
|
||||
/// </summary>
|
||||
/// <param name="hWnd">IntPtr A handle to the window whose transform is used for the conversion.</param>
|
||||
/// <param name="point">A pointer to a POINT structure that specifies the logical coordinates to be converted. The new physical coordinates are copied into this structure if the function succeeds.</param>
|
||||
/// <returns>bool</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern bool LogicalToPhysicalPointForPerMonitorDPI(IntPtr hWnd, ref POINT point);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a point in a window from logical coordinates into physical coordinates, regardless of the dots per inch (dpi) awareness of the caller. For more information about DPI awareness levels, see PROCESS_DPI_AWARENESS.
|
||||
/// See more at <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dn384112(v=vs.85).aspx">PhysicalToLogicalPointForPerMonitorDPI function</a>
|
||||
/// </summary>
|
||||
/// <param name="hWnd">IntPtr A handle to the window whose transform is used for the conversion.</param>
|
||||
/// <param name="point">NativePoint A pointer to a POINT structure that specifies the physical/screen coordinates to be converted. The new logical coordinates are copied into this structure if the function succeeds.</param>
|
||||
/// <returns>bool</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern bool PhysicalToLogicalPointForPerMonitorDPI(IntPtr hWnd, ref POINT point);
|
||||
|
||||
/// <summary>
|
||||
/// See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947(v=vs.85).aspx">SystemParametersInfo function</a>
|
||||
/// Retrieves the value of one of the system-wide parameters, taking into account the provided DPI value.
|
||||
/// </summary>
|
||||
/// <param name="uiAction">
|
||||
/// SystemParametersInfoActions The system-wide parameter to be retrieved.
|
||||
/// This function is only intended for use with SPI_GETICONTITLELOGFONT, SPI_GETICONMETRICS, or SPI_GETNONCLIENTMETRICS. See SystemParametersInfo for more information on these values.
|
||||
/// </param>
|
||||
/// <param name="uiParam">
|
||||
/// A parameter whose usage and format depends on the system parameter being queried or set. For more
|
||||
/// information about system-wide parameters, see the uiAction parameter. If not otherwise indicated, you must specify
|
||||
/// zero for this parameter.
|
||||
/// </param>
|
||||
/// <param name="pvParam">IntPtr</param>
|
||||
/// <param name="fWinIni">SystemParametersInfoBehaviors</param>
|
||||
/// <param name="dpi">uint with dpi value</param>
|
||||
/// <returns>bool</returns>
|
||||
[DllImport("User32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool SystemParametersInfoForDpi(SystemParametersInfoActions uiAction, uint uiParam, IntPtr pvParam, SystemParametersInfoBehaviors fWinIni, uint dpi);
|
||||
|
||||
/// <summary>
|
||||
/// See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt748626(v=vs.85).aspx">GetThreadDpiAwarenessContext function</a>
|
||||
/// Gets the DPI_AWARENESS_CONTEXT for the current thread.
|
||||
///
|
||||
/// This method will return the latest DPI_AWARENESS_CONTEXT sent to SetThreadDpiAwarenessContext. If SetThreadDpiAwarenessContext was never called for this thread, then the return value will equal the default DPI_AWARENESS_CONTEXT for the process.
|
||||
/// </summary>
|
||||
/// <returns>DpiAwarenessContext</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern DpiAwarenessContext GetThreadDpiAwarenessContext();
|
||||
|
||||
/// <summary>
|
||||
/// Set the DPI awareness for the current thread to the provided value.
|
||||
/// </summary>
|
||||
/// <param name="dpiAwarenessContext">DpiAwarenessContext the new value for the current thread</param>
|
||||
/// <returns>DpiAwarenessContext previous value</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern DpiAwarenessContext SetThreadDpiAwarenessContext(DpiAwarenessContext dpiAwarenessContext);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the DpiAwareness value from a DpiAwarenessContext.
|
||||
/// </summary>
|
||||
/// <param name="dpiAwarenessContext">DpiAwarenessContext</param>
|
||||
/// <returns>DpiAwareness</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern DpiAwareness GetAwarenessFromDpiAwarenessContext(DpiAwarenessContext dpiAwarenessContext);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the DPI from a given DPI_AWARENESS_CONTEXT handle. This enables you to determine the DPI of a thread without needed to examine a window created within that thread.
|
||||
/// </summary>
|
||||
/// <param name="dpiAwarenessContext">DpiAwarenessContext</param>
|
||||
/// <returns>uint with dpi value</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern uint GetDpiFromDpiAwarenessContext(DpiAwarenessContext dpiAwarenessContext);
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a specified DPI_AWARENESS_CONTEXT is valid and supported by the current system.
|
||||
/// </summary>
|
||||
/// <param name="dpiAwarenessContext">DpiAwarenessContext The context that you want to determine if it is supported.</param>
|
||||
/// <returns>bool true if supported otherwise false</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern bool IsValidDpiAwarenessContext(DpiAwarenessContext dpiAwarenessContext);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the DPI_HOSTING_BEHAVIOR of the specified window.
|
||||
///
|
||||
/// This API allows you to examine the hosting behavior of a window after it has been created. A window's hosting behavior is the hosting behavior of the thread in which the window was created, as set by a call to SetThreadDpiHostingBehavior. This is a permanent value and cannot be changed after the window is created, even if the thread's hosting behavior is changed.
|
||||
/// </summary>
|
||||
/// <returns>DpiHostingBehavior</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern DpiHostingBehavior GetWindowDpiHostingBehavior();
|
||||
|
||||
/// <summary>
|
||||
/// See more at <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt845775.aspx">SetThreadDpiHostingBehavior function</a>
|
||||
/// Sets the thread's DPI_HOSTING_BEHAVIOR. This behavior allows windows created in the thread to host child windows with a different DPI_AWARENESS_CONTEXT.
|
||||
///
|
||||
/// DPI_HOSTING_BEHAVIOR enables a mixed content hosting behavior, which allows parent windows created in the thread to host child windows with a different DPI_AWARENESS_CONTEXT value. This property only effects new windows created within this thread while the mixed hosting behavior is active. A parent window with this hosting behavior is able to host child windows with different DPI_AWARENESS_CONTEXT values, regardless of whether the child windows have mixed hosting behavior enabled.
|
||||
///
|
||||
/// This hosting behavior does not allow for windows with per-monitor DPI_AWARENESS_CONTEXT values to be hosted until windows with DPI_AWARENESS_CONTEXT values of system or unaware.
|
||||
///
|
||||
/// To avoid unexpected outcomes, a thread's DPI_HOSTING_BEHAVIOR should be changed to support mixed hosting behaviors only when creating a new window which needs to support those behaviors. Once that window is created, the hosting behavior should be switched back to its default value.
|
||||
///
|
||||
/// This API is used to change the thread's DPI_HOSTING_BEHAVIOR from its default value. This is only necessary if your app needs to host child windows from plugins and third-party components that do not support per-monitor-aware context. This is most likely to occur if you are updating complex applications to support per-monitor DPI_AWARENESS_CONTEXT behaviors.
|
||||
///
|
||||
/// Enabling mixed hosting behavior will not automatically adjust the thread's DPI_AWARENESS_CONTEXT to be compatible with legacy content. The thread's awareness context must still be manually changed before new windows are created to host such content.
|
||||
/// </summary>
|
||||
/// <param name="dpiHostingBehavior">DpiHostingBehavior</param>
|
||||
/// <returns>previous DpiHostingBehavior</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern DpiHostingBehavior SetThreadDpiHostingBehavior(DpiHostingBehavior dpiHostingBehavior);
|
||||
|
||||
/// <summary>
|
||||
///Retrieves the DPI_HOSTING_BEHAVIOR from the current thread.
|
||||
/// </summary>
|
||||
/// <returns>DpiHostingBehavior</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern DpiHostingBehavior GetThreadDpiHostingBehavior();
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the default per-monitor DPI scaling behavior of a child window in a dialog.
|
||||
/// This function returns TRUE if the operation was successful, and FALSE otherwise. To get extended error information, call GetLastError.
|
||||
///
|
||||
/// Possible errors are ERROR_INVALID_HANDLE if passed an invalid HWND, and ERROR_ACCESS_DENIED if the windows belongs to another process.
|
||||
///
|
||||
/// The behaviors are specified as values from the DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS enum. This function follows the typical two-parameter approach to setting flags, where a mask specifies the subset of the flags to be changed.
|
||||
///
|
||||
/// It is valid to set these behaviors on any window. It does not matter if the window is currently a child of a dialog at the point in time that SetDialogControlDpiChangeBehavior is called. The behaviors are retained and will take effect only when the window is an immediate child of a dialog that has per-monitor DPI scaling enabled.
|
||||
///
|
||||
/// This API influences individual controls within dialogs. The dialog-wide per-monitor DPI scaling behavior is controlled by SetDialogDpiChangeBehavior.
|
||||
/// </summary>
|
||||
/// <param name="hWnd">IntPtr A handle for the window whose behavior will be modified.</param>
|
||||
/// <param name="mask">DialogScalingBehaviors A mask specifying the subset of flags to be changed.</param>
|
||||
/// <param name="values">DialogScalingBehaviors The desired value to be set for the specified subset of flags.</param>
|
||||
/// <returns>bool</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern bool SetDialogControlDpiChangeBehavior(IntPtr hWnd, DialogScalingBehaviors mask, DialogScalingBehaviors values);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves and per-monitor DPI scaling behavior overrides of a child window in a dialog.
|
||||
/// The flags set on the given window. If passed an invalid handle, this function will return zero, and set its last error to ERROR_INVALID_HANDLE.
|
||||
/// </summary>
|
||||
/// <param name="hWnd">IntPtr A handle for the window whose behavior will be modified.</param>
|
||||
/// <returns>DialogScalingBehaviors</returns>
|
||||
[DllImport("User32.dll")]
|
||||
private static extern DialogScalingBehaviors GetDialogControlDpiChangeBehavior(IntPtr hWnd);
|
||||
}
|
||||
}
|
34
GreenshotPlugin/Core/Enums/DialogDpiChangeBehaviors.cs
Normal file
34
GreenshotPlugin/Core/Enums/DialogDpiChangeBehaviors.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) Dapplo and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
using System;
|
||||
|
||||
namespace GreenshotPlugin.Core.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// In Per Monitor v2 contexts, dialogs will automatically respond to DPI changes by resizing themselves and re-computing the positions of their child windows (here referred to as re-layouting). This enum works in conjunction with SetDialogDpiChangeBehavior in order to override the default DPI scaling behavior for dialogs.
|
||||
/// This does not affect DPI scaling behavior for the child windows of dialogs(beyond re-layouting), which is controlled by DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum DialogDpiChangeBehaviors
|
||||
{
|
||||
/// <summary>
|
||||
/// The default behavior of the dialog manager. In response to a DPI change, the dialog manager will re-layout each control, update the font on each control, resize the dialog, and update the dialog's own font.
|
||||
/// </summary>
|
||||
Default = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Prevents the dialog manager from responding to WM_GETDPISCALEDSIZE and WM_DPICHANGED, disabling all default DPI scaling behavior.
|
||||
/// </summary>
|
||||
DisableAll = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Prevents the dialog manager from resizing the dialog in response to a DPI change.
|
||||
/// </summary>
|
||||
DisableResize = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Prevents the dialog manager from re-layouting all of the dialogue's immediate children HWNDs in response to a DPI change.
|
||||
/// </summary>
|
||||
DisableControlRelayout = 3
|
||||
}
|
||||
}
|
32
GreenshotPlugin/Core/Enums/DialogScalingBehaviors.cs
Normal file
32
GreenshotPlugin/Core/Enums/DialogScalingBehaviors.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) Dapplo and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
using System;
|
||||
|
||||
namespace GreenshotPlugin.Core.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes per-monitor DPI scaling behavior overrides for child windows within dialogs. The values in this enumeration are bitfields and can be combined.
|
||||
///
|
||||
/// This enum is used with SetDialogControlDpiChangeBehavior in order to override the default per-monitor DPI scaling behavior for a child window within a dialog.
|
||||
///
|
||||
/// These settings only apply to individual controls within dialogs. The dialog-wide per-monitor DPI scaling behavior of a dialog is controlled by DIALOG_DPI_CHANGE_BEHAVIORS.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum DialogScalingBehaviors
|
||||
{
|
||||
/// <summary>
|
||||
/// The default behavior of the dialog manager. The dialog managed will update the font, size, and position of the child window on DPI changes.
|
||||
/// </summary>
|
||||
Default = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Prevents the dialog manager from sending an updated font to the child window via WM_SETFONT in response to a DPI change.
|
||||
/// </summary>
|
||||
DisableFontUpdate = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Prevents the dialog manager from resizing and repositioning the child window in response to a DPI change.
|
||||
/// </summary>
|
||||
DisableRelayout = 2
|
||||
}
|
||||
}
|
40
GreenshotPlugin/Core/Enums/DpiAwareness.cs
Normal file
40
GreenshotPlugin/Core/Enums/DpiAwareness.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) Dapplo and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace GreenshotPlugin.Core.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies the dots per inch (dpi) setting for a thread, process, or window.
|
||||
/// Can be used everywhere ProcessDpiAwareness is passed.
|
||||
/// </summary>
|
||||
public enum DpiAwareness
|
||||
{
|
||||
/// <summary>
|
||||
/// Invalid DPI awareness. This is an invalid DPI awareness value.
|
||||
/// </summary>
|
||||
Invalid = -1,
|
||||
|
||||
/// <summary>
|
||||
/// DPI unaware.
|
||||
/// This process does not scale for DPI changes and is always assumed to have a scale factor of 100% (96 DPI).
|
||||
/// It will be automatically scaled by the system on any other DPI setting.
|
||||
/// </summary>
|
||||
Unaware = 0,
|
||||
|
||||
/// <summary>
|
||||
/// System DPI aware.
|
||||
/// This process does not scale for DPI changes.
|
||||
/// It will query for the DPI once and use that value for the lifetime of the process.
|
||||
/// If the DPI changes, the process will not adjust to the new DPI value.
|
||||
/// It will be automatically scaled up or down by the system when the DPI changes from the system value.
|
||||
/// </summary>
|
||||
SystemAware = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Per monitor DPI aware.
|
||||
/// This process checks for the DPI when it is created and adjusts the scale factor whenever the DPI changes.
|
||||
/// These processes are not automatically scaled by the system.
|
||||
/// </summary>
|
||||
PerMonitorAware = 2
|
||||
}
|
||||
}
|
46
GreenshotPlugin/Core/Enums/DpiAwarenessContext.cs
Normal file
46
GreenshotPlugin/Core/Enums/DpiAwarenessContext.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) Dapplo and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace GreenshotPlugin.Core.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public enum DpiAwarenessContext
|
||||
{
|
||||
/// <summary>
|
||||
/// DPI unaware.
|
||||
/// This window does not scale for DPI changes and is always assumed to have a scale factor of 100% (96 DPI).
|
||||
/// It will be automatically scaled by the system on any other DPI setting.
|
||||
/// </summary>
|
||||
Unaware = -1,
|
||||
|
||||
/// <summary>
|
||||
/// System DPI aware.
|
||||
/// This window does not scale for DPI changes.
|
||||
/// It will query for the DPI once and use that value for the lifetime of the process.
|
||||
/// If the DPI changes, the process will not adjust to the new DPI value.
|
||||
/// It will be automatically scaled up or down by the system when the DPI changes from the system value.
|
||||
/// </summary>
|
||||
SystemAware = -2,
|
||||
|
||||
/// <summary>
|
||||
/// Per monitor DPI aware.
|
||||
/// This window checks for the DPI when it is created and adjusts the scale factor whenever the DPI changes.
|
||||
/// These processes are not automatically scaled by the system.
|
||||
/// </summary>
|
||||
PerMonitorAware = -3,
|
||||
|
||||
/// <summary>
|
||||
/// Also known as Per Monitor v2. An advancement over the original per-monitor DPI awareness mode, which enables applications to access new DPI-related scaling behaviors on a per top-level window basis.
|
||||
/// Per Monitor v2 was made available in the Creators Update of Windows 10, and is not available on earlier versions of the operating system.
|
||||
/// The additional behaviors introduced are as follows:
|
||||
/// * Child window DPI change notifications - In Per Monitor v2 contexts, the entire window tree is notified of any DPI changes that occur.
|
||||
/// * Scaling of non-client area - All windows will automatically have their non-client area drawn in a DPI sensitive fashion. Calls to EnableNonClientDpiScaling are unnecessary.
|
||||
/// * Scaling of Win32 menus - All NTUSER menus created in Per Monitor v2 contexts will be scaling in a per-monitor fashion.
|
||||
/// * Dialog Scaling - Win32 dialogs created in Per Monitor v2 contexts will automatically respond to DPI changes.
|
||||
/// * Improved scaling of comctl32 controls - Various comctl32 controls have improved DPI scaling behavior in Per Monitor v2 contexts.
|
||||
/// * Improved theming behavior - UxTheme handles opened in the context of a Per Monitor v2 window will operate in terms of the DPI associated with that window.
|
||||
/// </summary>
|
||||
PerMonitorAwareV2 = -4
|
||||
}
|
||||
}
|
28
GreenshotPlugin/Core/Enums/DpiHostingBehavior.cs
Normal file
28
GreenshotPlugin/Core/Enums/DpiHostingBehavior.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) Dapplo and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace GreenshotPlugin.Core.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies the DPI hosting behavior for a window.
|
||||
/// This behavior allows windows created in the thread to host child windows with a different DPI_AWARENESS_CONTEXT
|
||||
/// </summary>
|
||||
public enum DpiHostingBehavior
|
||||
{
|
||||
/// <summary>
|
||||
/// Invalid DPI hosting behavior. This usually occurs if the previous SetThreadDpiHostingBehavior call used an invalid parameter.
|
||||
/// </summary>
|
||||
Invalid = -1,
|
||||
|
||||
/// <summary>
|
||||
/// Default DPI hosting behavior. The associated window behaves as normal, and cannot create or re-parent child windows with a different DPI_AWARENESS_CONTEXT.
|
||||
/// </summary>
|
||||
Default = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Mixed DPI hosting behavior. This enables the creation and re-parenting of child windows with different DPI_AWARENESS_CONTEXT. These child windows will be independently scaled by the OS.
|
||||
/// </summary>
|
||||
Mixed = 1
|
||||
|
||||
}
|
||||
}
|
|
@ -1,11 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
// Greenshot - a free and open source screenshot tool
|
||||
// Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
//
|
||||
// For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace GreenshotWin10Plugin.Native
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace GreenshotPlugin.Core.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// The HRESULT represents Windows error codes
|
40
GreenshotPlugin/Core/Enums/MonitorDpiType.cs
Normal file
40
GreenshotPlugin/Core/Enums/MonitorDpiType.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) Dapplo and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
using System;
|
||||
|
||||
namespace GreenshotPlugin.Core.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// See
|
||||
/// <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dn280511(v=vs.85).aspx">
|
||||
/// MONITOR_DPI_TYPE
|
||||
/// enumeration
|
||||
/// </a>
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum MonitorDpiType
|
||||
{
|
||||
/// <summary>
|
||||
/// The effective DPI.
|
||||
/// This value should be used when determining the correct scale factor for scaling UI elements.
|
||||
/// This incorporates the scale factor set by the user for this specific display.
|
||||
/// </summary>
|
||||
EffectiveDpi = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The angular DPI.
|
||||
/// This DPI ensures rendering at a compliant angular resolution on the screen.
|
||||
/// This does not include the scale factor set by the user for this specific display
|
||||
/// </summary>
|
||||
AngularDpi = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The raw DPI.
|
||||
/// This value is the linear DPI of the screen as measured on the screen itself.
|
||||
/// Use this value when you want to read the pixel density and not the recommended scaling setting.
|
||||
/// This does not include the scale factor set by the user for this specific display and is not guaranteed to be a
|
||||
/// supported DPI value.
|
||||
/// </summary>
|
||||
RawDpi = 2
|
||||
}
|
||||
}
|
30
GreenshotPlugin/Core/Enums/MonitorFrom.cs
Normal file
30
GreenshotPlugin/Core/Enums/MonitorFrom.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) Dapplo and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
using System;
|
||||
|
||||
namespace GreenshotPlugin.Core.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// Flags for the MonitorFromRect / MonitorFromWindow "flags" field
|
||||
/// see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd145063(v=vs.85).aspx">MonitorFromRect function</a>
|
||||
/// or see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd145064(v=vs.85).aspx">MonitorFromWindow function</a>
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum MonitorFrom : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a handle to the display monitor that is nearest to the rectangle.
|
||||
/// </summary>
|
||||
DefaultToNearest = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Returns NULL. (why??)
|
||||
/// </summary>
|
||||
DefaultToNull = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Returns a handle to the primary display monitor.
|
||||
/// </summary>
|
||||
DefaultToPrimary = 2
|
||||
}
|
||||
}
|
1390
GreenshotPlugin/Core/Enums/SystemParametersInfoActions.cs
Normal file
1390
GreenshotPlugin/Core/Enums/SystemParametersInfoActions.cs
Normal file
File diff suppressed because it is too large
Load diff
28
GreenshotPlugin/Core/Enums/SystemParametersInfoBehaviors.cs
Normal file
28
GreenshotPlugin/Core/Enums/SystemParametersInfoBehaviors.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) Dapplo and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace GreenshotPlugin.Core.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// If a system parameter is being set, specifies whether the user profile is to be updated, and if so, whether the
|
||||
/// WM_SETTINGCHANGE message is to be broadcast to all top-level windows to notify them of the change.
|
||||
/// This parameter can be zero if you do not want to update the user profile or broadcast the WM_SETTINGCHANGE message,
|
||||
/// or it can be one or more of the following values.
|
||||
/// </summary>
|
||||
public enum SystemParametersInfoBehaviors : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// Do nothing
|
||||
/// </summary>
|
||||
None = 0x00,
|
||||
|
||||
/// <summary>Writes the new system-wide parameter setting to the user profile.</summary>
|
||||
UpdateIniFile = 0x01,
|
||||
|
||||
/// <summary>Broadcasts the WM_SETTINGCHANGE message after updating the user profile.</summary>
|
||||
SendChange = 0x02,
|
||||
|
||||
/// <summary>Same as SPIF_SENDCHANGE.</summary>
|
||||
SendWinIniChange = SendChange
|
||||
}
|
||||
}
|
|
@ -17,10 +17,11 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using GreenshotPlugin.Core.Enums;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace GreenshotWin10Plugin.Native
|
||||
namespace GreenshotPlugin.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Extensions to handle the HResult
|
||||
|
@ -55,7 +56,7 @@ namespace GreenshotWin10Plugin.Native
|
|||
/// <param name="hResult">HResult</param>
|
||||
public static void ThrowOnFailure(this HResult hResult)
|
||||
{
|
||||
if (Failed(hResult))
|
||||
if (hResult.Failed())
|
||||
{
|
||||
throw Marshal.GetExceptionForHR((int)hResult);
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
*
|
||||
* For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -1203,7 +1203,7 @@ namespace GreenshotPlugin.Core {
|
|||
public static Image Adjust(Image sourceImage, float brightness, float contrast, float gamma)
|
||||
{
|
||||
//create a blank bitmap the same size as original
|
||||
// If using 8bpp than the following exception comes: A Graphics object cannot be created from an image that has an indexed pixel format.
|
||||
// If using 8bpp than the following exception comes: A Graphics object cannot be created from an image that has an indexed pixel format.
|
||||
Bitmap newBitmap = CreateEmpty(sourceImage.Width, sourceImage.Height, PixelFormat.Format24bppRgb, Color.Empty, sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
|
||||
using (ImageAttributes adjustAttributes = CreateAdjustAttributes(brightness, contrast, gamma))
|
||||
{
|
||||
|
@ -1306,7 +1306,7 @@ namespace GreenshotPlugin.Core {
|
|||
sourceRect.Intersect(bitmapRect);
|
||||
}
|
||||
|
||||
// If no pixelformat is supplied
|
||||
// If no pixelformat is supplied
|
||||
if (PixelFormat.DontCare == targetFormat || PixelFormat.Undefined == targetFormat)
|
||||
{
|
||||
if (SupportsPixelFormat(sourceImage.PixelFormat))
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
* For more information see: http://getgreenshot.org/
|
||||
* The Greenshot project is hosted on GitHub: https://github.com/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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace GreenshotPlugin.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Extensions to help with querying the Operating System
|
||||
/// </summary>
|
||||
public static class OperatingSystemExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows 10
|
||||
/// </summary>
|
||||
/// <param name="operatingSystem">OperatingSystem from Environment.OSVersion</param>
|
||||
/// <returns>true if we are running on Windows 10</returns>
|
||||
public static bool IsWindows10(this OperatingSystem operatingSystem)
|
||||
{
|
||||
return operatingSystem.Version.Major == 10;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows 10 or later
|
||||
/// </summary>
|
||||
/// <param name="operatingSystem">OperatingSystem from Environment.OSVersion</param>
|
||||
/// <returns>true if we are running on Windows 10 or later</returns>
|
||||
public static bool IsWindows10OrLater(this OperatingSystem operatingSystem)
|
||||
{
|
||||
return operatingSystem.Version.Major >= 10;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows 8(.1)
|
||||
/// </summary>
|
||||
/// <param name="operatingSystem">OperatingSystem from Environment.OSVersion</param>
|
||||
/// <returns>true if we are running on Windows 8(.1)</returns>
|
||||
public static bool IsWindows8(this OperatingSystem operatingSystem)
|
||||
{
|
||||
return operatingSystem.Version.Major == 6 && operatingSystem.Version.Minor >= 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows 8 or later
|
||||
/// </summary>
|
||||
/// <param name="operatingSystem">OperatingSystem from Environment.OSVersion</param>
|
||||
/// <returns>true if we are running on Windows 8 or later</returns>
|
||||
public static bool IsWindows8OrLater(this OperatingSystem operatingSystem)
|
||||
{
|
||||
return (operatingSystem.Version.Major == 6 && operatingSystem.Version.Minor >= 2) || operatingSystem.Version.Major > 6;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows 7 or later
|
||||
/// </summary>
|
||||
/// <param name="operatingSystem">OperatingSystem from Environment.OSVersion</param>
|
||||
/// <returns>true if we are running on Windows 7 or later</returns>
|
||||
public static bool IsWindows7OrLater(this OperatingSystem operatingSystem)
|
||||
{
|
||||
return (operatingSystem.Version.Major == 6 && operatingSystem.Version.Minor >= 1) || operatingSystem.Version.Major > 6;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows Vista or later
|
||||
/// </summary>
|
||||
/// <param name="operatingSystem">OperatingSystem from Environment.OSVersion</param>
|
||||
/// <returns>true if we are running on Windows Vista or later</returns>
|
||||
public static bool IsWindowsVistaOrLater(this OperatingSystem operatingSystem)
|
||||
{
|
||||
return operatingSystem.Version.Major >= 6;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows XP or later
|
||||
/// </summary>
|
||||
/// <param name="operatingSystem">OperatingSystem from Environment.OSVersion</param>
|
||||
/// <returns>true if we are running on Windows XP or later</returns>
|
||||
public static bool IsWindowsXpOrLater(this OperatingSystem operatingSystem)
|
||||
{
|
||||
// Windows 2000 is Major 5 minor 0
|
||||
return Environment.OSVersion.Version.Major > 5 || (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
*
|
||||
* For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -145,7 +145,7 @@ namespace GreenshotPlugin.Core {
|
|||
private static readonly IList<IntPtr> IgnoreHandles = new List<IntPtr>();
|
||||
private static readonly IList<string> ExcludeProcessesFromFreeze = new List<string>();
|
||||
private static readonly IAppVisibility AppVisibility;
|
||||
|
||||
|
||||
static WindowDetails() {
|
||||
try
|
||||
{
|
||||
|
@ -212,7 +212,7 @@ namespace GreenshotPlugin.Core {
|
|||
public override int GetHashCode() {
|
||||
return Handle.ToInt32();
|
||||
}
|
||||
|
||||
|
||||
public override bool Equals(object right) {
|
||||
return Equals(right as WindowDetails);
|
||||
}
|
||||
|
@ -226,11 +226,11 @@ namespace GreenshotPlugin.Core {
|
|||
if (other is null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (ReferenceEquals(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (GetType() != other.GetType()){
|
||||
return false;
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ namespace GreenshotPlugin.Core {
|
|||
private static IEnumerable<WindowDetails> FindWindow(IList<WindowDetails> windows, string titlePattern, string classnamePattern) {
|
||||
Regex titleRegexp = null;
|
||||
Regex classnameRegexp = null;
|
||||
|
||||
|
||||
if (titlePattern != null && titlePattern.Trim().Length > 0) {
|
||||
titleRegexp = new Regex(titlePattern);
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the child with matching classname
|
||||
/// </summary>
|
||||
|
@ -486,7 +486,7 @@ namespace GreenshotPlugin.Core {
|
|||
public IEnumerable<WindowDetails> FindChildren(string titlePattern, string classnamePattern) {
|
||||
return FindWindow(Children, titlePattern, classnamePattern);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Recursing helper method for the FindPath
|
||||
/// </summary>
|
||||
|
@ -620,7 +620,7 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets whether the window is maximised or not.
|
||||
/// </summary>
|
||||
|
@ -650,14 +650,14 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This doesn't work as good as is should, but does move the App out of the way...
|
||||
/// </summary>
|
||||
public void HideApp() {
|
||||
User32.ShowWindow(Handle, ShowWindowCommand.Hide);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the window is visible.
|
||||
/// </summary>
|
||||
|
@ -697,7 +697,7 @@ namespace GreenshotPlugin.Core {
|
|||
return User32.IsWindowVisible(Handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool HasParent {
|
||||
get {
|
||||
GetParent();
|
||||
|
@ -757,7 +757,7 @@ namespace GreenshotPlugin.Core {
|
|||
_lastWindowRectangleRetrieveTime = now;
|
||||
}
|
||||
}
|
||||
if (gotFrameBounds && Environment.OSVersion.IsWindows10() && !Maximised)
|
||||
if (gotFrameBounds && WindowsVersion.IsWindows10OrLater && !Maximised)
|
||||
{
|
||||
// Somehow DWM doesn't calculate it corectly, there is a 1 pixel border around the capture
|
||||
// Remove this border, currently it's fixed but TODO: Make it depend on the OS?
|
||||
|
@ -775,7 +775,7 @@ namespace GreenshotPlugin.Core {
|
|||
Log.WarnFormat("Couldn't retrieve the windows rectangle: {0}", Win32.GetMessage(error));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Correction for maximized windows, only if it's not an app
|
||||
if (!HasParent && !IsApp && Maximised) {
|
||||
// Only if the border size can be retrieved
|
||||
|
@ -816,7 +816,7 @@ namespace GreenshotPlugin.Core {
|
|||
return new Size(tmpRectangle.Right - tmpRectangle.Left, tmpRectangle.Bottom - tmpRectangle.Top);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the client rectangle, this is the part of the window inside the borders (drawable area)
|
||||
/// </summary>
|
||||
|
@ -841,7 +841,7 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores and Brings the window to the front,
|
||||
/// Restores and Brings the window to the front,
|
||||
/// assuming it is a visible application window.
|
||||
/// </summary>
|
||||
public void Restore() {
|
||||
|
@ -969,7 +969,7 @@ namespace GreenshotPlugin.Core {
|
|||
} else {
|
||||
doesCaptureFit = true;
|
||||
}
|
||||
} else if (!Environment.OSVersion.IsWindows8OrLater()) {
|
||||
} else if (!WindowsVersion.IsWindows8OrLater) {
|
||||
//GetClientRect(out windowRectangle);
|
||||
GetBorderSize(out borderSize);
|
||||
formLocation = new Point(windowRectangle.X - borderSize.Width, windowRectangle.Y - borderSize.Height);
|
||||
|
@ -986,7 +986,7 @@ namespace GreenshotPlugin.Core {
|
|||
captureRectangle.Inflate(borderSize.Width, borderSize.Height);
|
||||
} else {
|
||||
// TODO: Also 8.x?
|
||||
if (Environment.OSVersion.IsWindows10())
|
||||
if (WindowsVersion.IsWindows10OrLater)
|
||||
{
|
||||
captureRectangle.Inflate(Conf.Win10BorderCrop);
|
||||
}
|
||||
|
@ -1017,7 +1017,7 @@ namespace GreenshotPlugin.Core {
|
|||
|
||||
// Intersect with screen
|
||||
captureRectangle.Intersect(capture.ScreenBounds);
|
||||
|
||||
|
||||
// Destination bitmap for the capture
|
||||
Bitmap capturedBitmap = null;
|
||||
bool frozen = false;
|
||||
|
@ -1064,7 +1064,7 @@ namespace GreenshotPlugin.Core {
|
|||
Color colorizationColor = DWM.ColorizationColor;
|
||||
// Modify by losing the transparency and increasing the intensity (as if the background color is white)
|
||||
colorizationColor = Color.FromArgb(255, (colorizationColor.R + 255) >> 1, (colorizationColor.G + 255) >> 1, (colorizationColor.B + 255) >> 1);
|
||||
tempForm.BackColor = colorizationColor;
|
||||
tempForm.BackColor = colorizationColor;
|
||||
}
|
||||
// Make sure everything is visible
|
||||
tempForm.Refresh();
|
||||
|
@ -1079,7 +1079,7 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
if (capturedBitmap != null) {
|
||||
// Not needed for Windows 8
|
||||
if (!Environment.OSVersion.IsWindows8OrLater()) {
|
||||
if (!WindowsVersion.IsWindows8OrLater) {
|
||||
// Only if the Inivalue is set, not maximized and it's not a tool window.
|
||||
if (Conf.WindowCaptureRemoveCorners && !Maximised && (ExtendedWindowStyle & ExtendedWindowStyleFlags.WS_EX_TOOLWINDOW) == 0) {
|
||||
// Remove corners
|
||||
|
@ -1099,7 +1099,7 @@ namespace GreenshotPlugin.Core {
|
|||
UnfreezeWindow();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
capture.Image = capturedBitmap;
|
||||
// Make sure the capture location is the location of the window, not the copy
|
||||
capture.Location = Location;
|
||||
|
@ -1181,7 +1181,7 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
return targetBuffer.UnlockAndReturnBitmap();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to get the window size for DWM Windows
|
||||
/// </summary>
|
||||
|
@ -1201,7 +1201,7 @@ namespace GreenshotPlugin.Core {
|
|||
/// Helper method to get the window size for GDI Windows
|
||||
/// </summary>
|
||||
/// <param name="rectangle">out Rectangle</param>
|
||||
/// <returns>bool true if it worked</returns>
|
||||
/// <returns>bool true if it worked</returns>
|
||||
private bool GetClientRect(out Rectangle rectangle) {
|
||||
var windowInfo = new WindowInfo();
|
||||
// Get the Window Info for this window
|
||||
|
@ -1209,12 +1209,12 @@ namespace GreenshotPlugin.Core {
|
|||
rectangle = result ? windowInfo.rcClient.ToRectangle() : Rectangle.Empty;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to get the window size for GDI Windows
|
||||
/// </summary>
|
||||
/// <param name="rectangle">out Rectangle</param>
|
||||
/// <returns>bool true if it worked</returns>
|
||||
/// <returns>bool true if it worked</returns>
|
||||
private bool GetWindowRect(out Rectangle rectangle) {
|
||||
var windowInfo = new WindowInfo();
|
||||
// Get the Window Info for this window
|
||||
|
@ -1227,7 +1227,7 @@ namespace GreenshotPlugin.Core {
|
|||
/// Helper method to get the Border size for GDI Windows
|
||||
/// </summary>
|
||||
/// <param name="size">out Size</param>
|
||||
/// <returns>bool true if it worked</returns>
|
||||
/// <returns>bool true if it worked</returns>
|
||||
private bool GetBorderSize(out Size size) {
|
||||
var windowInfo = new WindowInfo();
|
||||
// Get the Window Info for this window
|
||||
|
@ -1280,7 +1280,7 @@ namespace GreenshotPlugin.Core {
|
|||
public void ToForeground(bool workaround = true) {
|
||||
ToForeground(Handle, workaround);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the region for a window
|
||||
/// </summary>
|
||||
|
@ -1295,7 +1295,7 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private bool CanFreezeOrUnfreeze(string titleOrProcessname) {
|
||||
if (string.IsNullOrEmpty(titleOrProcessname)) {
|
||||
return false;
|
||||
|
@ -1397,13 +1397,13 @@ namespace GreenshotPlugin.Core {
|
|||
exceptionOccured = User32.CreateWin32Exception("PrintWindow");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Apply the region "transparency"
|
||||
if (region != null && !region.IsEmpty(graphics)) {
|
||||
graphics.ExcludeClip(region);
|
||||
graphics.Clear(Color.Transparent);
|
||||
}
|
||||
|
||||
|
||||
graphics.Flush();
|
||||
}
|
||||
|
||||
|
@ -1421,7 +1421,7 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
return returnImage;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance of this class for
|
||||
/// the specified Window Handle.
|
||||
|
@ -1430,7 +1430,7 @@ namespace GreenshotPlugin.Core {
|
|||
public WindowDetails(IntPtr hWnd) {
|
||||
Handle = hWnd;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets an instance of the current active foreground window
|
||||
/// </summary>
|
||||
|
@ -1451,7 +1451,7 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check if this window is Greenshot
|
||||
/// </summary>
|
||||
|
@ -1469,7 +1469,7 @@ namespace GreenshotPlugin.Core {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Desktop window
|
||||
/// </summary>
|
||||
|
@ -1477,7 +1477,7 @@ namespace GreenshotPlugin.Core {
|
|||
public static WindowDetails GetDesktopWindow() {
|
||||
return new WindowDetails(User32.GetDesktopWindow());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get all the top level windows
|
||||
/// </summary>
|
||||
|
@ -1715,7 +1715,7 @@ namespace GreenshotPlugin.Core {
|
|||
if (window.Iconic) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Windows without size
|
||||
Size windowSize = window.WindowRectangle.Size;
|
||||
if (windowSize.Width == 0 || windowSize.Height == 0) {
|
||||
|
@ -1744,7 +1744,7 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the AppLauncher
|
||||
/// </summary>
|
||||
|
@ -1760,7 +1760,7 @@ namespace GreenshotPlugin.Core {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Return true if the metro-app-launcher is visible
|
||||
/// </summary>
|
||||
|
|
107
GreenshotPlugin/Core/WindowsVersion.cs
Normal file
107
GreenshotPlugin/Core/WindowsVersion.cs
Normal file
|
@ -0,0 +1,107 @@
|
|||
// Copyright (c) Dapplo and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace GreenshotPlugin.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to test the windows version
|
||||
/// </summary>
|
||||
public static class WindowsVersion
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the current windows version
|
||||
/// </summary>
|
||||
public static Version WinVersion { get; } = Environment.OSVersion.Version;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows 10
|
||||
/// </summary>
|
||||
/// <returns>true if we are running on Windows 10</returns>
|
||||
public static bool IsWindows10 { get; } = WinVersion.Major == 10;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows 10 or later
|
||||
/// </summary>
|
||||
/// <returns>true if we are running on Windows 10 or later</returns>
|
||||
public static bool IsWindows10OrLater { get; } = WinVersion.Major >= 10;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows 7 or later
|
||||
/// </summary>
|
||||
/// <returns>true if we are running on Windows 7 or later</returns>
|
||||
public static bool IsWindows7OrLater { get; } = WinVersion.Major == 6 && WinVersion.Minor >= 1 || WinVersion.Major > 6;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows 8.0
|
||||
/// </summary>
|
||||
/// <returns>true if we are running on Windows 8.0</returns>
|
||||
public static bool IsWindows8 { get; } = WinVersion.Major == 6 && WinVersion.Minor == 2;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows 8(.1)
|
||||
/// </summary>
|
||||
/// <returns>true if we are running on Windows 8(.1)</returns>
|
||||
public static bool IsWindows81 { get; } = WinVersion.Major == 6 && WinVersion.Minor == 3;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows 8.0 or 8.1
|
||||
/// </summary>
|
||||
/// <returns>true if we are running on Windows 8.1 or 8.0</returns>
|
||||
public static bool IsWindows8X { get; } = IsWindows8 || IsWindows81;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows 8.1 or later
|
||||
/// </summary>
|
||||
/// <returns>true if we are running on Windows 8.1 or later</returns>
|
||||
public static bool IsWindows81OrLater { get; } = WinVersion.Major == 6 && WinVersion.Minor >= 3 || WinVersion.Major > 6;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows 8 or later
|
||||
/// </summary>
|
||||
/// <returns>true if we are running on Windows 8 or later</returns>
|
||||
public static bool IsWindows8OrLater { get; } = WinVersion.Major == 6 && WinVersion.Minor >= 2 || WinVersion.Major > 6;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows Vista
|
||||
/// </summary>
|
||||
/// <returns>true if we are running on Windows Vista or later</returns>
|
||||
public static bool IsWindowsVista { get; } = WinVersion.Major >= 6 && WinVersion.Minor == 0;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows Vista or later
|
||||
/// </summary>
|
||||
/// <returns>true if we are running on Windows Vista or later</returns>
|
||||
public static bool IsWindowsVistaOrLater { get; } = WinVersion.Major >= 6;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is from before Windows Vista (e.g. Windows XP)
|
||||
/// </summary>
|
||||
/// <returns>true if we are running on Windows from before Vista</returns>
|
||||
public static bool IsWindowsBeforeVista { get; } = WinVersion.Major < 6;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows XP
|
||||
/// </summary>
|
||||
/// <returns>true if we are running on Windows XP or later</returns>
|
||||
public static bool IsWindowsXp { get; } = WinVersion.Major == 5 && WinVersion.Minor >= 1;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current OS is Windows XP or later
|
||||
/// </summary>
|
||||
/// <returns>true if we are running on Windows XP or later</returns>
|
||||
public static bool IsWindowsXpOrLater { get; } = WinVersion.Major >= 5 || WinVersion.Major == 5 && WinVersion.Minor >= 1;
|
||||
|
||||
/// <summary>
|
||||
/// Test if the current Windows version is 10 and the build number or later
|
||||
/// See the build numbers <a href="https://en.wikipedia.org/wiki/Windows_10_version_history">here</a>
|
||||
/// </summary>
|
||||
/// <param name="minimalBuildNumber">int</param>
|
||||
/// <returns>bool</returns>
|
||||
public static bool IsWindows10BuildOrLater(int minimalBuildNumber)
|
||||
{
|
||||
return IsWindows10 && WinVersion.Build >= minimalBuildNumber;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
*
|
||||
* For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -25,12 +25,12 @@ using System.Text;
|
|||
|
||||
namespace Greenshot.IniFile {
|
||||
/// <summary>
|
||||
///
|
||||
/// The IniReader does exactly what it says, it reads the .ini file
|
||||
/// </summary>
|
||||
public static class IniReader {
|
||||
private const string SectionStart = "[";
|
||||
private const string SectionEnd = "]";
|
||||
private const string Comment = ";";
|
||||
private const char SectionStartToken = '[';
|
||||
private const char SectionEndToken = ']';
|
||||
private const char CommentToken = ';';
|
||||
private static readonly char[] Assignment = { '=' };
|
||||
|
||||
/// <summary>
|
||||
|
@ -52,11 +52,16 @@ namespace Greenshot.IniFile {
|
|||
continue;
|
||||
}
|
||||
string cleanLine = line.Trim();
|
||||
if (cleanLine.Length == 0 || cleanLine.StartsWith(Comment)) {
|
||||
if (cleanLine.Length == 0 || cleanLine[0] == CommentToken) {
|
||||
continue;
|
||||
}
|
||||
if (cleanLine.StartsWith(SectionStart)) {
|
||||
string section = line.Replace(SectionStart, string.Empty).Replace(SectionEnd, string.Empty).Trim();
|
||||
if (cleanLine[0] == SectionStartToken) {
|
||||
var sectionEndIndex = line.IndexOf(SectionEndToken,1);
|
||||
if (sectionEndIndex <0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string section = line.Substring(1,sectionEndIndex-1).Trim();
|
||||
if (!ini.TryGetValue(section, out nameValues))
|
||||
{
|
||||
nameValues = new Dictionary<string, string>();
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
*
|
||||
* For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -155,7 +155,7 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
|||
// Cleanup
|
||||
User32.DestroyIcon(shfi.hIcon);
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an icon representation of an image contained in the specified file.
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Greenshot - a free and open source screenshot tool
|
||||
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
|
||||
*
|
||||
*
|
||||
* For more information see: http://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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -30,6 +30,7 @@ using Microsoft.Win32.SafeHandles;
|
|||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using log4net;
|
||||
using GreenshotPlugin.Core.Enums;
|
||||
|
||||
namespace GreenshotPlugin.UnmanagedHelpers {
|
||||
/// <summary>
|
||||
|
@ -53,7 +54,7 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
|||
|
||||
public const int PW_DEFAULT = 0x00;
|
||||
public const int PW_CLIENTONLY = 0x01;
|
||||
|
||||
|
||||
// For MonitorFromWindow
|
||||
public const int MONITOR_DEFAULTTONULL = 0;
|
||||
public const int MONITOR_DEFAULTTOPRIMARY = 1;
|
||||
|
@ -62,6 +63,19 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
|||
|
||||
[DllImport("user32", SetLastError = true)]
|
||||
public static extern bool keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified window handle identifies an existing window.
|
||||
/// </summary>
|
||||
/// <param name="hWnd">A handle to the window to be tested.</param>
|
||||
/// <returns>
|
||||
/// If the window handle identifies an existing window, the return value is true.
|
||||
/// If the window handle does not identify an existing window, the return value is false.
|
||||
/// </returns>
|
||||
[DllImport("user32", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool IsWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool IsWindowVisible(IntPtr hWnd);
|
||||
|
@ -125,7 +139,7 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
|||
[DllImport("user32", SetLastError = true, EntryPoint = "SetWindowLongPtr")]
|
||||
public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int index, IntPtr styleFlags);
|
||||
[DllImport("user32", SetLastError = true)]
|
||||
public static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);
|
||||
public static extern IntPtr MonitorFromWindow(IntPtr hwnd, MonitorFrom dwFlags);
|
||||
[DllImport("user32", SetLastError = true)]
|
||||
public static extern IntPtr MonitorFromRect([In] ref RECT lprc, uint dwFlags);
|
||||
[DllImport("user32", SetLastError = true)]
|
||||
|
@ -224,8 +238,18 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
|||
[DllImport("user32", SetLastError = true)]
|
||||
public static extern bool CloseDesktop(IntPtr hDesktop);
|
||||
|
||||
/// <summary>
|
||||
/// The GetWindowDC function retrieves the device context (DC) for the entire window, including title bar, menus, and scroll bars. A window device context permits painting anywhere in a window, because the origin of the device context is the upper-left corner of the window instead of the client area.
|
||||
/// GetWindowDC assigns default attributes to the window device context each time it retrieves the device context.Previous attributes are lost.
|
||||
/// See <a href="https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getwindowdc">GetWindowDC function</a>
|
||||
/// </summary>
|
||||
/// <param name="hWnd">A handle to the window whose DC is to be retrieved. If this value is NULL, GetWindowDC retrieves the DC for the entire screen.</param>
|
||||
/// <returns>If the function succeeds, the return value is a handle to a device context for the specified window.</returns>
|
||||
[DllImport("user32", SetLastError = true)]
|
||||
public static extern IntPtr GetWindowDC(IntPtr hWnd);
|
||||
|
||||
/// <summary>
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the cursor location safely, accounting for DPI settings in Vista/Windows 7.
|
||||
/// </summary>
|
||||
/// <returns>Point with cursor location, relative to the origin of the monitor setup
|
||||
|
@ -407,6 +431,21 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
|||
return returnValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a DC as SafeWindowDcHandle for the whole of the specified hWnd
|
||||
/// </summary>
|
||||
/// <param name="hWnd">IntPtr</param>
|
||||
/// <returns>SafeWindowDcHandle</returns>
|
||||
public static SafeWindowDcHandle FromWindow(IntPtr hWnd)
|
||||
{
|
||||
if (hWnd == IntPtr.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var hDcDesktop = GetWindowDC(hWnd);
|
||||
return new SafeWindowDcHandle(hWnd, hDcDesktop);
|
||||
}
|
||||
|
||||
public static SafeWindowDcHandle FromDesktop() {
|
||||
IntPtr hWndDesktop = User32.GetDesktopWindow();
|
||||
IntPtr hDCDesktop = GetWindowDC(hWndDesktop);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using GreenshotPlugin.Core;
|
||||
using System;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
|
|
|
@ -17,18 +17,19 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using GreenshotPlugin.Core.Enums;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
|
||||
namespace GreenshotWin10Plugin.Native
|
||||
{
|
||||
/// <summary>
|
||||
/// The IDataTransferManagerInterOp is documented here: https://msdn.microsoft.com/en-us/library/windows/desktop/jj542488(v=vs.85).aspx.
|
||||
/// This interface allows an app to tie the share context to a specific
|
||||
/// window using a window handle. Useful for Win32 apps.
|
||||
/// </summary>
|
||||
[ComImport, Guid("3A3DCD6C-3EAB-43DC-BCDE-45671CE800C8")]
|
||||
/// <summary>
|
||||
/// The IDataTransferManagerInterOp is documented here: https://msdn.microsoft.com/en-us/library/windows/desktop/jj542488(v=vs.85).aspx.
|
||||
/// This interface allows an app to tie the share context to a specific
|
||||
/// window using a window handle. Useful for Win32 apps.
|
||||
/// </summary>
|
||||
[ComImport, Guid("3A3DCD6C-3EAB-43DC-BCDE-45671CE800C8")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface IDataTransferManagerInterOp
|
||||
{
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace GreenshotWin10Plugin
|
|||
/// <returns>IEnumerable with the destinations</returns>
|
||||
public IEnumerable<IDestination> Destinations()
|
||||
{
|
||||
if (!Environment.OSVersion.IsWindows10OrLater())
|
||||
if (!WindowsVersion.IsWindows10OrLater)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue