Skip to content

Commit

Permalink
Refactoring to use Dapplo.Windows (greenshot#398)
Browse files Browse the repository at this point in the history
* Removed a LOT of the native "Win32" invokes in favor of Dapplo.Windows which was created mainly for Greenshot.
* Changed all usages of Point, Rectangle, RectangleF, Size to the Native versions of those from Dapplo.Windows.Common.
* Small fix for the OCR text feature.
  • Loading branch information
Lakritzator authored Apr 13, 2022
1 parent 8aca1c8 commit 13e2e67
Show file tree
Hide file tree
Showing 159 changed files with 1,643 additions and 6,557 deletions.
47 changes: 27 additions & 20 deletions src/Greenshot.Base/Controls/GreenshotForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,20 @@ protected bool ManualStoreFields
/// </summary>
protected bool ToFront { get; set; }

protected GreenshotForm()
{
DpiChanged += (sender, dpiChangedEventArgs) => DpiChangedHandler(dpiChangedEventArgs.DeviceDpiOld, dpiChangedEventArgs.DeviceDpiNew);
}

/// <summary>
/// This is the basic DpiChangedHandler responsible for all the DPI relative changes
/// </summary>
/// <param name="oldDpi"></param>
/// <param name="newDpi"></param>
protected virtual void DpiChangedHandler(int oldDpi, int newDpi)
{
}

#if DEBUG
/// <summary>
/// Code to initialize the language etc during design time
Expand Down Expand Up @@ -382,10 +396,10 @@ protected void ApplyLanguage(ToolStripItem applyTo)

protected void ApplyLanguage(Control applyTo)
{
if (!(applyTo is IGreenshotLanguageBindable languageBindable))
if (applyTo is not IGreenshotLanguageBindable languageBindable)
{
// check if it's a menu!
if (!(applyTo is ToolStrip toolStrip))
if (applyTo is not ToolStrip toolStrip)
{
return;
}
Expand All @@ -402,20 +416,14 @@ protected void ApplyLanguage(Control applyTo)
ApplyLanguage(applyTo, languageBindable.LanguageKey);

// Repopulate the combox boxes
if (applyTo is IGreenshotConfigBindable configBindable && applyTo is GreenshotComboBox comboxBox)
{
if (!string.IsNullOrEmpty(configBindable.SectionName) && !string.IsNullOrEmpty(configBindable.PropertyName))
{
IniSection section = IniConfig.GetIniSection(configBindable.SectionName);
if (section != null)
{
// Only update the language, so get the actual value and than repopulate
Enum currentValue = comboxBox.GetSelectedEnum();
comboxBox.Populate(section.Values[configBindable.PropertyName].ValueType);
comboxBox.SetValue(currentValue);
}
}
}
if (applyTo is not (IGreenshotConfigBindable configBindable and GreenshotComboBox comboxBox)) return;
if (string.IsNullOrEmpty(configBindable.SectionName) || string.IsNullOrEmpty(configBindable.PropertyName)) return;
IniSection section = IniConfig.GetIniSection(configBindable.SectionName);
if (section == null) return;
// Only update the language, so get the actual value and than repopulate
Enum currentValue = comboxBox.GetSelectedEnum();
comboxBox.Populate(section.Values[configBindable.PropertyName].ValueType);
comboxBox.SetValue(currentValue);
}

/// <summary>
Expand Down Expand Up @@ -458,10 +466,9 @@ protected void ApplyLanguage()
continue;
}

if (!(controlObject is Control applyToControl))
if (controlObject is not Control applyToControl)
{
ToolStripItem applyToItem = controlObject as ToolStripItem;
if (applyToItem == null)
if (controlObject is not ToolStripItem applyToItem)
{
LOG.DebugFormat("No Control or ToolStripItem: {0}", field.Name);
continue;
Expand Down Expand Up @@ -530,7 +537,7 @@ protected void ApplyLanguage(Control applyTo, string languageKey)
/// <summary>
/// Fill all GreenshotControls with the values from the configuration
/// </summary>
protected void FillFields()
private void FillFields()
{
foreach (FieldInfo field in GetCachedFields(GetType()))
{
Expand Down
31 changes: 17 additions & 14 deletions src/Greenshot.Base/Controls/ThumbnailForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using Dapplo.Windows.Common.Extensions;
using Dapplo.Windows.Common.Structs;
using Dapplo.Windows.DesktopWindowsManager;
using Dapplo.Windows.DesktopWindowsManager.Structs;
using Dapplo.Windows.User32;
using Dapplo.Windows.User32.Enums;
using Greenshot.Base.Core;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.IniFile;
using Greenshot.Base.UnmanagedHelpers;
using Greenshot.Base.UnmanagedHelpers.Enums;
using Greenshot.Base.UnmanagedHelpers.Structs;

namespace Greenshot.Base.Controls
{
Expand Down Expand Up @@ -70,7 +73,7 @@ private void UnregisterThumbnail()
{
if (_thumbnailHandle == IntPtr.Zero) return;

DWM.DwmUnregisterThumbnail(_thumbnailHandle);
DwmApi.DwmUnregisterThumbnail(_thumbnailHandle);
_thumbnailHandle = IntPtr.Zero;
}

Expand All @@ -83,19 +86,19 @@ public void ShowThumbnail(WindowDetails window, Control parentControl)
{
UnregisterThumbnail();

DWM.DwmRegisterThumbnail(Handle, window.Handle, out _thumbnailHandle);
DwmApi.DwmRegisterThumbnail(Handle, window.Handle, out _thumbnailHandle);
if (_thumbnailHandle == IntPtr.Zero) return;

var result = DWM.DwmQueryThumbnailSourceSize(_thumbnailHandle, out var sourceSize);
var result = DwmApi.DwmQueryThumbnailSourceSize(_thumbnailHandle, out var sourceSize);
if (result.Failed())
{
DWM.DwmUnregisterThumbnail(_thumbnailHandle);
DwmApi.DwmUnregisterThumbnail(_thumbnailHandle);
return;
}

if (sourceSize.IsEmpty)
{
DWM.DwmUnregisterThumbnail(_thumbnailHandle);
DwmApi.DwmUnregisterThumbnail(_thumbnailHandle);
return;
}

Expand All @@ -110,17 +113,17 @@ public void ShowThumbnail(WindowDetails window, Control parentControl)
Width = thumbnailWidth;
Height = thumbnailHeight;
// Prepare the displaying of the Thumbnail
var dwmThumbnailProperties = new DWM_THUMBNAIL_PROPERTIES
var dwmThumbnailProperties = new DwmThumbnailProperties()
{
Opacity = 255,
Visible = true,
SourceClientAreaOnly = false,
Destination = new RECT(0, 0, thumbnailWidth, thumbnailHeight)
Destination = new NativeRect(0, 0, thumbnailWidth, thumbnailHeight)
};
result = DWM.DwmUpdateThumbnailProperties(_thumbnailHandle, ref dwmThumbnailProperties);
result = DwmApi.DwmUpdateThumbnailProperties(_thumbnailHandle, ref dwmThumbnailProperties);
if (result.Failed())
{
DWM.DwmUnregisterThumbnail(_thumbnailHandle);
DwmApi.DwmUnregisterThumbnail(_thumbnailHandle);
return;
}

Expand All @@ -137,13 +140,13 @@ public void ShowThumbnail(WindowDetails window, Control parentControl)
// Make sure it's on "top"!
if (parentControl != null)
{
User32.SetWindowPos(Handle, parentControl.Handle, 0, 0, 0, 0, WindowPos.SWP_NOMOVE | WindowPos.SWP_NOSIZE | WindowPos.SWP_NOACTIVATE);
User32Api.SetWindowPos(Handle, parentControl.Handle, 0, 0, 0, 0, WindowPos.SWP_NOMOVE | WindowPos.SWP_NOSIZE | WindowPos.SWP_NOACTIVATE);
}
}

public void AlignToControl(Control alignTo)
{
var screenBounds = WindowCapture.GetScreenBounds();
var screenBounds = DisplayInfo.ScreenBounds;
if (screenBounds.Contains(alignTo.Left, alignTo.Top - Height))
{
Location = new Point(alignTo.Left + (alignTo.Width / 2) - (Width / 2), alignTo.Top - Height);
Expand Down
31 changes: 17 additions & 14 deletions src/Greenshot.Base/Core/AbstractDestination.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,18 @@
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using Dapplo.Windows.Common.Extensions;
using Dapplo.Windows.Common.Structs;
using Dapplo.Windows.Dpi;
using Dapplo.Windows.User32;
using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces;
using Greenshot.Base.UnmanagedHelpers;
using log4net;

namespace Greenshot.Base.Core
{
/// <summary>
/// Description of AbstractDestination.
/// The AbstractDestination is a default implementation of IDestination
/// </summary>
public abstract class AbstractDestination : IDestination
{
Expand All @@ -41,7 +44,7 @@ public abstract class AbstractDestination : IDestination

public virtual int CompareTo(object obj)
{
if (!(obj is IDestination other))
if (obj is not IDestination other)
{
return 1;
}
Expand Down Expand Up @@ -176,18 +179,18 @@ public ExportInformation ShowPickerMenu(bool addDynamics, ISurface surface, ICap
ExportInformation exportInformation = new ExportInformation(Designation, Language.GetString("settings_destination_picker"));
var menu = new ContextMenuStrip
{
ImageScalingSize = CoreConfig.ScaledIconSize,
ImageScalingSize = CoreConfig.IconSize,
Tag = null,
TopLevel = true
};

menu.Opening += (sender, args) =>
{
// find the DPI settings for the screen where this is going to land
var screenDpi = DpiHelper.GetDpi(menu.Location);
var scaledIconSize = DpiHelper.ScaleWithDpi(CoreConfig.IconSize, screenDpi);
var screenDpi = NativeDpiMethods.GetDpi(menu.Location);
var scaledIconSize = DpiCalculator.ScaleWithDpi(CoreConfig.IconSize, screenDpi);
menu.SuspendLayout();
var fontSize = DpiHelper.ScaleWithDpi(12f, screenDpi);
var fontSize = DpiCalculator.ScaleWithDpi(12f, screenDpi);
menu.Font = new Font(FontFamily.GenericSansSerif, fontSize, FontStyle.Regular, GraphicsUnit.Pixel);
menu.ImageScalingSize = scaledIconSize;
menu.ResumeLayout();
Expand Down Expand Up @@ -304,29 +307,29 @@ public ExportInformation ShowPickerMenu(bool addDynamics, ISurface surface, ICap
ShowMenuAtCursor(menu);
return exportInformation;
}

/// <summary>
/// This method will show the supplied context menu at the mouse cursor, also makes sure it has focus and it's not visible in the taskbar.
/// </summary>
/// <param name="menu"></param>
private static void ShowMenuAtCursor(ContextMenuStrip menu)
{
// find a suitable location
Point location = Cursor.Position;
Rectangle menuRectangle = new Rectangle(location, menu.Size);
NativePoint location = Cursor.Position;
var menuRectangle = new NativeRect(location, menu.Size);

menuRectangle.Intersect(WindowCapture.GetScreenBounds());
menuRectangle = menuRectangle.Intersect(DisplayInfo.ScreenBounds);
if (menuRectangle.Height < menu.Height)
{
location.Offset(-40, -(menuRectangle.Height - menu.Height));
location = location.Offset(-40, -(menuRectangle.Height - menu.Height));
}
else
{
location.Offset(-40, -10);
location = location.Offset(-40, -10);
}

// This prevents the problem that the context menu shows in the task-bar
User32.SetForegroundWindow(SimpleServiceProvider.Current.GetInstance<NotifyIcon>().ContextMenuStrip.Handle);
User32Api.SetForegroundWindow(SimpleServiceProvider.Current.GetInstance<NotifyIcon>().ContextMenuStrip.Handle);
menu.Show(location);
menu.Focus();

Expand Down
Loading

0 comments on commit 13e2e67

Please sign in to comment.