This commit is contained in:
NaBian committed 2020-05-12 23:59:46 +08:00
1 parent 1fa4c20a91
commit f4a0c6fd4f
7 files changed
+111 -29

No files matched your search

@@ -129,7 +129,6 @@
<Setter Property="Opacity" Value=".8" TargetName="ButtonPanel"/> <Setter Property="Opacity" Value=".8" TargetName="ButtonPanel"/>
</Trigger> </Trigger>
<Trigger Property="WindowState" Value="Maximized"> <Trigger Property="WindowState" Value="Maximized">
<Setter Property="Padding" Value="{x:Static tools:WindowHelper.WindowMaximizedPadding}"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="ButtonMax"/> <Setter Property="Visibility" Value="Collapsed" TargetName="ButtonMax"/>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonRestore"/> <Setter Property="Visibility" Value="Visible" TargetName="ButtonRestore"/>
</Trigger> </Trigger>
@@ -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) if (msg <= InteropValues.WM_WINDOWPOSCHANGED)
{ {
@@ -167,7 +167,7 @@ namespace HandyControl.Controls
protected override void OnSourceInitialized(EventArgs e) protected override void OnSourceInitialized(EventArgs e)
{ {
var hwndSource = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); var hwndSource = this.GetHwndSource();
if (hwndSource != null) if (hwndSource != null)
{ {
hwndSource.AddHook(HwndSourceHook); hwndSource.AddHook(HwndSourceHook);
@@ -1,10 +1,13 @@
using System; using System;
using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
using System.Windows.Data; using System.Windows.Data;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using HandyControl.Data; using HandyControl.Data;
using HandyControl.Tools;
using HandyControl.Tools.Extension; using HandyControl.Tools.Extension;
using HandyControl.Tools.Interop;
#if netle40 #if netle40
using Microsoft.Windows.Shell; using Microsoft.Windows.Shell;
#else #else
@@ -80,6 +83,8 @@ namespace HandyControl.Controls
private Thickness _actualBorderThickness; private Thickness _actualBorderThickness;
private readonly Thickness _commonPadding;
private bool _showNonClientArea = true; private bool _showNonClientArea = true;
private double _tempNonClientAreaHeight; private double _tempNonClientAreaHeight;
@@ -114,45 +119,96 @@ namespace HandyControl.Controls
}; };
#endif #endif
BindingOperations.SetBinding(chrome, WindowChrome.CaptionHeightProperty, BindingOperations.SetBinding(chrome, WindowChrome.CaptionHeightProperty,
new Binding(NonClientAreaHeightProperty.Name) {Source = this}); new Binding(NonClientAreaHeightProperty.Name) { Source = this });
WindowChrome.SetWindowChrome(this, chrome); 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 public Brush CloseButtonBackground
{ {
get => (Brush) GetValue(CloseButtonBackgroundProperty); get => (Brush)GetValue(CloseButtonBackgroundProperty);
set => SetValue(CloseButtonBackgroundProperty, value); set => SetValue(CloseButtonBackgroundProperty, value);
} }
public Brush CloseButtonForeground public Brush CloseButtonForeground
{ {
get => (Brush) GetValue(CloseButtonForegroundProperty); get => (Brush)GetValue(CloseButtonForegroundProperty);
set => SetValue(CloseButtonForegroundProperty, value); set => SetValue(CloseButtonForegroundProperty, value);
} }
public Brush OtherButtonBackground public Brush OtherButtonBackground
{ {
get => (Brush) GetValue(OtherButtonBackgroundProperty); get => (Brush)GetValue(OtherButtonBackgroundProperty);
set => SetValue(OtherButtonBackgroundProperty, value); set => SetValue(OtherButtonBackgroundProperty, value);
} }
public Brush OtherButtonForeground public Brush OtherButtonForeground
{ {
get => (Brush) GetValue(OtherButtonForegroundProperty); get => (Brush)GetValue(OtherButtonForegroundProperty);
set => SetValue(OtherButtonForegroundProperty, value); set => SetValue(OtherButtonForegroundProperty, value);
} }
public double NonClientAreaHeight public double NonClientAreaHeight
{ {
get => (double) GetValue(NonClientAreaHeightProperty); get => (double)GetValue(NonClientAreaHeightProperty);
set => SetValue(NonClientAreaHeightProperty, value); set => SetValue(NonClientAreaHeightProperty, value);
} }
public bool IsFullScreen public bool IsFullScreen
{ {
get => (bool) GetValue(IsFullScreenProperty); get => (bool)GetValue(IsFullScreenProperty);
set => SetValue(IsFullScreenProperty, value); set => SetValue(IsFullScreenProperty, value);
} }
@@ -164,56 +220,56 @@ namespace HandyControl.Controls
public Brush CloseButtonHoverBackground public Brush CloseButtonHoverBackground
{ {
get => (Brush) GetValue(CloseButtonHoverBackgroundProperty); get => (Brush)GetValue(CloseButtonHoverBackgroundProperty);
set => SetValue(CloseButtonHoverBackgroundProperty, value); set => SetValue(CloseButtonHoverBackgroundProperty, value);
} }
public Brush CloseButtonHoverForeground public Brush CloseButtonHoverForeground
{ {
get => (Brush) GetValue(CloseButtonHoverForegroundProperty); get => (Brush)GetValue(CloseButtonHoverForegroundProperty);
set => SetValue(CloseButtonHoverForegroundProperty, value); set => SetValue(CloseButtonHoverForegroundProperty, value);
} }
public Brush OtherButtonHoverBackground public Brush OtherButtonHoverBackground
{ {
get => (Brush) GetValue(OtherButtonHoverBackgroundProperty); get => (Brush)GetValue(OtherButtonHoverBackgroundProperty);
set => SetValue(OtherButtonHoverBackgroundProperty, value); set => SetValue(OtherButtonHoverBackgroundProperty, value);
} }
public Brush OtherButtonHoverForeground public Brush OtherButtonHoverForeground
{ {
get => (Brush) GetValue(OtherButtonHoverForegroundProperty); get => (Brush)GetValue(OtherButtonHoverForegroundProperty);
set => SetValue(OtherButtonHoverForegroundProperty, value); set => SetValue(OtherButtonHoverForegroundProperty, value);
} }
public Brush NonClientAreaBackground public Brush NonClientAreaBackground
{ {
get => (Brush) GetValue(NonClientAreaBackgroundProperty); get => (Brush)GetValue(NonClientAreaBackgroundProperty);
set => SetValue(NonClientAreaBackgroundProperty, value); set => SetValue(NonClientAreaBackgroundProperty, value);
} }
public Brush NonClientAreaForeground public Brush NonClientAreaForeground
{ {
get => (Brush) GetValue(NonClientAreaForegroundProperty); get => (Brush)GetValue(NonClientAreaForegroundProperty);
set => SetValue(NonClientAreaForegroundProperty, value); set => SetValue(NonClientAreaForegroundProperty, value);
} }
public bool ShowNonClientArea public bool ShowNonClientArea
{ {
get => (bool) GetValue(ShowNonClientAreaProperty); get => (bool)GetValue(ShowNonClientAreaProperty);
set => SetValue(ShowNonClientAreaProperty, value); set => SetValue(ShowNonClientAreaProperty, value);
} }
public bool ShowTitle public bool ShowTitle
{ {
get => (bool) GetValue(ShowTitleProperty); get => (bool)GetValue(ShowTitleProperty);
set => SetValue(ShowTitleProperty, value); set => SetValue(ShowTitleProperty, value);
} }
private static void OnShowNonClientAreaChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) private static void OnShowNonClientAreaChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ {
var ctl = (Window) d; var ctl = (Window)d;
ctl.SwitchShowNonClientArea((bool) e.NewValue); ctl.SwitchShowNonClientArea((bool)e.NewValue);
} }
private void SwitchShowNonClientArea(bool showNonClientArea) private void SwitchShowNonClientArea(bool showNonClientArea)
@@ -248,8 +304,8 @@ namespace HandyControl.Controls
private static void OnIsFullScreenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) private static void OnIsFullScreenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ {
var ctl = (Window) d; var ctl = (Window)d;
ctl.SwitchIsFullScreen((bool) e.NewValue); ctl.SwitchIsFullScreen((bool)e.NewValue);
} }
private void SwitchIsFullScreen(bool isFullScreen) private void SwitchIsFullScreen(bool isFullScreen)
@@ -128,7 +128,6 @@
<Setter Property="Opacity" Value=".8" TargetName="ButtonPanel"/> <Setter Property="Opacity" Value=".8" TargetName="ButtonPanel"/>
</Trigger> </Trigger>
<Trigger Property="WindowState" Value="Maximized"> <Trigger Property="WindowState" Value="Maximized">
<Setter Property="Padding" Value="{x:Static tools:WindowHelper.WindowMaximizedPadding}"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="ButtonMax"/> <Setter Property="Visibility" Value="Collapsed" TargetName="ButtonMax"/>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonRestore"/> <Setter Property="Visibility" Value="Visible" TargetName="ButtonRestore"/>
</Trigger> </Trigger>
@@ -132,15 +132,17 @@ namespace HandyControl.Tools
{ {
get get
{ {
InteropValues.APPBARDATA appBarData = default;
var autoHide = InteropMethods.SHAppBarMessage(4, ref appBarData) != 0;
#if netle40 #if netle40
return WindowResizeBorderThickness; return WindowResizeBorderThickness.Add(new Thickness(autoHide ? -8 : 0));
#elif Core #elif Core
var hdc = InteropMethods.GetDC(IntPtr.Zero); var hdc = InteropMethods.GetDC(IntPtr.Zero);
var scale = InteropMethods.GetDeviceCaps(hdc, InteropValues.DESKTOPVERTRES) / (float)InteropMethods.GetDeviceCaps(hdc, InteropValues.VERTRES); var scale = InteropMethods.GetDeviceCaps(hdc, InteropValues.DESKTOPVERTRES) / (float)InteropMethods.GetDeviceCaps(hdc, InteropValues.VERTRES);
InteropMethods.ReleaseDC(IntPtr.Zero, hdc); InteropMethods.ReleaseDC(IntPtr.Zero, hdc);
return WindowResizeBorderThickness.Add(new Thickness(4 * scale)); return WindowResizeBorderThickness.Add(new Thickness((autoHide ? - 4 : 4) * scale));
#else #else
return WindowResizeBorderThickness.Add(new Thickness(4)); return WindowResizeBorderThickness.Add(new Thickness(autoHide ? - 4 : 4));
#endif #endif
} }
} }
@@ -17,7 +17,7 @@ namespace HandyControl.Tools.Interop
{ {
#region common #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); internal static readonly IntPtr HRGN_NONE = new IntPtr(-1);
@@ -461,7 +461,10 @@ namespace HandyControl.Tools.Interop
[ReflectionPermission(SecurityAction.Assert, Unrestricted = true), [ReflectionPermission(SecurityAction.Assert, Unrestricted = true),
SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.UnmanagedCode)] 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 #endregion
@@ -48,6 +48,7 @@ namespace HandyControl.Tools.Interop
NIIF_ERROR = 0x00000003, NIIF_ERROR = 0x00000003,
WM_ACTIVATE = 0x0006, WM_ACTIVATE = 0x0006,
WM_QUIT = 0x0012, WM_QUIT = 0x0012,
WM_GETMINMAXINFO = 0x0024,
WM_WINDOWPOSCHANGING = 0x0046, WM_WINDOWPOSCHANGING = 0x0046,
WM_WINDOWPOSCHANGED = 0x0047, WM_WINDOWPOSCHANGED = 0x0047,
WM_SETICON = 0x0080, WM_SETICON = 0x0080,
@@ -85,7 +86,8 @@ namespace HandyControl.Tools.Interop
SC_MINIMIZE = 0xF020, SC_MINIMIZE = 0xF020,
SC_MAXIMIZE = 0xF030, SC_MAXIMIZE = 0xF030,
SC_RESTORE = 0xF120, SC_RESTORE = 0xF120,
SRCCOPY = 0x00CC0020; SRCCOPY = 0x00CC0020,
MONITOR_DEFAULTTONEAREST = 0x00000002;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal class NOTIFYICONDATA internal class NOTIFYICONDATA
@@ -933,5 +935,26 @@ namespace HandyControl.Tools.Interop
return length; 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;
}
} }
} }