use AppWindow API if we can

This commit is contained in:
DismissedLight
2022-08-04 21:42:51 +08:00
parent 723ccff276
commit 4a289d72fc
16 changed files with 426 additions and 172 deletions

View File

@@ -0,0 +1,11 @@
using System.Runtime.InteropServices;
namespace Windows.Win32.Graphics.Gdi;
public partial struct MONITORINFO
{
public static MONITORINFO Default
{
get => new() { cbSize = (uint)Marshal.SizeOf<MONITORINFO>() };
}
}

View File

@@ -1,16 +1,30 @@
// ComCtl32
SetWindowSubclass
RemoveWindowSubclass
// Type definition
MINMAXINFO
//
DefSubclassProc
SetWindowSubclass
RemoveWindowSubclass
// User32
SetWindowText
GetDpiForWindow
GetMonitorInfo
GetWindowPlacement
SetWindowPlacement
// Type definition
MINMAXINFO
GetWindowRect
MonitorFromRect
SetWindowPos
SetWindowText
// Const value
WM_GETMINMAXINFO

View File

@@ -11,6 +11,7 @@
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.2.10-beta">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Windows.SDK.Win32Metadata" Version="24.0.1-preview" />
</ItemGroup>
</Project>

View File

@@ -11,10 +11,7 @@ public partial struct WINDOWPLACEMENT
{
get
{
return new WINDOWPLACEMENT()
{
length = (uint)Marshal.SizeOf<WINDOWPLACEMENT>(),
};
return new() { length = (uint)Marshal.SizeOf<WINDOWPLACEMENT>() };
}
}

View File

@@ -67,11 +67,7 @@ public partial class App : Application
get => ApplicationData.Current.LocalSettings;
}
/// <summary>
/// Invoked when the application is launched.
/// Any async operation in this method should be wrapped with try catch
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
/// <inheritdoc/>
[SuppressMessage("", "VSTHRD100")]
protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
@@ -83,7 +79,6 @@ public partial class App : Application
firstInstance.Activated += OnActivated;
Window = Ioc.Default.GetRequiredService<MainWindow>();
Window.Activate();
logger.LogInformation(EventIds.CommonLog, "Cache folder : {folder}", CacheFolder.Path);

View File

@@ -31,6 +31,7 @@ public abstract class CompositionImage : Microsoft.UI.Xaml.Controls.Control
private readonly IImageCache imageCache;
private SpriteVisual? spriteVisual;
private bool isShow = true;
/// <summary>
/// 构造一个新的单色图像
@@ -88,7 +89,7 @@ public abstract class CompositionImage : Microsoft.UI.Xaml.Controls.Control
if (exception is HttpRequestException httpRequestException)
{
infoBarService.Warning($"GET {uri}\n{httpRequestException}");
infoBarService.Error(httpRequestException, $"GET {uri}");
}
else
{
@@ -113,7 +114,6 @@ public abstract class CompositionImage : Microsoft.UI.Xaml.Controls.Control
}
else
{
// should hide
image.HideAsync(token).SafeForget(logger);
}
}
@@ -149,14 +149,22 @@ public abstract class CompositionImage : Microsoft.UI.Xaml.Controls.Control
}
}
private Task ShowAsync(CancellationToken token)
private async Task ShowAsync(CancellationToken token)
{
return AnimationBuilder.Create().Opacity(1d).StartAsync(this, token);
if (!isShow)
{
await AnimationBuilder.Create().Opacity(1d).StartAsync(this, token);
isShow = true;
}
}
private Task HideAsync(CancellationToken token)
private async Task HideAsync(CancellationToken token)
{
return AnimationBuilder.Create().Opacity(0d).StartAsync(this, token);
if (isShow)
{
await AnimationBuilder.Create().Opacity(0d).StartAsync(this, token);
isShow = false;
}
}
private void OnSizeChanged(object sender, SizeChangedEventArgs e)

View File

