Files
Shrlalgo.RvKits/WPFluent/Controls/PendingBox/PendingBox.cs

193 lines
5.9 KiB
C#
Raw Normal View History

2025-04-24 20:56:44 +08:00
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Windows.Threading;
2025-04-24 20:56:44 +08:00
using WPFluent.Interop;
namespace WPFluent.Controls;
public static class PendingBox
{
public static IPendingHandler Show(string? message = null, string? title = null, bool isShowCancel = false, bool closeOnCanceled = true)
{
return Show(null, message, title, isShowCancel, closeOnCanceled);
}
public static IPendingHandler Show(Window? owner, string? message, string? title = null, bool isShowCancel = false, bool closeOnCanceled = true)
{
return ShowCore(owner, message, title, isShowCancel, closeOnCanceled);
}
[SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance")]
[SuppressMessage("CodeQuality", "IDE0079:Remove unnecessary suppression")]
private static IPendingHandler ShowCore(Window? owner, string? message, string? title, bool isShowCancel, bool closeOnCanceled = true)
{
owner
??= Application.Current.Windows.OfType<Window>().FirstOrDefault(window => window.IsActive)
?? Application.Current.MainWindow;
Dispatcher dispatcher = owner?.Dispatcher ?? Application.Current.Dispatcher;
return dispatcher.Invoke(() =>
{
PendingBoxDialog dialog = new()
{
Owner = owner,
Title = title ?? string.Empty,
Message = message ?? ("加载中" + "..."),
IsShowCancel = isShowCancel,
WindowStartupLocation = owner is null ? WindowStartupLocation.CenterScreen : WindowStartupLocation.CenterOwner
};
PendingHandler pending = new(dialog)
{
CloseOnCanceled = closeOnCanceled,
};
dialog.Closing += (_, e) =>
{
if (!e.Cancel)
{
2025-04-24 20:56:44 +08:00
User32.SetForegroundWindow(new WindowInteropHelper(owner).Handle);
}
};
dialog.Closed += (s, e) =>
{
pending.RaiseClosedEvent(s, e);
2025-04-24 20:56:44 +08:00
User32.EnableWindow(new WindowInteropHelper(owner).Handle, true);
User32.SetForegroundWindow(new WindowInteropHelper(owner).Handle);
};
dialog.Canceled += (s, e) =>
{
pending.RaiseCanceledEvent(s, e);
2025-04-24 20:56:44 +08:00
User32.EnableWindow(new WindowInteropHelper(owner).Handle, true);
};
2025-04-24 20:56:44 +08:00
User32.EnableWindow(new WindowInteropHelper(owner).Handle, false);
dialog.Show();
return pending;
});
}
[SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance")]
[SuppressMessage("Style", "IDE0060:Remove unused parameter")]
[SuppressMessage("CodeQuality", "IDE0079:Remove unnecessary suppression")]
private static IPendingHandler ShowCoreAsync(Window? owner, string? message, string? title, bool isShowCancel, bool closeOnCanceled = true)
{
Point? center = null;
try
{
owner?.Dispatcher.Invoke(() =>
{
Rect rect = new();
2025-04-24 20:56:44 +08:00
User32.GetWindowRect(new WindowInteropHelper(owner).Handle, out rect);
Point p = new(rect.Left + (int)((rect.Right - rect.Left) / 2d), rect.Top + (int)((rect.Bottom - rect.Top) / 2d));
center = new(p.X, p.Y);
});
}
catch
{
///
}
PendingBoxDialog dialog = new()
{
Title = title ?? string.Empty,
Message = message ?? ("加载中" + "..."),
IsShowCancel = isShowCancel,
WindowStartupLocation = WindowStartupLocation.CenterScreen,
};
PendingHandlerAsync pending = new(dialog);
dialog.Closing += (_, e) =>
{
if (!e.Cancel)
{
2025-04-24 20:56:44 +08:00
User32.SetForegroundWindow(new WindowInteropHelper(owner).Handle);
}
};
dialog.Closed += (s, e) =>
{
pending.RaiseClosedEvent(s, e);
pending.Close();
};
dialog.Canceled += (s, e) =>
{
pending.RaiseCanceledEvent(s, e);
pending.Close();
};
if (center != null)
{
dialog.Loaded += (_, _) =>
{
try
{
LayoutHelper.MoveWindowCenter(dialog, (Point)center);
}
catch
{
///
}
};
}
return pending;
}
}
file static class LayoutHelper
{
public static void MoveWindowCenter(Window window, Point center)
{
if (window == null)
{
return;
}
nint hwnd = new WindowInteropHelper(window).Handle;
if (hwnd == IntPtr.Zero)
{
return;
}
Rect rect = default;
2025-04-24 20:56:44 +08:00
User32.GetWindowRect(hwnd, out rect);
nint monitorHandle = User32.MonitorFromWindow(hwnd, User32.MonitorDefaultTo.Nearest);
User32.MONITORINFO monitorInfo = new()
{
cbSize = Marshal.SizeOf<User32.MONITORINFO>()
};
2025-04-24 20:56:44 +08:00
User32.GetMonitorInfo(monitorHandle, ref monitorInfo);
Rect screen = monitorInfo.rcMonitor;
(double x, double y) = ((int)center.X, (int)center.Y);
(double w, double h) = (rect.Right - rect.Left, rect.Bottom - rect.Top);
(x, y) = ((int)(x - w / 2d), (int)(y - h / 2d));
if (x + w > screen.Right)
{
x = screen.Right - w;
}
else if (x - w < screen.Left)
{
x = screen.Left + w;
}
if (y + h > screen.Bottom)
{
y = screen.Bottom - h;
}
else if (y - h < screen.Top)
{
y = screen.Top + h;
}
2025-04-24 20:56:44 +08:00
User32.MoveWindow(hwnd, x, y, w, h, false);
}
}