diff --git a/src/Snap.Hutao/SettingsUI/Styles/Button.xaml b/src/Snap.Hutao/SettingsUI/Styles/Button.xaml
index 871b51c5..c1827fea 100644
--- a/src/Snap.Hutao/SettingsUI/Styles/Button.xaml
+++ b/src/Snap.Hutao/SettingsUI/Styles/Button.xaml
@@ -7,7 +7,7 @@
diff --git a/src/Snap.Hutao/Snap.Hutao.Win32/Foundation/POINT.cs b/src/Snap.Hutao/Snap.Hutao.Win32/Foundation/POINT.cs
new file mode 100644
index 00000000..ccdb9103
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao.Win32/Foundation/POINT.cs
@@ -0,0 +1,10 @@
+namespace Windows.Win32.Foundation;
+
+public partial struct POINT
+{
+ public POINT(int x,int y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao.Win32/Foundation/RECT.cs b/src/Snap.Hutao/Snap.Hutao.Win32/Foundation/RECT.cs
new file mode 100644
index 00000000..45fd53b3
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao.Win32/Foundation/RECT.cs
@@ -0,0 +1,19 @@
+namespace Windows.Win32.Foundation;
+public partial struct RECT
+{
+ public RECT(int left, int top, int right, int bottom)
+ {
+ this.left = left;
+ this.top = top;
+ this.right = right;
+ this.bottom = bottom;
+ }
+
+ public int Size
+ {
+ get
+ {
+ return (right - left) * (bottom - top);
+ }
+ }
+}
diff --git a/src/Snap.Hutao/Snap.Hutao.Win32/UI/WindowsAndMessaging/WINDOWPLACEMENT.cs b/src/Snap.Hutao/Snap.Hutao.Win32/UI/WindowsAndMessaging/WINDOWPLACEMENT.cs
new file mode 100644
index 00000000..0e7f5119
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao.Win32/UI/WindowsAndMessaging/WINDOWPLACEMENT.cs
@@ -0,0 +1,38 @@
+using System.Runtime.InteropServices;
+using Windows.Win32.Foundation;
+
+namespace Windows.Win32.UI.WindowsAndMessaging;
+public partial struct WINDOWPLACEMENT
+{
+ ///
+ /// Gets the default (empty) value.
+ ///
+ public static WINDOWPLACEMENT Default
+ {
+ get
+ {
+ return new WINDOWPLACEMENT()
+ {
+ length = (uint)Marshal.SizeOf(),
+ };
+ }
+ }
+
+ ///
+ /// 构造一个新的
+ ///
+ /// 最大点
+ /// 正常位置
+ /// 显示命令
+ /// 窗体位置
+ public static WINDOWPLACEMENT Create(POINT ptMaxPosition, RECT rcNormalPosition, SHOW_WINDOW_CMD showCmd)
+ {
+ WINDOWPLACEMENT result = Default;
+
+ result.ptMaxPosition = ptMaxPosition;
+ result.rcNormalPosition = rcNormalPosition;
+ result.showCmd = showCmd;
+
+ return result;
+ }
+}
diff --git a/src/Snap.Hutao/Snap.Hutao.Win32/Unsafe.cs b/src/Snap.Hutao/Snap.Hutao.Win32/Unsafe.cs
new file mode 100644
index 00000000..28a85b6e
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao.Win32/Unsafe.cs
@@ -0,0 +1,18 @@
+using Windows.Win32.UI.WindowsAndMessaging;
+
+namespace Snap.Hutao.Win32;
+public class Unsafe
+{
+ ///
+ /// 使用指针操作简化封送
+ ///
+ ///
+ ///
+ ///
+ public static unsafe void SetMinTrackSize(nint lPARAM, float minWidth, float minHeight)
+ {
+ MINMAXINFO* rect2 = (MINMAXINFO*)lPARAM;
+ rect2->ptMinTrackSize.x = (int)Math.Max(minWidth, rect2->ptMinTrackSize.x);
+ rect2->ptMinTrackSize.y = (int)Math.Max(minHeight, rect2->ptMinTrackSize.y);
+ }
+}
diff --git a/src/Snap.Hutao/Snap.Hutao/App.xaml b/src/Snap.Hutao/Snap.Hutao/App.xaml
index 43009bea..b3b425fb 100644
--- a/src/Snap.Hutao/Snap.Hutao/App.xaml
+++ b/src/Snap.Hutao/Snap.Hutao/App.xaml
@@ -25,7 +25,6 @@
6,6,0,0
0,6,6,0
0,0,6,6
- 4
diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Behavior/ContentDialogBehavior.cs b/src/Snap.Hutao/Snap.Hutao/Control/Behavior/ContentDialogBehavior.cs
new file mode 100644
index 00000000..4f871435
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Control/Behavior/ContentDialogBehavior.cs
@@ -0,0 +1,34 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using CommunityToolkit.WinUI.UI.Behaviors;
+using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Media;
+using Microsoft.UI.Xaml.Shapes;
+
+namespace Snap.Hutao.Control.Behavior;
+
+///
+/// Make ContentDialog's SmokeLayerBackground dsiplay over custom titleBar
+///
+public class ContentDialogBehavior : BehaviorBase
+{
+ ///
+ protected override void OnAssociatedObjectLoaded()
+ {
+ DependencyObject parent = VisualTreeHelper.GetParent(AssociatedObject);
+ DependencyObject child = VisualTreeHelper.GetChild(parent, 2);
+ Rectangle smokeLayerBackground = (Rectangle)child;
+
+ smokeLayerBackground.Margin = new Thickness(0);
+ smokeLayerBackground.RegisterPropertyChangedCallback(FrameworkElement.MarginProperty, OnMarginChanged);
+ }
+
+ private static void OnMarginChanged(DependencyObject sender, DependencyProperty property)
+ {
+ if (property == FrameworkElement.MarginProperty)
+ {
+ sender.ClearValue(property);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Logging/EventIds.cs b/src/Snap.Hutao/Snap.Hutao/Core/Logging/EventIds.cs
index 97c405d1..b0040760 100644
--- a/src/Snap.Hutao/Snap.Hutao/Core/Logging/EventIds.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Core/Logging/EventIds.cs
@@ -78,4 +78,9 @@ internal static class EventIds
/// 背景状态
///
public static readonly EventId BackdropState = 200001;
+
+ ///
+ /// 子类控制
+ ///
+ public static readonly EventId SubClassing = 200002;
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Core/WindowManager.cs b/src/Snap.Hutao/Snap.Hutao/Core/WindowManager.cs
index 74c36215..607df41f 100644
--- a/src/Snap.Hutao/Snap.Hutao/Core/WindowManager.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Core/WindowManager.cs
@@ -5,30 +5,30 @@ using Microsoft.UI.Xaml;
using Snap.Hutao.Control.HostBackdrop;
using Snap.Hutao.Core.Logging;
using Snap.Hutao.Core.Setting;
-using System.Runtime.InteropServices;
-using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.UI.Shell;
using Windows.Win32.UI.WindowsAndMessaging;
using WinRT.Interop;
+using static Windows.Win32.PInvoke;
+
namespace Snap.Hutao.Core;
///
-/// 窗口状态管理器
-/// 主要包含了各类 P/Inoke 代码
+/// 窗口管理器
+/// 主要包含了针对窗体的 P/Inoke 逻辑
///
internal class WindowManager
{
- private const int MinWidth = 800;
- private const int MinHeight = 600;
-
+ private const int MinWidth = 848;
+ private const int MinHeight = 524;
+ private const int SubclassId = 101;
private readonly HWND handle;
private readonly Window window;
private readonly UIElement titleBar;
private readonly ILogger logger;
- // We have to explictly hold a reference to the SUBCLASSPROC
+ // We have to explictly hold a reference to the SUBCLASSPROC,
// otherwise will casuse System.ExecutionEngineException
private SUBCLASSPROC? subClassProc;
@@ -53,17 +53,14 @@ internal class WindowManager
int right = LocalSetting.GetValueType(SettingKeys.WindowRight);
int bottom = LocalSetting.GetValueType(SettingKeys.WindowBottom);
- return new() { left = left, top = top, right = right, bottom = bottom };
+ return new(left, top, right, bottom);
}
private static void SaveWindowRect(HWND handle)
{
- WINDOWPLACEMENT windowPlacement = new()
- {
- length = (uint)Marshal.SizeOf(),
- };
+ WINDOWPLACEMENT windowPlacement = WINDOWPLACEMENT.Default;
- PInvoke.GetWindowPlacement(handle, ref windowPlacement);
+ GetWindowPlacement(handle, ref windowPlacement);
LocalSetting.Set(SettingKeys.WindowLeft, windowPlacement.rcNormalPosition.left);
LocalSetting.Set(SettingKeys.WindowTop, windowPlacement.rcNormalPosition.top);
@@ -77,52 +74,42 @@ internal class WindowManager
window.SetTitleBar(titleBar);
window.Closed += OnWindowClosed;
- PInvoke.SetWindowText(handle, "胡桃");
+ SetWindowText(handle, "胡桃");
RECT rect = RetriveWindowRect();
- if ((rect.right - rect.left) * (rect.bottom - rect.top) > 0)
+ if (rect.Size > 0)
{
- WINDOWPLACEMENT windowPlacement = new()
- {
- length = (uint)Marshal.SizeOf(),
- showCmd = SHOW_WINDOW_CMD.SW_SHOWNORMAL,
- ptMaxPosition = new() { x = -1, y = -1 },
- rcNormalPosition = rect,
- };
-
- PInvoke.SetWindowPlacement(handle, in windowPlacement);
+ WINDOWPLACEMENT windowPlacement = WINDOWPLACEMENT.Create(new(-1, -1), rect, SHOW_WINDOW_CMD.SW_SHOWNORMAL);
+ SetWindowPlacement(handle, in windowPlacement);
}
bool micaApplied = new SystemBackdrop(window).TrySetBackdrop();
logger.LogInformation(EventIds.BackdropState, "Apply {name} : {result}", nameof(SystemBackdrop), micaApplied ? "succeed" : "failed");
- subClassProc = new(OnWindowProcedure);
- _ = PInvoke.SetWindowSubclass(handle, subClassProc, 101, 0);
+ subClassProc = new(OnSubclassProcedure);
+ bool subClassApplied = SetWindowSubclass(handle, subClassProc, SubclassId, 0);
+ logger.LogInformation(EventIds.SubClassing, "Apply {name} : {result}", nameof(SUBCLASSPROC), subClassApplied ? "succeed" : "failed");
}
private void OnWindowClosed(object sender, WindowEventArgs args)
{
- PInvoke.RemoveWindowSubclass(handle, subClassProc, 101);
+ RemoveWindowSubclass(handle, subClassProc, SubclassId);
subClassProc = null;
SaveWindowRect(handle);
}
- private LRESULT OnWindowProcedure(HWND hwnd, uint uMsg, WPARAM wParam, LPARAM lParam, nuint uIdSubclass, nuint dwRefData)
+ private LRESULT OnSubclassProcedure(HWND hwnd, uint uMsg, WPARAM wParam, LPARAM lParam, nuint uIdSubclass, nuint dwRefData)
{
switch (uMsg)
{
- case PInvoke.WM_GETMINMAXINFO:
+ case WM_GETMINMAXINFO:
{
- uint dpi = PInvoke.GetDpiForWindow(handle);
+ uint dpi = GetDpiForWindow(handle);
float scalingFactor = dpi / 96f;
-
- MINMAXINFO minMaxInfo = Marshal.PtrToStructure(lParam);
- minMaxInfo.ptMinTrackSize.x = (int)Math.Max(MinWidth * scalingFactor, minMaxInfo.ptMinTrackSize.x);
- minMaxInfo.ptMinTrackSize.y = (int)Math.Max(MinHeight * scalingFactor, minMaxInfo.ptMinTrackSize.y);
- Marshal.StructureToPtr(minMaxInfo, lParam, true);
+ Win32.Unsafe.SetMinTrackSize(lParam, MinWidth * scalingFactor, MinHeight * scalingFactor);
break;
}
}
- return PInvoke.DefSubclassProc(hwnd, uMsg, wParam, lParam);
+ return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Dialog/UserDialog.xaml b/src/Snap.Hutao/Snap.Hutao/View/Dialog/UserDialog.xaml
index b1489dea..5adb851c 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Dialog/UserDialog.xaml
+++ b/src/Snap.Hutao/Snap.Hutao/View/Dialog/UserDialog.xaml
@@ -1,11 +1,12 @@
-
+
+
+
+
+ Margin="0,8,0,0"
+ Icon=""
+ Header="手动获取"
+ Description="进入我们的文档页面并按指示操作"
+ HorizontalAlignment="Stretch">
+ Margin="12,0,0,0"
+ Padding="4"
+ Content="立即前往"
+ NavigateUri="https://www.snapgenshin.com/documents/features/mhy-account-switch.html#%E5%A6%82%E4%BD%95%E8%8E%B7%E5%8F%96-cookie"/>
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Dialog/UserDialog.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Dialog/UserDialog.xaml.cs
index 683d15c6..49209b54 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Dialog/UserDialog.xaml.cs
+++ b/src/Snap.Hutao/Snap.Hutao/View/Dialog/UserDialog.xaml.cs
@@ -1,6 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Snap.Hutao.Core.Threading;
@@ -15,7 +16,7 @@ public sealed partial class UserDialog : ContentDialog
/// 构造一个新的添加用户对话框
///
/// 呈现的父窗口
- public UserDialog(Microsoft.UI.Xaml.Window window)
+ public UserDialog(Window window)
{
InitializeComponent();
XamlRoot = window.Content.XamlRoot;
diff --git a/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml.cs
index f68ebfcf..15a4bb68 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml.cs
+++ b/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml.cs
@@ -29,6 +29,6 @@ public sealed partial class MainView : UserControl
navigationService = Ioc.Default.GetRequiredService();
navigationService.Initialize(NavView, ContentFrame);
- //navigationService.Navigate(INavigationAwaiter.Default, true);
+ navigationService.Navigate(INavigationAwaiter.Default, true);
}
}
\ No newline at end of file