@@ -1,146 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.UI;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Snap.Hutao.Control.HostBackdrop;
using Snap.Hutao.Core.Logging;
using Snap.Hutao.Core.Setting;
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;
/// <summary>
/// 窗口管理器
/// 主要包含了针对窗体的 P/Inoke 逻辑
/// </summary>
internal class WindowManager
{
private const int MinWidth = 848;
private const int MinHeight = 524;
private const int SubclassId = 101;
private static readonly Windows.UI.Color SystemBaseLowColor = Windows.UI.Color.FromArgb(0x33, 0xFF, 0xFF, 0xFF);
private static readonly Windows.UI.Color SystemBaseMediumLowColor = Windows.UI.Color.FromArgb(0x66, 0xFF, 0xFF, 0xFF);
private readonly HWND handle;
private readonly Window window;
private readonly UIElement titleBar;
private readonly ILogger<WindowManager> logger;
// We have to explictly hold a reference to the SUBCLASSPROC,
// otherwise will casuse System.ExecutionEngineException
private SUBCLASSPROC? subClassProc;
/// <summary>
/// 构造一个新的窗口状态管理器
/// </summary>
/// <param name="window">窗口</param>
/// <param name="titleBar">充当标题栏的元素</param>
public WindowManager(Window window, UIElement titleBar)
{
this.window = window;
this.titleBar = titleBar;
logger = Ioc.Default.GetRequiredService<ILogger<WindowManager>>();
handle = (HWND)WindowNative.GetWindowHandle(window);
InitializeWindow();
}
private static RECT RetriveWindowRect()
{
int left = LocalSetting.GetValueType<int>(SettingKeys.WindowLeft);
int top = LocalSetting.GetValueType<int>(SettingKeys.WindowTop);
int right = LocalSetting.GetValueType<int>(SettingKeys.WindowRight);
int bottom = LocalSetting.GetValueType<int>(SettingKeys.WindowBottom);
return new(left, top, right, bottom);
}
private static void SaveWindowRect(HWND handle)
{
WINDOWPLACEMENT windowPlacement = WINDOWPLACEMENT.Default;
GetWindowPlacement(handle, ref windowPlacement);
LocalSetting.Set(SettingKeys.WindowLeft, windowPlacement.rcNormalPosition.left);
LocalSetting.Set(SettingKeys.WindowTop, windowPlacement.rcNormalPosition.top);
LocalSetting.Set(SettingKeys.WindowRight, windowPlacement.rcNormalPosition.right);
LocalSetting.Set(SettingKeys.WindowBottom, windowPlacement.rcNormalPosition.bottom);
}
private void InitializeWindow()
{
if (false && AppWindowTitleBar.IsCustomizationSupported())
{
AppWindow appWindow = GetAppWindow();
AppWindowTitleBar titleBar = appWindow.TitleBar;
titleBar.ExtendsContentIntoTitleBar = true;
titleBar.ButtonBackgroundColor = Colors.Transparent;
titleBar.ButtonHoverBackgroundColor = SystemBaseLowColor;
titleBar.ButtonPressedBackgroundColor = SystemBaseMediumLowColor;
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
// appWindow.TitleBar.SetDragRectangles();
appWindow.Title = "胡桃";
}
else
{
window.ExtendsContentIntoTitleBar = true;
window.SetTitleBar(titleBar);
SetWindowText(handle, "胡桃");
}
window.Closed += OnWindowClosed;
RECT rect = RetriveWindowRect();
if (rect.Size > 0)
{
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(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)
{
RemoveWindowSubclass(handle, subClassProc, SubclassId);
subClassProc = null;
SaveWindowRect(handle);
}
private LRESULT OnSubclassProcedure(HWND hwnd, uint uMsg, WPARAM wParam, LPARAM lParam, nuint uIdSubclass, nuint dwRefData)
{
switch (uMsg)
{
case WM_GETMINMAXINFO:
{
uint dpi = GetDpiForWindow(handle);
float scalingFactor = dpi / 96f;
Win32.Unsafe.SetMinTrackSize(lParam, MinWidth * scalingFactor, MinHeight * scalingFactor);
break;
}
}
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
private AppWindow GetAppWindow()
{
WindowId windowId = Win32Interop.GetWindowIdFromWindow(handle);
return AppWindow.GetFromWindowId(windowId);
}
}

View File

@@ -0,0 +1,91 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.UI;
using Microsoft.UI.Windowing;
using System.Numerics;
using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Gdi;
using Windows.Win32.UI.WindowsAndMessaging;
using static Windows.Win32.PInvoke;
namespace Snap.Hutao.Core.Windowing;
/// <summary>
/// Win32/COM 窗体互操作
/// </summary>
internal static class Interop
{
/// <summary>
/// 获取 <see cref="AppWindow"/>
/// </summary>
/// <param name="hwnd">窗体句柄</param>
/// <returns>AppWindow</returns>
public static AppWindow GetAppWindow(HWND hwnd)
{
WindowId windowId = Win32Interop.GetWindowIdFromWindow(hwnd);
return AppWindow.GetFromWindowId(windowId);
}
/// <summary>
/// 设置窗体位置
/// </summary>
/// <param name="hwnd">窗体句柄</param>
public static void SetWindowPosition(HWND hwnd)
{
if (WindowRect.RetriveWindowRect() is RECT { Size: > 0 } retrived)
{
WINDOWPLACEMENT windowPlacement = WINDOWPLACEMENT.Create(new(-1, -1), retrived, SHOW_WINDOW_CMD.SW_SHOWNORMAL);
SetWindowPlacement(hwnd, in windowPlacement);
}
else
{
// Set first launch size.
Vector2 size = Interop.TransformSizeForWindow(new(1200, 741), hwnd);
SET_WINDOW_POS_FLAGS first = SET_WINDOW_POS_FLAGS.SWP_NOMOVE | SET_WINDOW_POS_FLAGS.SWP_NOZORDER;
SetWindowPos(hwnd, default, 0, 0, (int)size.X, (int)size.Y, first);
// Make it centralized
GetWindowRect(hwnd, out RECT rect);
Interop.TransformToCenterScreen(ref rect);
SET_WINDOW_POS_FLAGS center = SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_NOZORDER | SET_WINDOW_POS_FLAGS.SWP_NOACTIVATE;
SetWindowPos(hwnd, default, rect.left, rect.top, 0, 0, center);
}
}
/// <summary>
/// 转换到当前窗体的DPI的尺寸
/// </summary>
/// <param name="size">尺寸</param>
/// <param name="hwnd">窗体句柄</param>
/// <returns>对应当前窗体DPI的尺寸</returns>
public static Vector2 TransformSizeForWindow(Vector2 size, HWND hwnd)
{
uint dpi = GetDpiForWindow(hwnd);
float scale = (float)dpi / 96;
return new(size.X * scale, size.Y * scale);
}
/// <summary>
/// 将矩形转换到屏幕中央
/// 当宽高超过时,会裁剪
/// </summary>
/// <param name="rect">矩形</param>
public static void TransformToCenterScreen(ref RECT rect)
{
HMONITOR hMonitor = MonitorFromRect(rect, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
MONITORINFO mi = MONITORINFO.Default;
GetMonitorInfo(hMonitor, ref mi);
RECT workAreaRect = mi.rcWork;
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
rect.left = workAreaRect.left + ((workAreaRect.right - workAreaRect.left - width) / 2);
rect.top = workAreaRect.top + ((workAreaRect.bottom - workAreaRect.top - height) / 2);
rect.right = rect.left + width;
rect.bottom = rect.top + height;
}
}

View File

@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
using Windows.System;
using WinRT;
namespace Snap.Hutao.Control.HostBackdrop;
namespace Snap.Hutao.Core.Windowing;
/// <summary>
/// 系统背景帮助类

View File

@@ -0,0 +1,133 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.UI;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Snap.Hutao.Core.Logging;
using System.Collections.Generic;
using Windows.Graphics;
using Windows.UI;
using Windows.Win32.Foundation;
using Windows.Win32.UI.Shell;
using WinRT.Interop;
using static Windows.Win32.PInvoke;
namespace Snap.Hutao.Core.Windowing;
/// <summary>
/// 窗口管理器
/// 主要包含了针对窗体的 P/Inoke 逻辑
/// </summary>
internal sealed class WindowManager : IDisposable
{
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 FrameworkElement titleBar;
private readonly ILogger<WindowManager> logger;
private readonly WindowSubclassManager subclassManager;
/// <summary>
/// 构造一个新的窗口状态管理器
/// </summary>
/// <param name="window">窗口</param>
/// <param name="titleBar">充当标题栏的元素</param>
public WindowManager(Window window, FrameworkElement titleBar)
{
this.window = window;
this.titleBar = titleBar;
logger = Ioc.Default.GetRequiredService<ILogger<WindowManager>>();
handle = (HWND)WindowNative.GetWindowHandle(window);
subclassManager = new(handle);
InitializeWindow();
}
/// <inheritdoc/>
public void Dispose()
{
WindowRect.SaveWindowRect(handle);
subclassManager.Dispose();
}
private void InitializeWindow()
{
if (AppWindowTitleBar.IsCustomizationSupported())
{
AppWindow appWindow = Interop.GetAppWindow(handle);
appWindow.Title = "胡桃";
AppWindowTitleBar appTitleBar = appWindow.TitleBar;
appTitleBar.ExtendsContentIntoTitleBar = true;
UpdateTitleButtonColor(appTitleBar);
UpdateDragRectangles(appTitleBar);
titleBar.SizeChanged += (s, e) => UpdateDragRectangles(appTitleBar);
titleBar.ActualThemeChanged += (s, e) => UpdateTitleButtonColor(appTitleBar);
appWindow.Show(true);
}
else
{
SetWindowText(handle, "胡桃");
window.ExtendsContentIntoTitleBar = true;
window.SetTitleBar(titleBar);
window.Activate();
}
Interop.SetWindowPosition(handle);
bool micaApplied = new SystemBackdrop(window).TrySetBackdrop();
logger.LogInformation(EventIds.BackdropState, "Apply {name} : {result}", nameof(SystemBackdrop), micaApplied ? "succeed" : "failed");
bool subClassApplied = subclassManager.TrySetWindowSubclass();
logger.LogInformation(EventIds.SubClassing, "Apply {name} : {result}", nameof(SUBCLASSPROC), subClassApplied ? "succeed" : "failed");
}
private void UpdateDragRectangles(AppWindowTitleBar appTitleBar)
{
uint dpi = GetDpiForWindow(handle);
// double scaleAdjustment = (uint)((((long)dpi * 100) + (96 >> 1)) / 96) / 100.0;
double scale = Math.Round(dpi / 96d, 2, MidpointRounding.AwayFromZero);
List<RectInt32> dragRectsList = new();
// 48 is the navigation button leftInset
RectInt32 dragRect = new((int)(48 * scale), 0, (int)(titleBar.ActualWidth * scale), (int)(titleBar.ActualHeight * scale));
dragRectsList.Add(dragRect);
RectInt32[] dragRects = dragRectsList.ToArray();
appTitleBar.SetDragRectangles(dragRects);
}
[SuppressMessage("", "CA1822")]
private void UpdateTitleButtonColor(AppWindowTitleBar appTitleBar)
{
appTitleBar.ButtonBackgroundColor = Colors.Transparent;
appTitleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
Color systemBaseLowColor = (Color)App.Current.Resources["SystemBaseLowColor"];
appTitleBar.ButtonHoverBackgroundColor = systemBaseLowColor;
Color systemBaseMediumLowColor = (Color)App.Current.Resources["SystemBaseMediumLowColor"];
appTitleBar.ButtonPressedBackgroundColor = systemBaseMediumLowColor;
// The Foreground doesn't accept Alpha channel. So we translate it to gray.
byte light = (byte)((systemBaseMediumLowColor.R + systemBaseMediumLowColor.G + systemBaseMediumLowColor.B) / 3);
byte result = (byte)((systemBaseMediumLowColor.A / 255.0) * light);
appTitleBar.ButtonInactiveForegroundColor = Color.FromArgb(0XFF, result, result, result);
Color systemBaseHighColor = (Color)App.Current.Resources["SystemBaseHighColor"];
appTitleBar.ButtonForegroundColor = systemBaseHighColor;
appTitleBar.ButtonHoverForegroundColor = systemBaseHighColor;
appTitleBar.ButtonPressedForegroundColor = systemBaseHighColor;
}
}

View File

@@ -0,0 +1,45 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Core.Setting;
using Windows.Win32.Foundation;
using Windows.Win32.UI.WindowsAndMessaging;
using static Windows.Win32.PInvoke;
namespace Snap.Hutao.Core.Windowing;
/// <summary>
/// 窗体矩形
/// </summary>
internal static class WindowRect
{
/// <summary>
/// 获取窗体矩形
/// </summary>
/// <returns>矩形</returns>
public static RECT RetriveWindowRect()
{
int left = LocalSetting.GetValueType<int>(SettingKeys.WindowLeft);
int top = LocalSetting.GetValueType<int>(SettingKeys.WindowTop);
int right = LocalSetting.GetValueType<int>(SettingKeys.WindowRight);
int bottom = LocalSetting.GetValueType<int>(SettingKeys.WindowBottom);
return new(left, top, right, bottom);
}
/// <summary>
/// 保存窗体矩形
/// </summary>
/// <param name="handle">窗体句柄</param>
public static void SaveWindowRect(HWND handle)
{
WINDOWPLACEMENT windowPlacement = WINDOWPLACEMENT.Default;
GetWindowPlacement(handle, ref windowPlacement);
LocalSetting.Set(SettingKeys.WindowLeft, windowPlacement.rcNormalPosition.left);
LocalSetting.Set(SettingKeys.WindowTop, windowPlacement.rcNormalPosition.top);
LocalSetting.Set(SettingKeys.WindowRight, windowPlacement.rcNormalPosition.right);
LocalSetting.Set(SettingKeys.WindowBottom, windowPlacement.rcNormalPosition.bottom);
}
}

View File

@@ -0,0 +1,68 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Windows.Win32.Foundation;
using Windows.Win32.UI.Shell;
using static Windows.Win32.PInvoke;
namespace Snap.Hutao.Core.Windowing;
/// <summary>
/// 窗体子类管理器
/// </summary>
internal class WindowSubclassManager : IDisposable
{
private const int SubclassId = 101;
private const int MinWidth = 848;
private const int MinHeight = 524;
private readonly HWND hwnd;
// We have to explictly hold a reference to the SUBCLASSPROC,
// otherwise will casuse System.ExecutionEngineException
private SUBCLASSPROC? subClassProc;
/// <summary>
/// 构造一个新的窗体子类管理器
/// </summary>
/// <param name="hwnd">窗体句柄</param>
public WindowSubclassManager(HWND hwnd)
{
this.hwnd = hwnd;
}
/// <summary>
/// 尝试设置窗体子类
/// </summary>
/// <returns>是否设置成功</returns>
public bool TrySetWindowSubclass()
{
subClassProc = new(OnSubclassProcedure);
return SetWindowSubclass(hwnd, subClassProc, SubclassId, 0);
}
/// <inheritdoc/>
public void Dispose()
{
RemoveWindowSubclass(hwnd, subClassProc, SubclassId);
subClassProc = null;
}
private LRESULT OnSubclassProcedure(HWND hwnd, uint uMsg, WPARAM wParam, LPARAM lParam, nuint uIdSubclass, nuint dwRefData)
{
switch (uMsg)
{
case WM_GETMINMAXINFO:
{
uint dpi = GetDpiForWindow(hwnd);
float scalingFactor = dpi / 96f;
Win32.Unsafe.SetMinTrackSize(lParam, MinWidth * scalingFactor, MinHeight * scalingFactor);
break;
}
}
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
}

View File

@@ -3,7 +3,7 @@
using Microsoft.UI.Xaml;
using Snap.Hutao.Context.Database;
using Snap.Hutao.Core;
using Snap.Hutao.Core.Windowing;
namespace Snap.Hutao;
@@ -14,6 +14,7 @@ namespace Snap.Hutao;
public sealed partial class MainWindow : Window
{
private readonly AppDbContext appDbContext;
private readonly WindowManager windowManager;
/// <summary>
/// 构造一个新的主窗体
@@ -24,11 +25,13 @@ public sealed partial class MainWindow : Window
{
this.appDbContext = appDbContext;
InitializeComponent();
_ = new WindowManager(this, TitleBarView.DragableArea);
windowManager = new WindowManager(this, (FrameworkElement)TitleBarView.DragableArea);
}
private void MainWindowClosed(object sender, WindowEventArgs args)
{
windowManager.Dispose();
// save userdata datebase
int changes = appDbContext.SaveChanges();
Verify.Operation(changes == 0, "存在未经处理的数据库记录更改");

View File

@@ -1,10 +1,13 @@
// 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.Logging;
using Snap.Hutao.Service.Abstraction;
using Snap.Hutao.Service.Navigation;
using Snap.Hutao.View.Page;
using Windows.UI.ViewManagement;
namespace Snap.Hutao.View;
@@ -15,6 +18,7 @@ public sealed partial class MainView : UserControl
{
private readonly INavigationService navigationService;
private readonly IInfoBarService infoBarService;
private readonly UISettings uISettings;
/// <summary>
/// 构造一个新的主视图
@@ -23,6 +27,9 @@ public sealed partial class MainView : UserControl
{
InitializeComponent();
uISettings = new();
uISettings.ColorValuesChanged += OnUISettingsColorValuesChanged;
infoBarService = Ioc.Default.GetRequiredService<IInfoBarService>();
infoBarService.Initialize(InfoBarStack);
@@ -31,4 +38,28 @@ public sealed partial class MainView : UserControl
navigationService.Navigate<AnnouncementPage>(INavigationAwaiter.Default, true);
}
private void OnUISettingsColorValuesChanged(UISettings sender, object args)
{
Program.UIDispatcherQueue.TryEnqueue(UpdateTheme);
}
private void UpdateTheme()
{
if (RequestedTheme.ToString() == App.Current.RequestedTheme.ToString())
{
return;
}
ILogger<MainView> logger = Ioc.Default.GetRequiredService<ILogger<MainView>>();
logger.LogInformation(EventIds.CommonLog, "Element Theme [{element}] App Theme [{app}]", RequestedTheme, App.Current.RequestedTheme);
// Update controls' theme which presents in the PopupRoot
RequestedTheme = App.Current.RequestedTheme switch
{
ApplicationTheme.Light => ElementTheme.Light,
ApplicationTheme.Dark => ElementTheme.Dark,
_ => throw Must.NeverHappen(),
};
}
}

View File

@@ -94,8 +94,10 @@ openInWebview: function(url){ location.href = url }}";
{
await WebView.EnsureCoreWebView2Async();
await WebView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(MihoyoSDKDefinition);
WebView.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
WebView.CoreWebView2.WebMessageReceived += OnWebMessageReceived;
await WebView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(MihoyoSDKDefinition);
}
catch (Exception ex)
{

View File

@@ -61,6 +61,7 @@
TargetType="FlyoutPresenter"
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}">
<Setter Property="Padding" Value="0,2,0,2"/>
<Setter Property="Background" Value="{ThemeResource FlyoutPresenterBackground}" />
</Style>
</Flyout.FlyoutPresenterStyle>
<StackPanel>