Files
better-genshin-impact/Build/MicaSetup/Design/Controls/Window/WindowBackdrop.cs

188 lines
5.6 KiB
C#

using MicaSetup.Helper;
using MicaSetup.Natives;
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
namespace MicaSetup.Design.Controls;
public static class WindowBackdrop
{
private static bool IsSupported(WindowBackdropType backdropType)
{
return backdropType switch
{
WindowBackdropType.Auto => OsVersionHelper.IsWindows11_22523,
WindowBackdropType.Tabbed => OsVersionHelper.IsWindows11_22523,
WindowBackdropType.Mica => OsVersionHelper.IsWindows11_OrGreater,
WindowBackdropType.Acrylic => OsVersionHelper.IsWindows7_OrGreater,
WindowBackdropType.None => OsVersionHelper.IsWindows11_OrGreater,
_ => false
};
}
public static bool ApplyBackdrop(Window window, WindowBackdropType backdropType = WindowBackdropType.Mica, ApplicationTheme theme = ApplicationTheme.Unknown)
{
if (!IsSupported(backdropType))
{
return false;
}
if (window is null)
{
return false;
}
if (window.IsLoaded)
{
nint windowHandle = new WindowInteropHelper(window).Handle;
if (windowHandle == 0x00)
{
return false;
}
return ApplyBackdrop(windowHandle, backdropType, theme);
}
window.Loaded += (sender, _) =>
{
nint windowHandle =
new WindowInteropHelper(sender as Window ?? null)?.Handle
?? IntPtr.Zero;
if (windowHandle == 0x00)
return;
ApplyBackdrop(windowHandle, backdropType, theme);
};
return true;
}
public static bool ApplyBackdrop(nint hWnd, WindowBackdropType backdropType = WindowBackdropType.Mica, ApplicationTheme theme = ApplicationTheme.Unknown)
{
if (!IsSupported(backdropType))
{
return false;
}
if (hWnd == 0x00 || !User32.IsWindow(hWnd))
{
return false;
}
if (backdropType != WindowBackdropType.Auto)
{
WindowDarkMode.RemoveBackground(hWnd);
}
switch (theme)
{
case ApplicationTheme.Unknown:
if (ApplicationThemeManager.GetAppTheme() == ApplicationTheme.Dark)
{
WindowDarkMode.ApplyWindowDarkMode(hWnd);
}
break;
case ApplicationTheme.Dark:
WindowDarkMode.ApplyWindowDarkMode(hWnd);
break;
case ApplicationTheme.Light:
case ApplicationTheme.HighContrast:
WindowDarkMode.RemoveWindowDarkMode(hWnd);
break;
}
var wtaOptions = new UxTheme.WTA_OPTIONS()
{
Flags = UxTheme.WTNCA.WTNCA_NODRAWCAPTION,
Mask = (uint)UxTheme.ThemeDialogTextureFlags.ETDT_VALIDBITS,
};
UxTheme.SetWindowThemeAttribute(
hWnd,
UxTheme.WINDOWTHEMEATTRIBUTETYPE.WTA_NONCLIENT,
wtaOptions,
(uint)Marshal.SizeOf(typeof(UxTheme.WTA_OPTIONS))
);
var dwmApiResult = DwmApi.DwmSetWindowAttribute(
hWnd,
DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE,
(int)(backdropType switch
{
WindowBackdropType.Auto => DwmApi.DWM_SYSTEMBACKDROP_TYPE.DWMSBT_AUTO,
WindowBackdropType.Mica => DwmApi.DWM_SYSTEMBACKDROP_TYPE.DWMSBT_MAINWINDOW,
WindowBackdropType.Acrylic => DwmApi.DWM_SYSTEMBACKDROP_TYPE.DWMSBT_TRANSIENTWINDOW,
WindowBackdropType.Tabbed => DwmApi.DWM_SYSTEMBACKDROP_TYPE.DWMSBT_TABBEDWINDOW,
_ => DwmApi.DWM_SYSTEMBACKDROP_TYPE.DWMSBT_NONE,
}),
Marshal.SizeOf(typeof(int))
);
return dwmApiResult == HRESULT.S_OK;
}
public static bool RemoveBackdrop(Window window)
{
if (window == null)
{
return false;
}
nint hWnd = new WindowInteropHelper(window).Handle;
return RemoveBackdrop(hWnd);
}
public static bool RemoveBackdrop(nint hWnd)
{
if (hWnd == 0x00 || !User32.IsWindow(hWnd))
{
return false;
}
var windowSource = HwndSource.FromHwnd(hWnd);
if (windowSource?.Handle.ToInt32() != 0x00 && windowSource?.CompositionTarget != null)
{
windowSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor;
}
if (windowSource?.RootVisual is Window window)
{
var backgroundBrush = window.Resources["ApplicationBackgroundBrush"];
if (backgroundBrush is not SolidColorBrush)
{
backgroundBrush = ApplicationThemeManager.GetAppTheme() == ApplicationTheme.Dark
? new SolidColorBrush(Color.FromArgb(0xFF, 0x20, 0x20, 0x20))
: new SolidColorBrush(Color.FromArgb(0xFF, 0xFA, 0xFA, 0xFA));
}
window.Background = (SolidColorBrush)backgroundBrush;
}
_ = DwmApi.DwmSetWindowAttribute(
hWnd,
DWMWINDOWATTRIBUTE.DWMWA_MICA_EFFECT,
0x0,
Marshal.SizeOf(typeof(int))
);
_ = DwmApi.DwmSetWindowAttribute(
hWnd,
DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE,
(int)DwmApi.DWM_SYSTEMBACKDROP_TYPE.DWMSBT_NONE,
Marshal.SizeOf(typeof(int))
);
return true;
}
}