From 723ccff276451c2927bf0d2bb0cab7f80b4e4ace Mon Sep 17 00:00:00 2001 From: DismissedLight <1686188646@qq.com> Date: Tue, 2 Aug 2022 22:50:14 +0800 Subject: [PATCH] fix image source apply issue --- .../Snap.Hutao.Win32/Snap.Hutao.Win32.csproj | 1 + src/Snap.Hutao/Snap.Hutao.Win32/Unsafe.cs | 6 +-- src/Snap.Hutao/Snap.Hutao.sln | 6 +-- .../Control/Behavior/ContentDialogBehavior.cs | 14 +++-- .../Control/Image/CompositionImage.cs | 54 +++++++++++-------- .../ConcurrentCancellationTokenSource.cs | 2 +- .../Snap.Hutao/Core/WindowManager.cs | 39 ++++++++++++-- .../Snap.Hutao/Package.appxmanifest | 2 +- 8 files changed, 87 insertions(+), 37 deletions(-) diff --git a/src/Snap.Hutao/Snap.Hutao.Win32/Snap.Hutao.Win32.csproj b/src/Snap.Hutao/Snap.Hutao.Win32/Snap.Hutao.Win32.csproj index 0d9fe8b5..cc02b6f9 100644 --- a/src/Snap.Hutao/Snap.Hutao.Win32/Snap.Hutao.Win32.csproj +++ b/src/Snap.Hutao/Snap.Hutao.Win32/Snap.Hutao.Win32.csproj @@ -4,6 +4,7 @@ net6.0 enable enable + AnyCPU;x64 diff --git a/src/Snap.Hutao/Snap.Hutao.Win32/Unsafe.cs b/src/Snap.Hutao/Snap.Hutao.Win32/Unsafe.cs index 28a85b6e..819d0622 100644 --- a/src/Snap.Hutao/Snap.Hutao.Win32/Unsafe.cs +++ b/src/Snap.Hutao/Snap.Hutao.Win32/Unsafe.cs @@ -6,9 +6,9 @@ public class Unsafe /// /// 使用指针操作简化封送 /// - /// - /// - /// + /// lParam + /// 最小宽度 + /// 最小高度 public static unsafe void SetMinTrackSize(nint lPARAM, float minWidth, float minHeight) { MINMAXINFO* rect2 = (MINMAXINFO*)lPARAM; diff --git a/src/Snap.Hutao/Snap.Hutao.sln b/src/Snap.Hutao/Snap.Hutao.sln index 77abf5cc..31f80b6e 100644 --- a/src/Snap.Hutao/Snap.Hutao.sln +++ b/src/Snap.Hutao/Snap.Hutao.sln @@ -14,7 +14,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SettingsUI", "SettingsUI\Se EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snap.Hutao.SourceGeneration", "Snap.Hutao.SourceGeneration\Snap.Hutao.SourceGeneration.csproj", "{8B96721E-5604-47D2-9B72-06FEBAD0CE00}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Snap.Hutao.Win32", "Snap.Hutao.Win32\Snap.Hutao.Win32.csproj", "{29209B14-A6E1-442E-9287-2C65B03C96CD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snap.Hutao.Win32", "Snap.Hutao.Win32\Snap.Hutao.Win32.csproj", "{29209B14-A6E1-442E-9287-2C65B03C96CD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -96,8 +96,8 @@ Global {29209B14-A6E1-442E-9287-2C65B03C96CD}.Release|Any CPU.Build.0 = Release|Any CPU {29209B14-A6E1-442E-9287-2C65B03C96CD}.Release|arm64.ActiveCfg = Release|Any CPU {29209B14-A6E1-442E-9287-2C65B03C96CD}.Release|arm64.Build.0 = Release|Any CPU - {29209B14-A6E1-442E-9287-2C65B03C96CD}.Release|x64.ActiveCfg = Release|Any CPU - {29209B14-A6E1-442E-9287-2C65B03C96CD}.Release|x64.Build.0 = Release|Any CPU + {29209B14-A6E1-442E-9287-2C65B03C96CD}.Release|x64.ActiveCfg = Release|x64 + {29209B14-A6E1-442E-9287-2C65B03C96CD}.Release|x64.Build.0 = Release|x64 {29209B14-A6E1-442E-9287-2C65B03C96CD}.Release|x86.ActiveCfg = Release|Any CPU {29209B14-A6E1-442E-9287-2C65B03C96CD}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Behavior/ContentDialogBehavior.cs b/src/Snap.Hutao/Snap.Hutao/Control/Behavior/ContentDialogBehavior.cs index 4f871435..5ee01480 100644 --- a/src/Snap.Hutao/Snap.Hutao/Control/Behavior/ContentDialogBehavior.cs +++ b/src/Snap.Hutao/Snap.Hutao/Control/Behavior/ContentDialogBehavior.cs @@ -17,11 +17,17 @@ 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); + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) + { + DependencyObject current = VisualTreeHelper.GetChild(parent, i); + if (current is Rectangle { Name: "SmokeLayerBackground" } background) + { + background.ClearValue(FrameworkElement.MarginProperty); + background.RegisterPropertyChangedCallback(FrameworkElement.MarginProperty, OnMarginChanged); + break; + } + } } private static void OnMarginChanged(DependencyObject sender, DependencyProperty property) diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Image/CompositionImage.cs b/src/Snap.Hutao/Snap.Hutao/Control/Image/CompositionImage.cs index caef3ac6..ce89cc4a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Control/Image/CompositionImage.cs +++ b/src/Snap.Hutao/Snap.Hutao/Control/Image/CompositionImage.cs @@ -12,6 +12,7 @@ using Snap.Hutao.Core.Exception; using Snap.Hutao.Core.Threading; using Snap.Hutao.Extension; using Snap.Hutao.Service.Abstraction; +using System.Net.Http; using System.Runtime.InteropServices; using Windows.Storage; using Windows.Storage.Streams; @@ -81,50 +82,52 @@ public abstract class CompositionImage : Microsoft.UI.Xaml.Controls.Control spriteVisual.Size = ActualSize; } - private static void OnApplyImageFailed(Exception exception) + private static void OnApplyImageFailed(Uri? uri, Exception exception) { - Ioc.Default - .GetRequiredService() - .Error(exception, "应用合成图像时发生异常"); + IInfoBarService infoBarService = Ioc.Default.GetRequiredService(); + + if (exception is HttpRequestException httpRequestException) + { + infoBarService.Warning($"GET {uri}\n{httpRequestException}"); + } + else + { + infoBarService.Error(exception, $"应用 {nameof(CompositionImage)} 的源时发生异常"); + } } private static void OnSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs arg) { CompositionImage image = (CompositionImage)sender; - - _ = TryGetImageUri(arg, out Uri? uri); + CancellationToken token = LoadingTokenSource.Register(image); ILogger logger = Ioc.Default.GetRequiredService>(); - image.ApplyImageInternalAsync(uri, LoadingTokenSource.Register(image)).SafeForget(logger, OnApplyImageFailed); - } - private static bool TryGetImageUri(DependencyPropertyChangedEventArgs arg, [NotNullWhen(true)] out Uri? result) - { - result = null; + // source is valid if (arg.NewValue is Uri inner && !string.IsNullOrEmpty(inner.Host)) { - // value is different from old one and not + // value is different from old one if (inner != (arg.OldValue as Uri)) { - result = inner; - return true; + image.ApplyImageInternalAsync(inner, token).SafeForget(logger, ex => OnApplyImageFailed(inner, ex)); } } - - return false; + else + { + // should hide + image.HideAsync(token).SafeForget(logger); + } } private async Task ApplyImageInternalAsync(Uri? uri, CancellationToken token) { - await AnimationBuilder.Create().Opacity(0d).StartAsync(this, token); + await HideAsync(token); if (uri != null) { StorageFile storageFile = await imageCache.GetFileFromCacheAsync(uri); - Compositor compositor = ElementCompositionPreview.GetElementVisual(this).Compositor; LoadedImageSurface? imageSurface = null; - try { imageSurface = await LoadImageSurfaceAsync(storageFile, token); @@ -141,12 +144,21 @@ public abstract class CompositionImage : Microsoft.UI.Xaml.Controls.Control OnUpdateVisual(spriteVisual); ElementCompositionPreview.SetElementChildVisual(this, spriteVisual); - - await AnimationBuilder.Create().Opacity(1d).StartAsync(this, token); + await ShowAsync(token); } } } + private Task ShowAsync(CancellationToken token) + { + return AnimationBuilder.Create().Opacity(1d).StartAsync(this, token); + } + + private Task HideAsync(CancellationToken token) + { + return AnimationBuilder.Create().Opacity(0d).StartAsync(this, token); + } + private void OnSizeChanged(object sender, SizeChangedEventArgs e) { if (e.NewSize != e.PreviousSize && spriteVisual != null) diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Threading/ConcurrentCancellationTokenSource.cs b/src/Snap.Hutao/Snap.Hutao/Core/Threading/ConcurrentCancellationTokenSource.cs index a0cd7879..7ef0a398 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Threading/ConcurrentCancellationTokenSource.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Threading/ConcurrentCancellationTokenSource.cs @@ -15,7 +15,7 @@ internal class ConcurrentCancellationTokenSource private readonly ConcurrentDictionary waitingItems = new(); /// - /// 未某个项注册取消令牌 + /// 为某个项注册取消令牌 /// /// 项 /// 取消令牌 diff --git a/src/Snap.Hutao/Snap.Hutao/Core/WindowManager.cs b/src/Snap.Hutao/Snap.Hutao/Core/WindowManager.cs index 607df41f..a8435071 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/WindowManager.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/WindowManager.cs @@ -1,6 +1,8 @@ // 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; @@ -23,6 +25,9 @@ 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; @@ -42,7 +47,9 @@ internal class WindowManager this.window = window; this.titleBar = titleBar; logger = Ioc.Default.GetRequiredService>(); + handle = (HWND)WindowNative.GetWindowHandle(window); + InitializeWindow(); } @@ -70,11 +77,29 @@ internal class WindowManager private void InitializeWindow() { - window.ExtendsContentIntoTitleBar = true; - window.SetTitleBar(titleBar); - window.Closed += OnWindowClosed; + if (false && AppWindowTitleBar.IsCustomizationSupported()) + { + AppWindow appWindow = GetAppWindow(); + AppWindowTitleBar titleBar = appWindow.TitleBar; + titleBar.ExtendsContentIntoTitleBar = true; - SetWindowText(handle, "胡桃"); + 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) { @@ -112,4 +137,10 @@ internal class WindowManager return DefSubclassProc(hwnd, uMsg, wParam, lParam); } + + private AppWindow GetAppWindow() + { + WindowId windowId = Win32Interop.GetWindowIdFromWindow(handle); + return AppWindow.GetFromWindowId(windowId); + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Package.appxmanifest b/src/Snap.Hutao/Snap.Hutao/Package.appxmanifest index 937607a1..672611b8 100644 --- a/src/Snap.Hutao/Snap.Hutao/Package.appxmanifest +++ b/src/Snap.Hutao/Snap.Hutao/Package.appxmanifest @@ -9,7 +9,7 @@ + Version="1.0.22.0" /> 胡桃