add transparent backdrop

This commit is contained in:
Lightczx
2024-01-08 15:16:41 +08:00
parent a26c52ba97
commit 1a944dae9c
7 changed files with 100 additions and 1 deletions

View File

@@ -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

View File

@@ -1,9 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows10.0.22621.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<ItemGroup>

View File

@@ -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;

View File

@@ -9,6 +9,8 @@ namespace Snap.Hutao.Core.Windowing;
[HighQuality]
internal enum BackdropType
{
Transparent,
/// <summary>
/// 无
/// </summary>

View File

@@ -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(),

View File

@@ -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);
}
}

View File

@@ -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);