chore: use file-scoped namespace
This commit is contained in:
1 parent
99d2fafb72
commit
bbf1b7d4c6
748 files changed
+57929
-58678
No files matched your search
@@ -5,86 +5,85 @@ using HandyControl.Tools;
|
||||
using HandyControl.Tools.Helper;
|
||||
using HandyControl.Tools.Interop;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
namespace HandyControl.Controls;
|
||||
|
||||
public class BlurWindow : Window
|
||||
{
|
||||
public class BlurWindow : Window
|
||||
protected override void OnSourceInitialized(EventArgs e)
|
||||
{
|
||||
protected override void OnSourceInitialized(EventArgs e)
|
||||
{
|
||||
base.OnSourceInitialized(e);
|
||||
base.OnSourceInitialized(e);
|
||||
|
||||
var versionInfo = SystemHelper.GetSystemVersionInfo();
|
||||
if (versionInfo >= SystemVersionInfo.Windows10_1903)
|
||||
{
|
||||
this.GetHwndSource()?.AddHook(HwndSourceHook);
|
||||
}
|
||||
var versionInfo = SystemHelper.GetSystemVersionInfo();
|
||||
if (versionInfo >= SystemVersionInfo.Windows10_1903)
|
||||
{
|
||||
this.GetHwndSource()?.AddHook(HwndSourceHook);
|
||||
}
|
||||
}
|
||||
|
||||
private IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case InteropValues.WM_ENTERSIZEMOVE:
|
||||
EnableBlur(this, false);
|
||||
break;
|
||||
case InteropValues.WM_EXITSIZEMOVE:
|
||||
EnableBlur(this, true);
|
||||
break;
|
||||
}
|
||||
|
||||
private IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
EnableBlur(this, true);
|
||||
}
|
||||
|
||||
private static void EnableBlur(Window window, bool isEnabled)
|
||||
{
|
||||
var versionInfo = SystemHelper.GetSystemVersionInfo();
|
||||
|
||||
var accentPolicy = new InteropValues.ACCENTPOLICY();
|
||||
var accentPolicySize = Marshal.SizeOf(accentPolicy);
|
||||
|
||||
accentPolicy.AccentFlags = 2;
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
switch (msg)
|
||||
if (versionInfo >= SystemVersionInfo.Windows10_1809)
|
||||
{
|
||||
case InteropValues.WM_ENTERSIZEMOVE:
|
||||
EnableBlur(this, false);
|
||||
break;
|
||||
case InteropValues.WM_EXITSIZEMOVE:
|
||||
EnableBlur(this, true);
|
||||
break;
|
||||
accentPolicy.AccentState = InteropValues.ACCENTSTATE.ACCENT_ENABLE_ACRYLICBLURBEHIND;
|
||||
}
|
||||
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
EnableBlur(this, true);
|
||||
}
|
||||
|
||||
private static void EnableBlur(Window window, bool isEnabled)
|
||||
{
|
||||
var versionInfo = SystemHelper.GetSystemVersionInfo();
|
||||
|
||||
var accentPolicy = new InteropValues.ACCENTPOLICY();
|
||||
var accentPolicySize = Marshal.SizeOf(accentPolicy);
|
||||
|
||||
accentPolicy.AccentFlags = 2;
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
if (versionInfo >= SystemVersionInfo.Windows10_1809)
|
||||
{
|
||||
accentPolicy.AccentState = InteropValues.ACCENTSTATE.ACCENT_ENABLE_ACRYLICBLURBEHIND;
|
||||
}
|
||||
else if (versionInfo >= SystemVersionInfo.Windows10)
|
||||
{
|
||||
accentPolicy.AccentState = InteropValues.ACCENTSTATE.ACCENT_ENABLE_BLURBEHIND;
|
||||
}
|
||||
else
|
||||
{
|
||||
accentPolicy.AccentState = InteropValues.ACCENTSTATE.ACCENT_ENABLE_TRANSPARENTGRADIENT;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (versionInfo >= SystemVersionInfo.Windows10)
|
||||
{
|
||||
accentPolicy.AccentState = InteropValues.ACCENTSTATE.ACCENT_ENABLE_BLURBEHIND;
|
||||
}
|
||||
|
||||
accentPolicy.GradientColor = ResourceHelper.GetResource<uint>(ResourceToken.BlurGradientValue);
|
||||
|
||||
var accentPtr = Marshal.AllocHGlobal(accentPolicySize);
|
||||
Marshal.StructureToPtr(accentPolicy, accentPtr, false);
|
||||
|
||||
var data = new InteropValues.WINCOMPATTRDATA
|
||||
else
|
||||
{
|
||||
Attribute = InteropValues.WINDOWCOMPOSITIONATTRIB.WCA_ACCENT_POLICY,
|
||||
DataSize = accentPolicySize,
|
||||
Data = accentPtr
|
||||
};
|
||||
|
||||
InteropMethods.Gdip.SetWindowCompositionAttribute(window.GetHandle(), ref data);
|
||||
|
||||
Marshal.FreeHGlobal(accentPtr);
|
||||
accentPolicy.AccentState = InteropValues.ACCENTSTATE.ACCENT_ENABLE_TRANSPARENTGRADIENT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
accentPolicy.AccentState = InteropValues.ACCENTSTATE.ACCENT_ENABLE_BLURBEHIND;
|
||||
}
|
||||
|
||||
accentPolicy.GradientColor = ResourceHelper.GetResource<uint>(ResourceToken.BlurGradientValue);
|
||||
|
||||
var accentPtr = Marshal.AllocHGlobal(accentPolicySize);
|
||||
Marshal.StructureToPtr(accentPolicy, accentPtr, false);
|
||||
|
||||
var data = new InteropValues.WINCOMPATTRDATA
|
||||
{
|
||||
Attribute = InteropValues.WINDOWCOMPOSITIONATTRIB.WCA_ACCENT_POLICY,
|
||||
DataSize = accentPolicySize,
|
||||
Data = accentPtr
|
||||
};
|
||||
|
||||
InteropMethods.Gdip.SetWindowCompositionAttribute(window.GetHandle(), ref data);
|
||||
|
||||
Marshal.FreeHGlobal(accentPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,455 +12,454 @@ using HandyControl.Expression.Drawing;
|
||||
using HandyControl.Tools;
|
||||
using HandyControl.Tools.Interop;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
namespace HandyControl.Controls;
|
||||
|
||||
public class GlowWindow : Window
|
||||
{
|
||||
public class GlowWindow : Window
|
||||
internal int DeferGlowChangesCount;
|
||||
|
||||
private readonly GlowEdge[] _glowEdges = new GlowEdge[4];
|
||||
|
||||
private DispatcherTimer _makeGlowVisibleTimer;
|
||||
|
||||
private bool _isGlowVisible;
|
||||
|
||||
private bool _useLogicalSizeForRestore;
|
||||
|
||||
private bool _updatingZOrder;
|
||||
|
||||
private Rect _logicalSizeForRestore = Rect.Empty;
|
||||
|
||||
public static readonly DependencyProperty ActiveGlowColorProperty = DependencyProperty.Register(
|
||||
"ActiveGlowColor", typeof(Color), typeof(GlowWindow), new PropertyMetadata(default(Color), OnGlowColorChanged));
|
||||
|
||||
public Color ActiveGlowColor
|
||||
{
|
||||
internal int DeferGlowChangesCount;
|
||||
get => (Color) GetValue(ActiveGlowColorProperty);
|
||||
set => SetValue(ActiveGlowColorProperty, value);
|
||||
}
|
||||
|
||||
private readonly GlowEdge[] _glowEdges = new GlowEdge[4];
|
||||
public static readonly DependencyProperty InactiveGlowColorProperty = DependencyProperty.Register(
|
||||
"InactiveGlowColor", typeof(Color), typeof(GlowWindow), new PropertyMetadata(default(Color), OnGlowColorChanged));
|
||||
|
||||
private DispatcherTimer _makeGlowVisibleTimer;
|
||||
public Color InactiveGlowColor
|
||||
{
|
||||
get => (Color) GetValue(InactiveGlowColorProperty);
|
||||
set => SetValue(InactiveGlowColorProperty, value);
|
||||
}
|
||||
|
||||
private bool _isGlowVisible;
|
||||
#region internal
|
||||
|
||||
private bool _useLogicalSizeForRestore;
|
||||
internal void EndDeferGlowChanges()
|
||||
{
|
||||
foreach (var current in LoadedGlowWindows) current.CommitChanges();
|
||||
}
|
||||
|
||||
private bool _updatingZOrder;
|
||||
#endregion
|
||||
|
||||
private Rect _logicalSizeForRestore = Rect.Empty;
|
||||
#region protected
|
||||
|
||||
public static readonly DependencyProperty ActiveGlowColorProperty = DependencyProperty.Register(
|
||||
"ActiveGlowColor", typeof(Color), typeof(GlowWindow), new PropertyMetadata(default(Color), OnGlowColorChanged));
|
||||
|
||||
public Color ActiveGlowColor
|
||||
protected virtual bool ShouldShowGlow
|
||||
{
|
||||
get
|
||||
{
|
||||
get => (Color) GetValue(ActiveGlowColorProperty);
|
||||
set => SetValue(ActiveGlowColorProperty, value);
|
||||
var handle = this.GetHandle();
|
||||
return InteropMethods.IsWindowVisible(handle) && !InteropMethods.IsIconic(handle) &&
|
||||
!InteropMethods.IsZoomed(handle) && ResizeMode != ResizeMode.NoResize;
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty InactiveGlowColorProperty = DependencyProperty.Register(
|
||||
"InactiveGlowColor", typeof(Color), typeof(GlowWindow), new PropertyMetadata(default(Color), OnGlowColorChanged));
|
||||
|
||||
public Color InactiveGlowColor
|
||||
private IntPtr HwndSourceHook(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
if (msg <= InteropValues.WM_WINDOWPOSCHANGED)
|
||||
{
|
||||
get => (Color) GetValue(InactiveGlowColorProperty);
|
||||
set => SetValue(InactiveGlowColorProperty, value);
|
||||
}
|
||||
|
||||
#region internal
|
||||
|
||||
internal void EndDeferGlowChanges()
|
||||
{
|
||||
foreach (var current in LoadedGlowWindows) current.CommitChanges();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected
|
||||
|
||||
protected virtual bool ShouldShowGlow
|
||||
{
|
||||
get
|
||||
if (msg == InteropValues.WM_ACTIVATE)
|
||||
{
|
||||
var handle = this.GetHandle();
|
||||
return InteropMethods.IsWindowVisible(handle) && !InteropMethods.IsIconic(handle) &&
|
||||
!InteropMethods.IsZoomed(handle) && ResizeMode != ResizeMode.NoResize;
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (msg != InteropValues.WM_QUIT)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case InteropValues.WM_WINDOWPOSCHANGING:
|
||||
WmWindowPosChanging(lParam);
|
||||
return IntPtr.Zero;
|
||||
case InteropValues.WM_WINDOWPOSCHANGED:
|
||||
WmWindowPosChanged(lParam);
|
||||
return IntPtr.Zero;
|
||||
default:
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IntPtr HwndSourceHook(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
else
|
||||
{
|
||||
if (msg <= InteropValues.WM_WINDOWPOSCHANGED)
|
||||
if (msg <= InteropValues.WM_NCRBUTTONDBLCLK)
|
||||
{
|
||||
if (msg == InteropValues.WM_ACTIVATE)
|
||||
switch (msg)
|
||||
{
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (msg != InteropValues.WM_QUIT)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case InteropValues.WM_WINDOWPOSCHANGING:
|
||||
WmWindowPosChanging(lParam);
|
||||
return IntPtr.Zero;
|
||||
case InteropValues.WM_WINDOWPOSCHANGED:
|
||||
WmWindowPosChanged(lParam);
|
||||
return IntPtr.Zero;
|
||||
default:
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
case InteropValues.WM_SETICON:
|
||||
break;
|
||||
case InteropValues.WM_NCCREATE:
|
||||
case InteropValues.WM_NCDESTROY:
|
||||
return IntPtr.Zero;
|
||||
case InteropValues.WM_NCACTIVATE:
|
||||
handled = true;
|
||||
return WmNcActivate(hWnd, wParam);
|
||||
default:
|
||||
switch (msg)
|
||||
{
|
||||
case InteropValues.WM_NCRBUTTONDOWN:
|
||||
case InteropValues.WM_NCRBUTTONUP:
|
||||
case InteropValues.WM_NCRBUTTONDBLCLK:
|
||||
handled = true;
|
||||
return IntPtr.Zero;
|
||||
default:
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (msg <= InteropValues.WM_NCRBUTTONDBLCLK)
|
||||
switch (msg)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case InteropValues.WM_SETICON:
|
||||
break;
|
||||
case InteropValues.WM_NCCREATE:
|
||||
case InteropValues.WM_NCDESTROY:
|
||||
return IntPtr.Zero;
|
||||
case InteropValues.WM_NCACTIVATE:
|
||||
handled = true;
|
||||
return WmNcActivate(hWnd, wParam);
|
||||
default:
|
||||
switch (msg)
|
||||
{
|
||||
case InteropValues.WM_NCRBUTTONDOWN:
|
||||
case InteropValues.WM_NCRBUTTONUP:
|
||||
case InteropValues.WM_NCRBUTTONDBLCLK:
|
||||
handled = true;
|
||||
return IntPtr.Zero;
|
||||
default:
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
case InteropValues.WM_NCUAHDRAWCAPTION:
|
||||
case InteropValues.WM_NCUAHDRAWFRAME:
|
||||
handled = true;
|
||||
return IntPtr.Zero;
|
||||
default:
|
||||
if (msg != InteropValues.WM_SYSCOMMAND) return IntPtr.Zero;
|
||||
WmSysCommand(hWnd, wParam);
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handled = true;
|
||||
return CallDefWindowProcWithoutVisibleStyle(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
protected override void OnActivated(EventArgs e)
|
||||
{
|
||||
UpdateGlowActiveState();
|
||||
base.OnActivated(e);
|
||||
}
|
||||
|
||||
protected override void OnDeactivated(EventArgs e)
|
||||
{
|
||||
UpdateGlowActiveState();
|
||||
base.OnDeactivated(e);
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
StopTimer();
|
||||
DestroyGlowWindows();
|
||||
base.OnClosed(e);
|
||||
}
|
||||
|
||||
protected override void OnSourceInitialized(EventArgs e)
|
||||
{
|
||||
base.OnSourceInitialized(e);
|
||||
|
||||
var hwndSource = this.GetHwndSource();
|
||||
if (hwndSource != null)
|
||||
{
|
||||
hwndSource.AddHook(HwndSourceHook);
|
||||
CreateGlowWindowHandles();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private
|
||||
|
||||
private IEnumerable<GlowEdge> LoadedGlowWindows => from w in _glowEdges where w != null select w;
|
||||
|
||||
private bool IsGlowVisible
|
||||
{
|
||||
get => _isGlowVisible;
|
||||
set
|
||||
{
|
||||
if (_isGlowVisible != value)
|
||||
{
|
||||
_isGlowVisible = value;
|
||||
for (var i = 0; i < _glowEdges.Length; i++)
|
||||
{
|
||||
GetOrCreateGlowWindow(i).IsVisible = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private GlowEdge GetOrCreateGlowWindow(int direction)
|
||||
{
|
||||
return _glowEdges[direction] ?? (_glowEdges[direction] = new GlowEdge(this, (Dock) direction)
|
||||
{
|
||||
ActiveGlowColor = ActiveGlowColor,
|
||||
InactiveGlowColor = InactiveGlowColor,
|
||||
IsActive = IsActive
|
||||
});
|
||||
}
|
||||
|
||||
private static void OnResizeModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var customChromeWindow = (GlowWindow) obj;
|
||||
customChromeWindow.UpdateGlowVisibility(false);
|
||||
}
|
||||
|
||||
private static void OnGlowColorChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) => ((GlowWindow) obj).UpdateGlowColors();
|
||||
|
||||
private void UpdateGlowColors()
|
||||
{
|
||||
using (DeferGlowChanges())
|
||||
{
|
||||
foreach (var current in LoadedGlowWindows)
|
||||
{
|
||||
current.ActiveGlowColor = ActiveGlowColor;
|
||||
current.InactiveGlowColor = InactiveGlowColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateGlowVisibility(bool delayIfNecessary)
|
||||
{
|
||||
var shouldShowGlow = ShouldShowGlow;
|
||||
if (shouldShowGlow != IsGlowVisible)
|
||||
{
|
||||
if (SystemParameters.MinimizeAnimation && shouldShowGlow && delayIfNecessary)
|
||||
{
|
||||
if (_makeGlowVisibleTimer != null)
|
||||
{
|
||||
_makeGlowVisibleTimer.Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (msg)
|
||||
_makeGlowVisibleTimer = new DispatcherTimer
|
||||
{
|
||||
case InteropValues.WM_NCUAHDRAWCAPTION:
|
||||
case InteropValues.WM_NCUAHDRAWFRAME:
|
||||
handled = true;
|
||||
return IntPtr.Zero;
|
||||
default:
|
||||
if (msg != InteropValues.WM_SYSCOMMAND) return IntPtr.Zero;
|
||||
WmSysCommand(hWnd, wParam);
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
Interval = TimeSpan.FromMilliseconds(200.0)
|
||||
};
|
||||
_makeGlowVisibleTimer.Tick += OnDelayedVisibilityTimerTick;
|
||||
}
|
||||
|
||||
_makeGlowVisibleTimer.Start();
|
||||
return;
|
||||
}
|
||||
|
||||
handled = true;
|
||||
return CallDefWindowProcWithoutVisibleStyle(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
protected override void OnActivated(EventArgs e)
|
||||
{
|
||||
UpdateGlowActiveState();
|
||||
base.OnActivated(e);
|
||||
}
|
||||
|
||||
protected override void OnDeactivated(EventArgs e)
|
||||
{
|
||||
UpdateGlowActiveState();
|
||||
base.OnDeactivated(e);
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
StopTimer();
|
||||
DestroyGlowWindows();
|
||||
base.OnClosed(e);
|
||||
IsGlowVisible = shouldShowGlow;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnSourceInitialized(EventArgs e)
|
||||
private void StopTimer()
|
||||
{
|
||||
if (_makeGlowVisibleTimer != null)
|
||||
{
|
||||
base.OnSourceInitialized(e);
|
||||
_makeGlowVisibleTimer.Stop();
|
||||
_makeGlowVisibleTimer.Tick -= OnDelayedVisibilityTimerTick;
|
||||
_makeGlowVisibleTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
var hwndSource = this.GetHwndSource();
|
||||
if (hwndSource != null)
|
||||
private void OnDelayedVisibilityTimerTick(object sender, EventArgs e)
|
||||
{
|
||||
StopTimer();
|
||||
UpdateGlowWindowPositions(false);
|
||||
}
|
||||
|
||||
private void UpdateGlowWindowPositions(bool delayIfNecessary)
|
||||
{
|
||||
using (DeferGlowChanges())
|
||||
{
|
||||
UpdateGlowVisibility(delayIfNecessary);
|
||||
foreach (var current in LoadedGlowWindows) current.UpdateWindowPos();
|
||||
}
|
||||
}
|
||||
|
||||
private IDisposable DeferGlowChanges() => new ChangeScope(this);
|
||||
|
||||
private void UpdateGlowActiveState()
|
||||
{
|
||||
using (DeferGlowChanges())
|
||||
{
|
||||
foreach (var current in LoadedGlowWindows)
|
||||
{
|
||||
hwndSource.AddHook(HwndSourceHook);
|
||||
CreateGlowWindowHandles();
|
||||
current.IsActive = IsActive;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private
|
||||
|
||||
private IEnumerable<GlowEdge> LoadedGlowWindows => from w in _glowEdges where w != null select w;
|
||||
|
||||
private bool IsGlowVisible
|
||||
private void DestroyGlowWindows()
|
||||
{
|
||||
for (var i = 0; i < _glowEdges.Length; i++)
|
||||
{
|
||||
get => _isGlowVisible;
|
||||
set
|
||||
using (_glowEdges[i])
|
||||
{
|
||||
if (_isGlowVisible != value)
|
||||
{
|
||||
_isGlowVisible = value;
|
||||
for (var i = 0; i < _glowEdges.Length; i++)
|
||||
{
|
||||
GetOrCreateGlowWindow(i).IsVisible = value;
|
||||
}
|
||||
}
|
||||
_glowEdges[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private GlowEdge GetOrCreateGlowWindow(int direction)
|
||||
private void WmWindowPosChanging(IntPtr lParam)
|
||||
{
|
||||
var windowpos = (InteropValues.WINDOWPOS) Marshal.PtrToStructure(lParam, typeof(InteropValues.WINDOWPOS));
|
||||
if ((windowpos.flags & 2u) == 0u && (windowpos.flags & 1u) == 0u && windowpos.cx > 0 && windowpos.cy > 0)
|
||||
{
|
||||
return _glowEdges[direction] ?? (_glowEdges[direction] = new GlowEdge(this, (Dock) direction)
|
||||
var rect = new Rect(windowpos.x, windowpos.y, windowpos.cx, windowpos.cy);
|
||||
rect = rect.DeviceToLogicalUnits();
|
||||
if (_useLogicalSizeForRestore)
|
||||
{
|
||||
ActiveGlowColor = ActiveGlowColor,
|
||||
InactiveGlowColor = InactiveGlowColor,
|
||||
IsActive = IsActive
|
||||
});
|
||||
}
|
||||
|
||||
private static void OnResizeModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var customChromeWindow = (GlowWindow) obj;
|
||||
customChromeWindow.UpdateGlowVisibility(false);
|
||||
}
|
||||
|
||||
private static void OnGlowColorChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) => ((GlowWindow) obj).UpdateGlowColors();
|
||||
|
||||
private void UpdateGlowColors()
|
||||
{
|
||||
using (DeferGlowChanges())
|
||||
{
|
||||
foreach (var current in LoadedGlowWindows)
|
||||
{
|
||||
current.ActiveGlowColor = ActiveGlowColor;
|
||||
current.InactiveGlowColor = InactiveGlowColor;
|
||||
}
|
||||
rect = _logicalSizeForRestore;
|
||||
_logicalSizeForRestore = Rect.Empty;
|
||||
_useLogicalSizeForRestore = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateGlowVisibility(bool delayIfNecessary)
|
||||
var logicalRect = GetOnScreenPosition(rect);
|
||||
logicalRect = logicalRect.LogicalToDeviceUnits();
|
||||
windowpos.x = (int) logicalRect.X;
|
||||
windowpos.y = (int) logicalRect.Y;
|
||||
Marshal.StructureToPtr(windowpos, lParam, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateZOrderOfOwner(IntPtr hwndOwner)
|
||||
{
|
||||
var lastOwnedWindow = IntPtr.Zero;
|
||||
InteropMethods.EnumThreadWindows(InteropMethods.GetCurrentThreadId(), delegate (IntPtr hwnd, IntPtr lParam)
|
||||
{
|
||||
var shouldShowGlow = ShouldShowGlow;
|
||||
if (shouldShowGlow != IsGlowVisible)
|
||||
if (InteropMethods.GetWindow(hwnd, 4) == hwndOwner) lastOwnedWindow = hwnd;
|
||||
return true;
|
||||
}, IntPtr.Zero);
|
||||
|
||||
if (lastOwnedWindow != IntPtr.Zero && InteropMethods.GetWindow(hwndOwner, 3) != lastOwnedWindow)
|
||||
InteropMethods.SetWindowPos(hwndOwner, lastOwnedWindow, 0, 0, 0, 0, 19);
|
||||
}
|
||||
|
||||
private void UpdateZOrderOfThisAndOwner()
|
||||
{
|
||||
if (_updatingZOrder) return;
|
||||
try
|
||||
{
|
||||
_updatingZOrder = true;
|
||||
var windowInteropHelper = new WindowInteropHelper(this);
|
||||
var handle = windowInteropHelper.Handle;
|
||||
foreach (var current in LoadedGlowWindows)
|
||||
{
|
||||
if (SystemParameters.MinimizeAnimation && shouldShowGlow && delayIfNecessary)
|
||||
{
|
||||
if (_makeGlowVisibleTimer != null)
|
||||
{
|
||||
_makeGlowVisibleTimer.Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
_makeGlowVisibleTimer = new DispatcherTimer
|
||||
{
|
||||
Interval = TimeSpan.FromMilliseconds(200.0)
|
||||
};
|
||||
_makeGlowVisibleTimer.Tick += OnDelayedVisibilityTimerTick;
|
||||
}
|
||||
|
||||
_makeGlowVisibleTimer.Start();
|
||||
return;
|
||||
}
|
||||
|
||||
StopTimer();
|
||||
IsGlowVisible = shouldShowGlow;
|
||||
var window = InteropMethods.GetWindow(current.Handle, 3);
|
||||
if (window != handle) InteropMethods.SetWindowPos(current.Handle, handle, 0, 0, 0, 0, 19);
|
||||
handle = current.Handle;
|
||||
}
|
||||
}
|
||||
|
||||
private void StopTimer()
|
||||
var owner = windowInteropHelper.Owner;
|
||||
if (owner != IntPtr.Zero) UpdateZOrderOfOwner(owner);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_makeGlowVisibleTimer != null)
|
||||
{
|
||||
_makeGlowVisibleTimer.Stop();
|
||||
_makeGlowVisibleTimer.Tick -= OnDelayedVisibilityTimerTick;
|
||||
_makeGlowVisibleTimer = null;
|
||||
}
|
||||
_updatingZOrder = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDelayedVisibilityTimerTick(object sender, EventArgs e)
|
||||
{
|
||||
StopTimer();
|
||||
UpdateGlowWindowPositions(false);
|
||||
}
|
||||
|
||||
private void UpdateGlowWindowPositions(bool delayIfNecessary)
|
||||
{
|
||||
using (DeferGlowChanges())
|
||||
{
|
||||
UpdateGlowVisibility(delayIfNecessary);
|
||||
foreach (var current in LoadedGlowWindows) current.UpdateWindowPos();
|
||||
}
|
||||
}
|
||||
|
||||
private IDisposable DeferGlowChanges() => new ChangeScope(this);
|
||||
|
||||
private void UpdateGlowActiveState()
|
||||
{
|
||||
using (DeferGlowChanges())
|
||||
{
|
||||
foreach (var current in LoadedGlowWindows)
|
||||
{
|
||||
current.IsActive = IsActive;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DestroyGlowWindows()
|
||||
{
|
||||
for (var i = 0; i < _glowEdges.Length; i++)
|
||||
{
|
||||
using (_glowEdges[i])
|
||||
{
|
||||
_glowEdges[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WmWindowPosChanging(IntPtr lParam)
|
||||
private void WmWindowPosChanged(IntPtr lParam)
|
||||
{
|
||||
try
|
||||
{
|
||||
var windowpos = (InteropValues.WINDOWPOS) Marshal.PtrToStructure(lParam, typeof(InteropValues.WINDOWPOS));
|
||||
if ((windowpos.flags & 2u) == 0u && (windowpos.flags & 1u) == 0u && windowpos.cx > 0 && windowpos.cy > 0)
|
||||
{
|
||||
var rect = new Rect(windowpos.x, windowpos.y, windowpos.cx, windowpos.cy);
|
||||
rect = rect.DeviceToLogicalUnits();
|
||||
if (_useLogicalSizeForRestore)
|
||||
{
|
||||
rect = _logicalSizeForRestore;
|
||||
_logicalSizeForRestore = Rect.Empty;
|
||||
_useLogicalSizeForRestore = false;
|
||||
}
|
||||
|
||||
var logicalRect = GetOnScreenPosition(rect);
|
||||
logicalRect = logicalRect.LogicalToDeviceUnits();
|
||||
windowpos.x = (int) logicalRect.X;
|
||||
windowpos.y = (int) logicalRect.Y;
|
||||
Marshal.StructureToPtr(windowpos, lParam, true);
|
||||
}
|
||||
UpdateGlowWindowPositions((windowpos.flags & 64u) == 0u);
|
||||
UpdateZOrderOfThisAndOwner();
|
||||
}
|
||||
|
||||
private void UpdateZOrderOfOwner(IntPtr hwndOwner)
|
||||
catch
|
||||
{
|
||||
var lastOwnedWindow = IntPtr.Zero;
|
||||
InteropMethods.EnumThreadWindows(InteropMethods.GetCurrentThreadId(), delegate (IntPtr hwnd, IntPtr lParam)
|
||||
{
|
||||
if (InteropMethods.GetWindow(hwnd, 4) == hwndOwner) lastOwnedWindow = hwnd;
|
||||
return true;
|
||||
}, IntPtr.Zero);
|
||||
|
||||
if (lastOwnedWindow != IntPtr.Zero && InteropMethods.GetWindow(hwndOwner, 3) != lastOwnedWindow)
|
||||
InteropMethods.SetWindowPos(hwndOwner, lastOwnedWindow, 0, 0, 0, 0, 19);
|
||||
// ignored
|
||||
}
|
||||
|
||||
private void UpdateZOrderOfThisAndOwner()
|
||||
{
|
||||
if (_updatingZOrder) return;
|
||||
try
|
||||
{
|
||||
_updatingZOrder = true;
|
||||
var windowInteropHelper = new WindowInteropHelper(this);
|
||||
var handle = windowInteropHelper.Handle;
|
||||
foreach (var current in LoadedGlowWindows)
|
||||
{
|
||||
var window = InteropMethods.GetWindow(current.Handle, 3);
|
||||
if (window != handle) InteropMethods.SetWindowPos(current.Handle, handle, 0, 0, 0, 0, 19);
|
||||
handle = current.Handle;
|
||||
}
|
||||
|
||||
var owner = windowInteropHelper.Owner;
|
||||
if (owner != IntPtr.Zero) UpdateZOrderOfOwner(owner);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_updatingZOrder = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void WmWindowPosChanged(IntPtr lParam)
|
||||
{
|
||||
try
|
||||
{
|
||||
var windowpos = (InteropValues.WINDOWPOS) Marshal.PtrToStructure(lParam, typeof(InteropValues.WINDOWPOS));
|
||||
|
||||
UpdateGlowWindowPositions((windowpos.flags & 64u) == 0u);
|
||||
UpdateZOrderOfThisAndOwner();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
private Rect GetOnScreenPosition(Rect floatRect)
|
||||
{
|
||||
var result = floatRect;
|
||||
floatRect = floatRect.LogicalToDeviceUnits();
|
||||
ScreenHelper.FindMaximumSingleMonitorRectangle(floatRect, out _, out var rect2);
|
||||
if (!floatRect.IntersectsWith(rect2))
|
||||
{
|
||||
ScreenHelper.FindMonitorRectsFromPoint(InteropMethods.GetCursorPos(), out _, out rect2);
|
||||
rect2 = rect2.DeviceToLogicalUnits();
|
||||
if (result.Width > rect2.Width) result.Width = rect2.Width;
|
||||
if (result.Height > rect2.Height) result.Height = rect2.Height;
|
||||
if (rect2.Right <= result.X) result.X = rect2.Right - result.Width;
|
||||
if (rect2.Left > result.X + result.Width) result.X = rect2.Left;
|
||||
if (rect2.Bottom <= result.Y) result.Y = rect2.Bottom - result.Height;
|
||||
if (rect2.Top > result.Y + result.Height) result.Y = rect2.Top;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static InteropValues.MONITORINFO MonitorInfoFromWindow(IntPtr hWnd)
|
||||
{
|
||||
var hMonitor = InteropMethods.MonitorFromWindow(hWnd, 2);
|
||||
var result = default(InteropValues.MONITORINFO);
|
||||
result.cbSize = (uint) Marshal.SizeOf(typeof(InteropValues.MONITORINFO));
|
||||
InteropMethods.GetMonitorInfo(hMonitor, ref result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private IntPtr WmNcActivate(IntPtr hWnd, IntPtr wParam) => InteropMethods.DefWindowProc(hWnd, InteropValues.WM_NCACTIVATE, wParam, InteropMethods.HRGN_NONE);
|
||||
|
||||
private bool IsAeroSnappedToMonitor(IntPtr hWnd)
|
||||
{
|
||||
var monitorinfo = MonitorInfoFromWindow(hWnd);
|
||||
var logicalRect = new Rect(Left, Top, Width, Height);
|
||||
logicalRect = logicalRect.LogicalToDeviceUnits();
|
||||
return MathHelper.AreClose(monitorinfo.rcWork.Height, logicalRect.Height) && MathHelper.AreClose(monitorinfo.rcWork.Top, logicalRect.Top);
|
||||
}
|
||||
|
||||
private void WmSysCommand(IntPtr hWnd, IntPtr wParam)
|
||||
{
|
||||
var num = InteropMethods.GET_SC_WPARAM(wParam);
|
||||
|
||||
if (num == InteropValues.SC_MOVE)
|
||||
{
|
||||
InteropMethods.RedrawWindow(hWnd, IntPtr.Zero, IntPtr.Zero,
|
||||
InteropValues.RedrawWindowFlags.Invalidate | InteropValues.RedrawWindowFlags.NoChildren |
|
||||
InteropValues.RedrawWindowFlags.UpdateNow | InteropValues.RedrawWindowFlags.Frame);
|
||||
}
|
||||
|
||||
if ((num == InteropValues.SC_MAXIMIZE || num == InteropValues.SC_MINIMIZE || num == InteropValues.SC_MOVE ||
|
||||
num == InteropValues.SC_SIZE) && WindowState == WindowState.Normal && !IsAeroSnappedToMonitor(hWnd))
|
||||
{
|
||||
_logicalSizeForRestore = new Rect(Left, Top, Width, Height);
|
||||
}
|
||||
|
||||
if (num == InteropValues.SC_MOVE && WindowState == WindowState.Maximized && _logicalSizeForRestore == Rect.Empty)
|
||||
{
|
||||
_logicalSizeForRestore = new Rect(Left, Top, Width, Height);
|
||||
}
|
||||
|
||||
if (num == InteropValues.SC_RESTORE && WindowState != WindowState.Minimized &&
|
||||
_logicalSizeForRestore.Width > 0.0 && _logicalSizeForRestore.Height > 0.0)
|
||||
{
|
||||
Left = _logicalSizeForRestore.Left;
|
||||
Top = _logicalSizeForRestore.Top;
|
||||
Width = _logicalSizeForRestore.Width;
|
||||
Height = _logicalSizeForRestore.Height;
|
||||
_useLogicalSizeForRestore = true;
|
||||
}
|
||||
}
|
||||
|
||||
private IntPtr CallDefWindowProcWithoutVisibleStyle(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
var flag = VisualHelper.ModifyStyle(hWnd, InteropValues.WS_VISIBLE, 0);
|
||||
var result = InteropMethods.DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
if (flag) VisualHelper.ModifyStyle(hWnd, 0, InteropValues.WS_VISIBLE);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void CreateGlowWindowHandles()
|
||||
{
|
||||
for (var i = 0; i < _glowEdges.Length; i++) GetOrCreateGlowWindow(i).EnsureHandle();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private Rect GetOnScreenPosition(Rect floatRect)
|
||||
{
|
||||
var result = floatRect;
|
||||
floatRect = floatRect.LogicalToDeviceUnits();
|
||||
ScreenHelper.FindMaximumSingleMonitorRectangle(floatRect, out _, out var rect2);
|
||||
if (!floatRect.IntersectsWith(rect2))
|
||||
{
|
||||
ScreenHelper.FindMonitorRectsFromPoint(InteropMethods.GetCursorPos(), out _, out rect2);
|
||||
rect2 = rect2.DeviceToLogicalUnits();
|
||||
if (result.Width > rect2.Width) result.Width = rect2.Width;
|
||||
if (result.Height > rect2.Height) result.Height = rect2.Height;
|
||||
if (rect2.Right <= result.X) result.X = rect2.Right - result.Width;
|
||||
if (rect2.Left > result.X + result.Width) result.X = rect2.Left;
|
||||
if (rect2.Bottom <= result.Y) result.Y = rect2.Bottom - result.Height;
|
||||
if (rect2.Top > result.Y + result.Height) result.Y = rect2.Top;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static InteropValues.MONITORINFO MonitorInfoFromWindow(IntPtr hWnd)
|
||||
{
|
||||
var hMonitor = InteropMethods.MonitorFromWindow(hWnd, 2);
|
||||
var result = default(InteropValues.MONITORINFO);
|
||||
result.cbSize = (uint) Marshal.SizeOf(typeof(InteropValues.MONITORINFO));
|
||||
InteropMethods.GetMonitorInfo(hMonitor, ref result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private IntPtr WmNcActivate(IntPtr hWnd, IntPtr wParam) => InteropMethods.DefWindowProc(hWnd, InteropValues.WM_NCACTIVATE, wParam, InteropMethods.HRGN_NONE);
|
||||
|
||||
private bool IsAeroSnappedToMonitor(IntPtr hWnd)
|
||||
{
|
||||
var monitorinfo = MonitorInfoFromWindow(hWnd);
|
||||
var logicalRect = new Rect(Left, Top, Width, Height);
|
||||
logicalRect = logicalRect.LogicalToDeviceUnits();
|
||||
return MathHelper.AreClose(monitorinfo.rcWork.Height, logicalRect.Height) && MathHelper.AreClose(monitorinfo.rcWork.Top, logicalRect.Top);
|
||||
}
|
||||
|
||||
private void WmSysCommand(IntPtr hWnd, IntPtr wParam)
|
||||
{
|
||||
var num = InteropMethods.GET_SC_WPARAM(wParam);
|
||||
|
||||
if (num == InteropValues.SC_MOVE)
|
||||
{
|
||||
InteropMethods.RedrawWindow(hWnd, IntPtr.Zero, IntPtr.Zero,
|
||||
InteropValues.RedrawWindowFlags.Invalidate | InteropValues.RedrawWindowFlags.NoChildren |
|
||||
InteropValues.RedrawWindowFlags.UpdateNow | InteropValues.RedrawWindowFlags.Frame);
|
||||
}
|
||||
|
||||
if ((num == InteropValues.SC_MAXIMIZE || num == InteropValues.SC_MINIMIZE || num == InteropValues.SC_MOVE ||
|
||||
num == InteropValues.SC_SIZE) && WindowState == WindowState.Normal && !IsAeroSnappedToMonitor(hWnd))
|
||||
{
|
||||
_logicalSizeForRestore = new Rect(Left, Top, Width, Height);
|
||||
}
|
||||
|
||||
if (num == InteropValues.SC_MOVE && WindowState == WindowState.Maximized && _logicalSizeForRestore == Rect.Empty)
|
||||
{
|
||||
_logicalSizeForRestore = new Rect(Left, Top, Width, Height);
|
||||
}
|
||||
|
||||
if (num == InteropValues.SC_RESTORE && WindowState != WindowState.Minimized &&
|
||||
_logicalSizeForRestore.Width > 0.0 && _logicalSizeForRestore.Height > 0.0)
|
||||
{
|
||||
Left = _logicalSizeForRestore.Left;
|
||||
Top = _logicalSizeForRestore.Top;
|
||||
Width = _logicalSizeForRestore.Width;
|
||||
Height = _logicalSizeForRestore.Height;
|
||||
_useLogicalSizeForRestore = true;
|
||||
}
|
||||
}
|
||||
|
||||
private IntPtr CallDefWindowProcWithoutVisibleStyle(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
var flag = VisualHelper.ModifyStyle(hWnd, InteropValues.WS_VISIBLE, 0);
|
||||
var result = InteropMethods.DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
if (flag) VisualHelper.ModifyStyle(hWnd, 0, InteropValues.WS_VISIBLE);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void CreateGlowWindowHandles()
|
||||
{
|
||||
for (var i = 0; i < _glowEdges.Length; i++) GetOrCreateGlowWindow(i).EnsureHandle();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
@@ -7,124 +7,123 @@ using System.Windows.Media.Imaging;
|
||||
using HandyControl.Data;
|
||||
using HandyControl.Interactivity;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
namespace HandyControl.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// 图片浏览器
|
||||
/// </summary>
|
||||
[TemplatePart(Name = ElementPanelTop, Type = typeof(Panel))]
|
||||
[TemplatePart(Name = ElementImageViewer, Type = typeof(ImageViewer))]
|
||||
public class ImageBrowser : Window
|
||||
{
|
||||
/// <summary>
|
||||
/// 图片浏览器
|
||||
/// </summary>
|
||||
[TemplatePart(Name = ElementPanelTop, Type = typeof(Panel))]
|
||||
[TemplatePart(Name = ElementImageViewer, Type = typeof(ImageViewer))]
|
||||
public class ImageBrowser : Window
|
||||
#region Constants
|
||||
|
||||
private const string ElementPanelTop = "PART_PanelTop";
|
||||
|
||||
private const string ElementImageViewer = "PART_ImageViewer";
|
||||
|
||||
#endregion Constants
|
||||
|
||||
#region Data
|
||||
|
||||
private Panel _panelTop;
|
||||
|
||||
private ImageViewer _imageViewer;
|
||||
|
||||
#endregion Data
|
||||
|
||||
static ImageBrowser()
|
||||
{
|
||||
#region Constants
|
||||
IsFullScreenProperty.AddOwner(typeof(ImageBrowser), new PropertyMetadata(ValueBoxes.FalseBox));
|
||||
}
|
||||
|
||||
private const string ElementPanelTop = "PART_PanelTop";
|
||||
public ImageBrowser()
|
||||
{
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.Close, ButtonClose_OnClick));
|
||||
|
||||
private const string ElementImageViewer = "PART_ImageViewer";
|
||||
WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||
WindowStyle = WindowStyle.None;
|
||||
AllowsTransparency = true;
|
||||
}
|
||||
|
||||
#endregion Constants
|
||||
|
||||
#region Data
|
||||
|
||||
private Panel _panelTop;
|
||||
|
||||
private ImageViewer _imageViewer;
|
||||
|
||||
#endregion Data
|
||||
|
||||
static ImageBrowser()
|
||||
/// <summary>
|
||||
/// 带一个图片Uri的构造函数
|
||||
/// </summary>
|
||||
/// <param name="uri"></param>
|
||||
public ImageBrowser(Uri uri) : this()
|
||||
{
|
||||
Loaded += (s, e) =>
|
||||
{
|
||||
IsFullScreenProperty.AddOwner(typeof(ImageBrowser), new PropertyMetadata(ValueBoxes.FalseBox));
|
||||
}
|
||||
|
||||
public ImageBrowser()
|
||||
{
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.Close, ButtonClose_OnClick));
|
||||
|
||||
WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||
WindowStyle = WindowStyle.None;
|
||||
AllowsTransparency = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 带一个图片Uri的构造函数
|
||||
/// </summary>
|
||||
/// <param name="uri"></param>
|
||||
public ImageBrowser(Uri uri) : this()
|
||||
{
|
||||
Loaded += (s, e) =>
|
||||
try
|
||||
{
|
||||
try
|
||||
_imageViewer.ImageSource = BitmapFrame.Create(uri);
|
||||
_imageViewer.ImgPath = uri.AbsolutePath;
|
||||
|
||||
if (File.Exists(_imageViewer.ImgPath))
|
||||
{
|
||||
_imageViewer.ImageSource = BitmapFrame.Create(uri);
|
||||
_imageViewer.ImgPath = uri.AbsolutePath;
|
||||
|
||||
if (File.Exists(_imageViewer.ImgPath))
|
||||
{
|
||||
var info = new FileInfo(_imageViewer.ImgPath);
|
||||
_imageViewer.ImgSize = info.Length;
|
||||
}
|
||||
var info = new FileInfo(_imageViewer.ImgPath);
|
||||
_imageViewer.ImgSize = info.Length;
|
||||
}
|
||||
catch
|
||||
{
|
||||
MessageBox.Show(Properties.Langs.Lang.ErrorImgPath);
|
||||
}
|
||||
};
|
||||
}
|
||||
catch
|
||||
{
|
||||
MessageBox.Show(Properties.Langs.Lang.ErrorImgPath);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 带一个图片路径的构造函数
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
public ImageBrowser(string path) : this(new Uri(path))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
if (_panelTop != null)
|
||||
{
|
||||
_panelTop.MouseLeftButtonDown -= PanelTopOnMouseLeftButtonDown;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 带一个图片路径的构造函数
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
public ImageBrowser(string path) : this(new Uri(path))
|
||||
if (_imageViewer != null)
|
||||
{
|
||||
|
||||
_imageViewer.MouseLeftButtonDown -= ImageViewer_MouseLeftButtonDown;
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
base.OnApplyTemplate();
|
||||
|
||||
_panelTop = GetTemplateChild(ElementPanelTop) as Panel;
|
||||
_imageViewer = GetTemplateChild(ElementImageViewer) as ImageViewer;
|
||||
|
||||
if (_panelTop != null)
|
||||
{
|
||||
if (_panelTop != null)
|
||||
{
|
||||
_panelTop.MouseLeftButtonDown -= PanelTopOnMouseLeftButtonDown;
|
||||
}
|
||||
|
||||
if (_imageViewer != null)
|
||||
{
|
||||
_imageViewer.MouseLeftButtonDown -= ImageViewer_MouseLeftButtonDown;
|
||||
}
|
||||
|
||||
base.OnApplyTemplate();
|
||||
|
||||
_panelTop = GetTemplateChild(ElementPanelTop) as Panel;
|
||||
_imageViewer = GetTemplateChild(ElementImageViewer) as ImageViewer;
|
||||
|
||||
if (_panelTop != null)
|
||||
{
|
||||
_panelTop.MouseLeftButtonDown += PanelTopOnMouseLeftButtonDown;
|
||||
}
|
||||
|
||||
if (_imageViewer != null)
|
||||
{
|
||||
_imageViewer.MouseLeftButtonDown += ImageViewer_MouseLeftButtonDown;
|
||||
}
|
||||
_panelTop.MouseLeftButtonDown += PanelTopOnMouseLeftButtonDown;
|
||||
}
|
||||
|
||||
private void ButtonClose_OnClick(object sender, RoutedEventArgs e) => Close();
|
||||
|
||||
private void PanelTopOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
if (_imageViewer != null)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
DragMove();
|
||||
}
|
||||
}
|
||||
|
||||
private void ImageViewer_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed && !(_imageViewer.ImageWidth > ActualWidth || _imageViewer.ImageHeight > ActualHeight))
|
||||
{
|
||||
DragMove();
|
||||
}
|
||||
_imageViewer.MouseLeftButtonDown += ImageViewer_MouseLeftButtonDown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ButtonClose_OnClick(object sender, RoutedEventArgs e) => Close();
|
||||
|
||||
private void PanelTopOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
DragMove();
|
||||
}
|
||||
}
|
||||
|
||||
private void ImageViewer_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed && !(_imageViewer.ImageWidth > ActualWidth || _imageViewer.ImageHeight > ActualHeight))
|
||||
{
|
||||
DragMove();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -7,229 +7,228 @@ using HandyControl.Data;
|
||||
using HandyControl.Interactivity;
|
||||
using HandyControl.Tools;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
namespace HandyControl.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// 弹出窗口
|
||||
/// </summary>
|
||||
[TemplatePart(Name = ElementMainBorder, Type = typeof(Border))]
|
||||
[TemplatePart(Name = ElementTitleBlock, Type = typeof(TextBlock))]
|
||||
public class PopupWindow : System.Windows.Window
|
||||
{
|
||||
/// <summary>
|
||||
/// 弹出窗口
|
||||
/// </summary>
|
||||
[TemplatePart(Name = ElementMainBorder, Type = typeof(Border))]
|
||||
[TemplatePart(Name = ElementTitleBlock, Type = typeof(TextBlock))]
|
||||
public class PopupWindow : System.Windows.Window
|
||||
#region Constants
|
||||
|
||||
private const string ElementMainBorder = "PART_MainBorder";
|
||||
|
||||
private const string ElementTitleBlock = "PART_TitleBlock";
|
||||
|
||||
#endregion Constants
|
||||
|
||||
private Border _mainBorder;
|
||||
|
||||
private TextBlock _titleBlock;
|
||||
|
||||
private bool _showBackground = true;
|
||||
|
||||
private FrameworkElement _targetElement;
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
#region Constants
|
||||
|
||||
private const string ElementMainBorder = "PART_MainBorder";
|
||||
|
||||
private const string ElementTitleBlock = "PART_TitleBlock";
|
||||
|
||||
#endregion Constants
|
||||
|
||||
private Border _mainBorder;
|
||||
|
||||
private TextBlock _titleBlock;
|
||||
|
||||
private bool _showBackground = true;
|
||||
|
||||
private FrameworkElement _targetElement;
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
if (_titleBlock != null)
|
||||
{
|
||||
if (_titleBlock != null)
|
||||
{
|
||||
_titleBlock.MouseLeftButtonDown -= TitleBlock_OnMouseLeftButtonDown;
|
||||
}
|
||||
|
||||
base.OnApplyTemplate();
|
||||
|
||||
_mainBorder = GetTemplateChild(ElementMainBorder) as Border;
|
||||
_titleBlock = GetTemplateChild(ElementTitleBlock) as TextBlock;
|
||||
|
||||
if (_titleBlock != null)
|
||||
{
|
||||
_titleBlock.MouseLeftButtonDown += TitleBlock_OnMouseLeftButtonDown;
|
||||
}
|
||||
|
||||
if (PopupElement != null)
|
||||
{
|
||||
_mainBorder.Child = PopupElement;
|
||||
}
|
||||
_titleBlock.MouseLeftButtonDown -= TitleBlock_OnMouseLeftButtonDown;
|
||||
}
|
||||
|
||||
internal static readonly DependencyProperty ContentStrProperty = DependencyProperty.Register(
|
||||
"ContentStr", typeof(string), typeof(PopupWindow), new PropertyMetadata(default(string)));
|
||||
base.OnApplyTemplate();
|
||||
|
||||
internal string ContentStr
|
||||
_mainBorder = GetTemplateChild(ElementMainBorder) as Border;
|
||||
_titleBlock = GetTemplateChild(ElementTitleBlock) as TextBlock;
|
||||
|
||||
if (_titleBlock != null)
|
||||
{
|
||||
get => (string) GetValue(ContentStrProperty);
|
||||
set => SetValue(ContentStrProperty, value);
|
||||
_titleBlock.MouseLeftButtonDown += TitleBlock_OnMouseLeftButtonDown;
|
||||
}
|
||||
|
||||
private bool IsDialog { get; set; }
|
||||
|
||||
public PopupWindow()
|
||||
if (PopupElement != null)
|
||||
{
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.Close, CloseButton_OnClick));
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.Confirm, ButtonOk_OnClick));
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.Cancel, ButtonCancle_OnClick));
|
||||
|
||||
Closing += (sender, args) =>
|
||||
{
|
||||
if (!IsDialog)
|
||||
Owner?.Focus();
|
||||
};
|
||||
Loaded += (s, e) =>
|
||||
{
|
||||
if (!_showBackground)
|
||||
{
|
||||
var point = ArithmeticHelper.CalSafePoint(_targetElement, PopupElement, BorderThickness);
|
||||
Left = point.X;
|
||||
Top = point.Y;
|
||||
Opacity = 1;
|
||||
}
|
||||
};
|
||||
try
|
||||
{
|
||||
Owner = Application.Current.MainWindow;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
public PopupWindow(System.Windows.Window owner) : this() => Owner = owner;
|
||||
|
||||
private void CloseButton_OnClick(object sender, RoutedEventArgs e) => Close();
|
||||
|
||||
public FrameworkElement PopupElement { get; set; }
|
||||
|
||||
public static readonly DependencyProperty ShowTitleProperty = DependencyProperty.Register(
|
||||
"ShowTitle", typeof(bool), typeof(PopupWindow), new PropertyMetadata(ValueBoxes.TrueBox));
|
||||
|
||||
public bool ShowTitle
|
||||
{
|
||||
get => (bool) GetValue(ShowTitleProperty);
|
||||
set => SetValue(ShowTitleProperty, ValueBoxes.BooleanBox(value));
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ShowCancelProperty = DependencyProperty.Register(
|
||||
"ShowCancel", typeof(bool), typeof(PopupWindow), new PropertyMetadata(ValueBoxes.FalseBox));
|
||||
|
||||
public bool ShowCancel
|
||||
{
|
||||
get => (bool) GetValue(ShowCancelProperty);
|
||||
set => SetValue(ShowCancelProperty, ValueBoxes.BooleanBox(value));
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ShowBorderProperty = DependencyProperty.Register(
|
||||
"ShowBorder", typeof(bool), typeof(PopupWindow), new PropertyMetadata(ValueBoxes.FalseBox));
|
||||
|
||||
public bool ShowBorder
|
||||
{
|
||||
get => (bool) GetValue(ShowBorderProperty);
|
||||
set => SetValue(ShowBorderProperty, ValueBoxes.BooleanBox(value));
|
||||
}
|
||||
|
||||
private void TitleBlock_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
DragMove();
|
||||
}
|
||||
}
|
||||
|
||||
public void Show(FrameworkElement element, bool showBackground = true)
|
||||
{
|
||||
if (!showBackground)
|
||||
{
|
||||
Opacity = 0;
|
||||
AllowsTransparency = true;
|
||||
WindowStyle = WindowStyle.None;
|
||||
ShowTitle = false;
|
||||
MinWidth = 0;
|
||||
MinHeight = 0;
|
||||
}
|
||||
|
||||
_showBackground = showBackground;
|
||||
_targetElement = element;
|
||||
Show();
|
||||
}
|
||||
|
||||
public void ShowDialog(FrameworkElement element, bool showBackground = true)
|
||||
{
|
||||
if (!showBackground)
|
||||
{
|
||||
Opacity = 0;
|
||||
AllowsTransparency = true;
|
||||
WindowStyle = WindowStyle.None;
|
||||
ShowTitle = false;
|
||||
MinWidth = 0;
|
||||
MinHeight = 0;
|
||||
}
|
||||
|
||||
_showBackground = showBackground;
|
||||
_targetElement = element;
|
||||
ShowDialog();
|
||||
}
|
||||
|
||||
public void Show(System.Windows.Window element, Point point)
|
||||
{
|
||||
Left = element.Left + point.X;
|
||||
Top = element.Top + point.Y;
|
||||
Show();
|
||||
}
|
||||
|
||||
public static void Show(string message)
|
||||
{
|
||||
var window = new PopupWindow
|
||||
{
|
||||
AllowsTransparency = true,
|
||||
WindowStyle = WindowStyle.None,
|
||||
ContentStr = message,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterScreen,
|
||||
Background = ResourceHelper.GetResourceInternal<Brush>(ResourceToken.PrimaryBrush)
|
||||
};
|
||||
window.Show();
|
||||
}
|
||||
|
||||
public static bool? ShowDialog(string message, string title = default, bool showCancel = false)
|
||||
{
|
||||
var window = new PopupWindow
|
||||
{
|
||||
AllowsTransparency = true,
|
||||
WindowStyle = WindowStyle.None,
|
||||
ContentStr = message,
|
||||
IsDialog = true,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterScreen,
|
||||
ShowBorder = true,
|
||||
Title = string.IsNullOrEmpty(title) ? Properties.Langs.Lang.Tip : title,
|
||||
ShowCancel = showCancel
|
||||
};
|
||||
return window.ShowDialog();
|
||||
}
|
||||
|
||||
private void ButtonOk_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (IsDialog)
|
||||
{
|
||||
DialogResult = true;
|
||||
}
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ButtonCancle_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (IsDialog)
|
||||
{
|
||||
DialogResult = false;
|
||||
}
|
||||
Close();
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
base.OnClosed(e);
|
||||
PopupElement = null;
|
||||
_mainBorder.Child = PopupElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static readonly DependencyProperty ContentStrProperty = DependencyProperty.Register(
|
||||
"ContentStr", typeof(string), typeof(PopupWindow), new PropertyMetadata(default(string)));
|
||||
|
||||
internal string ContentStr
|
||||
{
|
||||
get => (string) GetValue(ContentStrProperty);
|
||||
set => SetValue(ContentStrProperty, value);
|
||||
}
|
||||
|
||||
private bool IsDialog { get; set; }
|
||||
|
||||
public PopupWindow()
|
||||
{
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.Close, CloseButton_OnClick));
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.Confirm, ButtonOk_OnClick));
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.Cancel, ButtonCancle_OnClick));
|
||||
|
||||
Closing += (sender, args) =>
|
||||
{
|
||||
if (!IsDialog)
|
||||
Owner?.Focus();
|
||||
};
|
||||
Loaded += (s, e) =>
|
||||
{
|
||||
if (!_showBackground)
|
||||
{
|
||||
var point = ArithmeticHelper.CalSafePoint(_targetElement, PopupElement, BorderThickness);
|
||||
Left = point.X;
|
||||
Top = point.Y;
|
||||
Opacity = 1;
|
||||
}
|
||||
};
|
||||
try
|
||||
{
|
||||
Owner = Application.Current.MainWindow;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
public PopupWindow(System.Windows.Window owner) : this() => Owner = owner;
|
||||
|
||||
private void CloseButton_OnClick(object sender, RoutedEventArgs e) => Close();
|
||||
|
||||
public FrameworkElement PopupElement { get; set; }
|
||||
|
||||
public static readonly DependencyProperty ShowTitleProperty = DependencyProperty.Register(
|
||||
"ShowTitle", typeof(bool), typeof(PopupWindow), new PropertyMetadata(ValueBoxes.TrueBox));
|
||||
|
||||
public bool ShowTitle
|
||||
{
|
||||
get => (bool) GetValue(ShowTitleProperty);
|
||||
set => SetValue(ShowTitleProperty, ValueBoxes.BooleanBox(value));
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ShowCancelProperty = DependencyProperty.Register(
|
||||
"ShowCancel", typeof(bool), typeof(PopupWindow), new PropertyMetadata(ValueBoxes.FalseBox));
|
||||
|
||||
public bool ShowCancel
|
||||
{
|
||||
get => (bool) GetValue(ShowCancelProperty);
|
||||
set => SetValue(ShowCancelProperty, ValueBoxes.BooleanBox(value));
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ShowBorderProperty = DependencyProperty.Register(
|
||||
"ShowBorder", typeof(bool), typeof(PopupWindow), new PropertyMetadata(ValueBoxes.FalseBox));
|
||||
|
||||
public bool ShowBorder
|
||||
{
|
||||
get => (bool) GetValue(ShowBorderProperty);
|
||||
set => SetValue(ShowBorderProperty, ValueBoxes.BooleanBox(value));
|
||||
}
|
||||
|
||||
private void TitleBlock_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
DragMove();
|
||||
}
|
||||
}
|
||||
|
||||
public void Show(FrameworkElement element, bool showBackground = true)
|
||||
{
|
||||
if (!showBackground)
|
||||
{
|
||||
Opacity = 0;
|
||||
AllowsTransparency = true;
|
||||
WindowStyle = WindowStyle.None;
|
||||
ShowTitle = false;
|
||||
MinWidth = 0;
|
||||
MinHeight = 0;
|
||||
}
|
||||
|
||||
_showBackground = showBackground;
|
||||
_targetElement = element;
|
||||
Show();
|
||||
}
|
||||
|
||||
public void ShowDialog(FrameworkElement element, bool showBackground = true)
|
||||
{
|
||||
if (!showBackground)
|
||||
{
|
||||
Opacity = 0;
|
||||
AllowsTransparency = true;
|
||||
WindowStyle = WindowStyle.None;
|
||||
ShowTitle = false;
|
||||
MinWidth = 0;
|
||||
MinHeight = 0;
|
||||
}
|
||||
|
||||
_showBackground = showBackground;
|
||||
_targetElement = element;
|
||||
ShowDialog();
|
||||
}
|
||||
|
||||
public void Show(System.Windows.Window element, Point point)
|
||||
{
|
||||
Left = element.Left + point.X;
|
||||
Top = element.Top + point.Y;
|
||||
Show();
|
||||
}
|
||||
|
||||
public static void Show(string message)
|
||||
{
|
||||
var window = new PopupWindow
|
||||
{
|
||||
AllowsTransparency = true,
|
||||
WindowStyle = WindowStyle.None,
|
||||
ContentStr = message,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterScreen,
|
||||
Background = ResourceHelper.GetResourceInternal<Brush>(ResourceToken.PrimaryBrush)
|
||||
};
|
||||
window.Show();
|
||||
}
|
||||
|
||||
public static bool? ShowDialog(string message, string title = default, bool showCancel = false)
|
||||
{
|
||||
var window = new PopupWindow
|
||||
{
|
||||
AllowsTransparency = true,
|
||||
WindowStyle = WindowStyle.None,
|
||||
ContentStr = message,
|
||||
IsDialog = true,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterScreen,
|
||||
ShowBorder = true,
|
||||
Title = string.IsNullOrEmpty(title) ? Properties.Langs.Lang.Tip : title,
|
||||
ShowCancel = showCancel
|
||||
};
|
||||
return window.ShowDialog();
|
||||
}
|
||||
|
||||
private void ButtonOk_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (IsDialog)
|
||||
{
|
||||
DialogResult = true;
|
||||
}
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ButtonCancle_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (IsDialog)
|
||||
{
|
||||
DialogResult = false;
|
||||
}
|
||||
Close();
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
base.OnClosed(e);
|
||||
PopupElement = null;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user