From 1a944dae9cf9c2e913d83cd45214fac0807bada4 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Mon, 8 Jan 2024 15:16:41 +0800 Subject: [PATCH] add transparent backdrop --- .../Snap.Hutao.Win32/NativeMethods.txt | 4 ++ .../Snap.Hutao.Win32/Snap.Hutao.Win32.csproj | 3 +- .../Windowing/Backdrop/TransparentBackdrop.cs | 67 +++++++++++++++++++ .../Snap.Hutao/Core/Windowing/BackdropType.cs | 2 + .../Core/Windowing/WindowController.cs | 2 + .../Core/Windowing/WindowExtension.cs | 12 ++++ .../Core/Windowing/WindowSubclass.cs | 11 +++ 7 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 src/Snap.Hutao/Snap.Hutao/Core/Windowing/Backdrop/TransparentBackdrop.cs diff --git a/src/Snap.Hutao/Snap.Hutao.Win32/NativeMethods.txt b/src/Snap.Hutao/Snap.Hutao.Win32/NativeMethods.txt index 5fca356a..30ce0c80 100644 --- a/src/Snap.Hutao/Snap.Hutao.Win32/NativeMethods.txt +++ b/src/Snap.Hutao/Snap.Hutao.Win32/NativeMethods.txt @@ -47,12 +47,14 @@ GetCursorPos GetDC GetDpiForWindow GetForegroundWindow +GetWindowLongPtrW GetWindowPlacement GetWindowThreadProcessId ReleaseDC RegisterHotKey SendInput SetForegroundWindow +SetWindowLongPtrW UnregisterHotKey // COM @@ -74,6 +76,7 @@ E_FAIL INFINITE RPC_E_WRONG_THREAD MAX_PATH +WM_ERASEBKGND WM_GETMINMAXINFO WM_HOTKEY WM_NCRBUTTONDOWN @@ -89,6 +92,7 @@ LPTHREAD_START_ROUTINE // UI.WindowsAndMessaging MINMAXINFO +WINDOW_EX_STYLE // System.Com CWMO_FLAGS \ No newline at end of file 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 6a15892b..df2df533 100644 --- a/src/Snap.Hutao/Snap.Hutao.Win32/Snap.Hutao.Win32.csproj +++ b/src/Snap.Hutao/Snap.Hutao.Win32/Snap.Hutao.Win32.csproj @@ -1,9 +1,10 @@ - + net8.0-windows10.0.22621.0 disable enable + x64 diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/Backdrop/TransparentBackdrop.cs b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/Backdrop/TransparentBackdrop.cs new file mode 100644 index 00000000..4abf863a --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/Backdrop/TransparentBackdrop.cs @@ -0,0 +1,67 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Microsoft.UI; +using Microsoft.UI.Composition; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Media; +using Windows.UI; + +namespace Snap.Hutao.Core.Windowing.Backdrop; + +internal sealed class TransparentBackdrop : SystemBackdrop, IDisposable, IBackdropNeedEraseBackground +{ + private readonly object compositorLock = new(); + + private Color tintColor; + private Windows.UI.Composition.CompositionColorBrush? brush; + private Windows.UI.Composition.Compositor? compositor; + + public TransparentBackdrop() + : this(Colors.Transparent) + { + } + + public TransparentBackdrop(Color tintColor) + { + this.tintColor = tintColor; + } + + internal Windows.UI.Composition.Compositor Compositor + { + get + { + if (compositor is null) + { + lock (compositorLock) + { + if (compositor is null) + { + DispatcherQueue.EnsureSystemDispatcherQueue(); + compositor = new Windows.UI.Composition.Compositor(); + } + } + } + + return compositor; + } + } + + public void Dispose() + { + compositor?.Dispose(); + } + + protected override void OnTargetConnected(ICompositionSupportsSystemBackdrop connectedTarget, XamlRoot xamlRoot) + { + brush ??= Compositor.CreateColorBrush(tintColor); + connectedTarget.SystemBackdrop = brush; + } + + protected override void OnTargetDisconnected(ICompositionSupportsSystemBackdrop disconnectedTarget) + { + disconnectedTarget.SystemBackdrop = null; + } +} + +internal interface IBackdropNeedEraseBackground; \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/BackdropType.cs b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/BackdropType.cs index f6416860..24f4b285 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/BackdropType.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/BackdropType.cs @@ -9,6 +9,8 @@ namespace Snap.Hutao.Core.Windowing; [HighQuality] internal enum BackdropType { + Transparent, + /// /// 无 /// diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowController.cs b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowController.cs index 72aeb090..c00b0e37 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowController.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowController.cs @@ -9,6 +9,7 @@ using Microsoft.UI.Xaml.Media; using Snap.Hutao.Core.LifeCycle; using Snap.Hutao.Core.Setting; using Snap.Hutao.Service; +using System.Diagnostics; using System.IO; using Windows.Graphics; using Windows.UI; @@ -157,6 +158,7 @@ internal sealed class WindowController { window.SystemBackdrop = backdropType switch { + BackdropType.Transparent => new Backdrop.TransparentBackdrop(), BackdropType.MicaAlt => new MicaBackdrop() { Kind = MicaKind.BaseAlt }, BackdropType.Mica => new MicaBackdrop() { Kind = MicaKind.Base }, BackdropType.Acrylic => new DesktopAcrylicBackdrop(), diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowExtension.cs b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowExtension.cs index e6598b80..97f41793 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowExtension.cs @@ -3,6 +3,10 @@ using Microsoft.UI.Xaml; using System.Runtime.CompilerServices; +using Windows.Win32.Foundation; +using Windows.Win32.UI.WindowsAndMessaging; +using WinRT.Interop; +using static Windows.Win32.PInvoke; namespace Snap.Hutao.Core.Windowing; @@ -16,4 +20,12 @@ internal static class WindowExtension WindowController windowController = new(window, window.WindowOptions, serviceProvider); WindowControllers.Add(window, windowController); } + + public static void SetLayeredWindow(this Window window) + { + HWND hwnd = (HWND)WindowNative.GetWindowHandle(window); + nint style = GetWindowLongPtr(hwnd, WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE); + style |= (nint)WINDOW_EX_STYLE.WS_EX_LAYERED; + SetWindowLongPtr(hwnd, WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, style); + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowSubclass.cs b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowSubclass.cs index c3e9ac21..4b12b05c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowSubclass.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/WindowSubclass.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. using Microsoft.UI.Xaml; +using Snap.Hutao.Core.Windowing.Backdrop; using Snap.Hutao.Core.Windowing.HotKey; using Windows.Win32.Foundation; using Windows.Win32.UI.Shell; @@ -110,6 +111,16 @@ internal sealed class WindowSubclass : IDisposable hotKeyController.OnHotKeyPressed(*(HotKeyParameter*)&lParam); break; } + + case WM_ERASEBKGND: + { + if (window.SystemBackdrop is IBackdropNeedEraseBackground) + { + return (LRESULT)(int)(BOOL)true; + } + + break; + } } return DefSubclassProc(hwnd, uMsg, wParam, lParam);