From f4a0c6fd4fa64589336df45667d9b18e4b4e79ea Mon Sep 17 00:00:00 2001
From: NaBian <836904362@qq.com>
Date: Tue, 12 May 2020 23:59:46 +0800
Subject: [PATCH] fixed #325
---
.../Themes/Styles/Window.xaml | 1 -
.../Controls/Window/GlowWindow.cs | 4 +-
.../Controls/Window/Window.cs | 96 +++++++++++++++----
.../Themes/Styles/Window.xaml | 1 -
.../Tools/Helper/WindowHelper.cs | 8 +-
.../Tools/Interop/InteropMethods.cs | 7 +-
.../Tools/Interop/InteropValues.cs | 25 ++++-
7 files changed, 112 insertions(+), 30 deletions(-)
diff --git a/src/Net_40/HandyControl_Net_40/Themes/Styles/Window.xaml b/src/Net_40/HandyControl_Net_40/Themes/Styles/Window.xaml
index a9e520ac..dc062c39 100644
--- a/src/Net_40/HandyControl_Net_40/Themes/Styles/Window.xaml
+++ b/src/Net_40/HandyControl_Net_40/Themes/Styles/Window.xaml
@@ -129,7 +129,6 @@
-
diff --git a/src/Shared/HandyControl_Shared/Controls/Window/GlowWindow.cs b/src/Shared/HandyControl_Shared/Controls/Window/GlowWindow.cs
index 490b9b67..4e31362b 100644
--- a/src/Shared/HandyControl_Shared/Controls/Window/GlowWindow.cs
+++ b/src/Shared/HandyControl_Shared/Controls/Window/GlowWindow.cs
@@ -75,7 +75,7 @@ namespace HandyControl.Controls
}
}
- protected virtual IntPtr HwndSourceHook(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
+ private IntPtr HwndSourceHook(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg <= InteropValues.WM_WINDOWPOSCHANGED)
{
@@ -167,7 +167,7 @@ namespace HandyControl.Controls
protected override void OnSourceInitialized(EventArgs e)
{
- var hwndSource = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
+ var hwndSource = this.GetHwndSource();
if (hwndSource != null)
{
hwndSource.AddHook(HwndSourceHook);
diff --git a/src/Shared/HandyControl_Shared/Controls/Window/Window.cs b/src/Shared/HandyControl_Shared/Controls/Window/Window.cs
index 932e79c8..a406243c 100644
--- a/src/Shared/HandyControl_Shared/Controls/Window/Window.cs
+++ b/src/Shared/HandyControl_Shared/Controls/Window/Window.cs
@@ -1,10 +1,13 @@
using System;
+using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using HandyControl.Data;
+using HandyControl.Tools;
using HandyControl.Tools.Extension;
+using HandyControl.Tools.Interop;
#if netle40
using Microsoft.Windows.Shell;
#else
@@ -80,6 +83,8 @@ namespace HandyControl.Controls
private Thickness _actualBorderThickness;
+ private readonly Thickness _commonPadding;
+
private bool _showNonClientArea = true;
private double _tempNonClientAreaHeight;
@@ -114,45 +119,96 @@ namespace HandyControl.Controls
};
#endif
BindingOperations.SetBinding(chrome, WindowChrome.CaptionHeightProperty,
- new Binding(NonClientAreaHeightProperty.Name) {Source = this});
+ new Binding(NonClientAreaHeightProperty.Name) { Source = this });
WindowChrome.SetWindowChrome(this, chrome);
+ _commonPadding = Padding;
- Loaded += (s, e) => OnLoaded(e);
+ Loaded += (s, e) => OnLoaded(e);
}
+ private void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
+ {
+ var mmi = (InteropValues.MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(InteropValues.MINMAXINFO));
+ var monitor = InteropMethods.MonitorFromWindow(hwnd, InteropValues.MONITOR_DEFAULTTONEAREST);
+
+ if (monitor != IntPtr.Zero && mmi != null)
+ {
+ InteropValues.APPBARDATA appBarData = default;
+ var autoHide = InteropMethods.SHAppBarMessage(4, ref appBarData) != 0;
+ if (autoHide)
+ {
+ var monitorInfo = default(InteropValues.MONITORINFO);
+ monitorInfo.cbSize = (uint)Marshal.SizeOf(typeof(InteropValues.MONITORINFO));
+ InteropMethods.GetMonitorInfo(monitor, ref monitorInfo);
+ var rcWorkArea = monitorInfo.rcWork;
+ var rcMonitorArea = monitorInfo.rcMonitor;
+ mmi.ptMaxPosition.X = Math.Abs(rcWorkArea.Left - rcMonitorArea.Left);
+ mmi.ptMaxPosition.Y = Math.Abs(rcWorkArea.Top - rcMonitorArea.Top);
+ mmi.ptMaxSize.X = Math.Abs(rcWorkArea.Right - rcWorkArea.Left);
+ mmi.ptMaxSize.Y = Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top - 1);
+ }
+ }
+
+ Marshal.StructureToPtr(mmi, lParam, true);
+ }
+
+ protected override void OnSourceInitialized(EventArgs e)
+ {
+ this.GetHwndSource()?.AddHook(HwndSourceHook);
+ base.OnSourceInitialized(e);
+ }
+
+ private IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
+ {
+ switch (msg)
+ {
+ case InteropValues.WM_WINDOWPOSCHANGED:
+ Padding = WindowState == WindowState.Maximized ? WindowHelper.WindowMaximizedPadding : _commonPadding;
+ break;
+ case InteropValues.WM_GETMINMAXINFO:
+ WmGetMinMaxInfo(hwnd, lparam);
+ Padding = WindowState == WindowState.Maximized ? WindowHelper.WindowMaximizedPadding : _commonPadding;
+ handled = true;
+ break;
+ }
+
+ return IntPtr.Zero;
+ }
+
+
public Brush CloseButtonBackground
{
- get => (Brush) GetValue(CloseButtonBackgroundProperty);
+ get => (Brush)GetValue(CloseButtonBackgroundProperty);
set => SetValue(CloseButtonBackgroundProperty, value);
}
public Brush CloseButtonForeground
{
- get => (Brush) GetValue(CloseButtonForegroundProperty);
+ get => (Brush)GetValue(CloseButtonForegroundProperty);
set => SetValue(CloseButtonForegroundProperty, value);
}
public Brush OtherButtonBackground
{
- get => (Brush) GetValue(OtherButtonBackgroundProperty);
+ get => (Brush)GetValue(OtherButtonBackgroundProperty);
set => SetValue(OtherButtonBackgroundProperty, value);
}
public Brush OtherButtonForeground
{
- get => (Brush) GetValue(OtherButtonForegroundProperty);
+ get => (Brush)GetValue(OtherButtonForegroundProperty);
set => SetValue(OtherButtonForegroundProperty, value);
}
public double NonClientAreaHeight
{
- get => (double) GetValue(NonClientAreaHeightProperty);
+ get => (double)GetValue(NonClientAreaHeightProperty);
set => SetValue(NonClientAreaHeightProperty, value);
}
public bool IsFullScreen
{
- get => (bool) GetValue(IsFullScreenProperty);
+ get => (bool)GetValue(IsFullScreenProperty);
set => SetValue(IsFullScreenProperty, value);
}
@@ -164,56 +220,56 @@ namespace HandyControl.Controls
public Brush CloseButtonHoverBackground
{
- get => (Brush) GetValue(CloseButtonHoverBackgroundProperty);
+ get => (Brush)GetValue(CloseButtonHoverBackgroundProperty);
set => SetValue(CloseButtonHoverBackgroundProperty, value);
}
public Brush CloseButtonHoverForeground
{
- get => (Brush) GetValue(CloseButtonHoverForegroundProperty);
+ get => (Brush)GetValue(CloseButtonHoverForegroundProperty);
set => SetValue(CloseButtonHoverForegroundProperty, value);
}
public Brush OtherButtonHoverBackground
{
- get => (Brush) GetValue(OtherButtonHoverBackgroundProperty);
+ get => (Brush)GetValue(OtherButtonHoverBackgroundProperty);
set => SetValue(OtherButtonHoverBackgroundProperty, value);
}
public Brush OtherButtonHoverForeground
{
- get => (Brush) GetValue(OtherButtonHoverForegroundProperty);
+ get => (Brush)GetValue(OtherButtonHoverForegroundProperty);
set => SetValue(OtherButtonHoverForegroundProperty, value);
}
public Brush NonClientAreaBackground
{
- get => (Brush) GetValue(NonClientAreaBackgroundProperty);
+ get => (Brush)GetValue(NonClientAreaBackgroundProperty);
set => SetValue(NonClientAreaBackgroundProperty, value);
}
public Brush NonClientAreaForeground
{
- get => (Brush) GetValue(NonClientAreaForegroundProperty);
+ get => (Brush)GetValue(NonClientAreaForegroundProperty);
set => SetValue(NonClientAreaForegroundProperty, value);
}
public bool ShowNonClientArea
{
- get => (bool) GetValue(ShowNonClientAreaProperty);
+ get => (bool)GetValue(ShowNonClientAreaProperty);
set => SetValue(ShowNonClientAreaProperty, value);
}
public bool ShowTitle
{
- get => (bool) GetValue(ShowTitleProperty);
+ get => (bool)GetValue(ShowTitleProperty);
set => SetValue(ShowTitleProperty, value);
}
private static void OnShowNonClientAreaChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
- var ctl = (Window) d;
- ctl.SwitchShowNonClientArea((bool) e.NewValue);
+ var ctl = (Window)d;
+ ctl.SwitchShowNonClientArea((bool)e.NewValue);
}
private void SwitchShowNonClientArea(bool showNonClientArea)
@@ -248,8 +304,8 @@ namespace HandyControl.Controls
private static void OnIsFullScreenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
- var ctl = (Window) d;
- ctl.SwitchIsFullScreen((bool) e.NewValue);
+ var ctl = (Window)d;
+ ctl.SwitchIsFullScreen((bool)e.NewValue);
}
private void SwitchIsFullScreen(bool isFullScreen)
diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/Window.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/Window.xaml
index c48c486c..84acaf28 100644
--- a/src/Shared/HandyControl_Shared/Themes/Styles/Window.xaml
+++ b/src/Shared/HandyControl_Shared/Themes/Styles/Window.xaml
@@ -128,7 +128,6 @@
-
diff --git a/src/Shared/HandyControl_Shared/Tools/Helper/WindowHelper.cs b/src/Shared/HandyControl_Shared/Tools/Helper/WindowHelper.cs
index 23f73766..ae465d22 100644
--- a/src/Shared/HandyControl_Shared/Tools/Helper/WindowHelper.cs
+++ b/src/Shared/HandyControl_Shared/Tools/Helper/WindowHelper.cs
@@ -132,15 +132,17 @@ namespace HandyControl.Tools
{
get
{
+ InteropValues.APPBARDATA appBarData = default;
+ var autoHide = InteropMethods.SHAppBarMessage(4, ref appBarData) != 0;
#if netle40
- return WindowResizeBorderThickness;
+ return WindowResizeBorderThickness.Add(new Thickness(autoHide ? -8 : 0));
#elif Core
var hdc = InteropMethods.GetDC(IntPtr.Zero);
var scale = InteropMethods.GetDeviceCaps(hdc, InteropValues.DESKTOPVERTRES) / (float)InteropMethods.GetDeviceCaps(hdc, InteropValues.VERTRES);
InteropMethods.ReleaseDC(IntPtr.Zero, hdc);
- return WindowResizeBorderThickness.Add(new Thickness(4 * scale));
+ return WindowResizeBorderThickness.Add(new Thickness((autoHide ? - 4 : 4) * scale));
#else
- return WindowResizeBorderThickness.Add(new Thickness(4));
+ return WindowResizeBorderThickness.Add(new Thickness(autoHide ? - 4 : 4));
#endif
}
}
diff --git a/src/Shared/HandyControl_Shared/Tools/Interop/InteropMethods.cs b/src/Shared/HandyControl_Shared/Tools/Interop/InteropMethods.cs
index fa6b8d37..fde76808 100644
--- a/src/Shared/HandyControl_Shared/Tools/Interop/InteropMethods.cs
+++ b/src/Shared/HandyControl_Shared/Tools/Interop/InteropMethods.cs
@@ -17,7 +17,7 @@ namespace HandyControl.Tools.Interop
{
#region common
- public const int E_FAIL = unchecked((int)0x80004005);
+ internal const int E_FAIL = unchecked((int)0x80004005);
internal static readonly IntPtr HRGN_NONE = new IntPtr(-1);
@@ -461,7 +461,10 @@ namespace HandyControl.Tools.Interop
[ReflectionPermission(SecurityAction.Assert, Unrestricted = true),
SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.UnmanagedCode)]
- public static void PtrToStructure(IntPtr lparam, object data) => Marshal.PtrToStructure(lparam, data);
+ internal static void PtrToStructure(IntPtr lparam, object data) => Marshal.PtrToStructure(lparam, data);
+
+ [DllImport(InteropValues.ExternDll.Shell32, CallingConvention = CallingConvention.StdCall)]
+ internal static extern uint SHAppBarMessage(int dwMessage, ref InteropValues.APPBARDATA pData);
#endregion
diff --git a/src/Shared/HandyControl_Shared/Tools/Interop/InteropValues.cs b/src/Shared/HandyControl_Shared/Tools/Interop/InteropValues.cs
index dfc65f65..955fc062 100644
--- a/src/Shared/HandyControl_Shared/Tools/Interop/InteropValues.cs
+++ b/src/Shared/HandyControl_Shared/Tools/Interop/InteropValues.cs
@@ -48,6 +48,7 @@ namespace HandyControl.Tools.Interop
NIIF_ERROR = 0x00000003,
WM_ACTIVATE = 0x0006,
WM_QUIT = 0x0012,
+ WM_GETMINMAXINFO = 0x0024,
WM_WINDOWPOSCHANGING = 0x0046,
WM_WINDOWPOSCHANGED = 0x0047,
WM_SETICON = 0x0080,
@@ -85,7 +86,8 @@ namespace HandyControl.Tools.Interop
SC_MINIMIZE = 0xF020,
SC_MAXIMIZE = 0xF030,
SC_RESTORE = 0xF120,
- SRCCOPY = 0x00CC0020;
+ SRCCOPY = 0x00CC0020,
+ MONITOR_DEFAULTTONEAREST = 0x00000002;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal class NOTIFYICONDATA
@@ -933,5 +935,26 @@ namespace HandyControl.Tools.Interop
return length;
}
}
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal class MINMAXINFO
+ {
+ public POINT ptReserved;
+ public POINT ptMaxSize;
+ public POINT ptMaxPosition;
+ public POINT ptMinTrackSize;
+ public POINT ptMaxTrackSize;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct APPBARDATA
+ {
+ public int cbSize;
+ public IntPtr hWnd;
+ public uint uCallbackMessage;
+ public uint uEdge;
+ public RECT rc;
+ public int lParam;
+ }
}
}
\ No newline at end of file