Files
HearingProtector/MicaWindowExt.cs
T
2026-09-26 12:11:20 +07:00

144 lines
5.3 KiB
C#

using Microsoft.UI;
using Microsoft.UI.Composition;
using Microsoft.UI.Composition.SystemBackdrops;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using Windows.Graphics;
using WinRT.Interop;
namespace HearingProtector.Extensions;
#pragma warning disable SYSLIB1054
public static class MicaWindowExt
{
[DllImport("user32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")] private static extern bool GetCursorPos(out POINT lpPoint);
[StructLayout(LayoutKind.Sequential)] public struct POINT { public int X; public int Y; }
public static void SetMicaStyle(this Window window, UIElement titleBar, SizeInt32? size = null, bool canResize = true, bool canMinMax = true)
{
window.SetSystemBackdrop();
window.ExtendsContentIntoTitleBar = true;
window.SetTitleBar(titleBar);
// Устанавливаем место появления окна и начальный размер
window.CenterWindowOnCursorScreen(size, canResize, canMinMax);
// Выводим окно на передний план
SetForegroundWindow(WindowNative.GetWindowHandle(window));
}
static void SetSystemBackdrop(this Window window)
{
// Проверяем версию Windows
if (Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent
("Windows.Foundation.UniversalApiContract", 13)) // Версия, в которой появился MicaBackdrop
{
// Используем Mica на Windows 11
window.SystemBackdrop = new MicaBackdrop()
{
Kind = MicaKind.Base // Или MicaKind.Alt для Mica Alt
};
}
else
{
// Используем Acrylic на Windows 10
//SystemBackdrop = new DesktopAcrylicBackdrop();
window.SystemBackdrop = new Windows10AcrylicBackdrop();
}
}
static void CenterWindowOnCursorScreen(this Window window, SizeInt32? size, bool canResize = true, bool canMinMax = true)
{
// Получаем AppWindow текущего окна
IntPtr hWnd = WindowNative.GetWindowHandle(window);
WindowId windowId = Win32Interop.GetWindowIdFromWindow(hWnd);
AppWindow appWindow = AppWindow.GetFromWindowId(windowId);
// Получаем позицию курсора
GetCursorPos(out POINT cursorPos);
// Находим дисплей с курсором
DisplayArea displayArea = DisplayArea.GetFromPoint(
new PointInt32(cursorPos.X, cursorPos.Y),
DisplayAreaFallback.Nearest);
if (!size.HasValue)
size = appWindow.Size;
// Центрируем окно на этом дисплее
appWindow.MoveAndResize(new RectInt32(
displayArea.WorkArea.X + (displayArea.WorkArea.Width - size.Value.Width) / 2,
displayArea.WorkArea.Y + (displayArea.WorkArea.Height - size.Value.Height) / 2,
size.Value.Width, size.Value.Height));
// Запрещаем пользовательское изменение размера
if (!canResize && appWindow.Presenter is OverlappedPresenter presenter)
{
presenter.IsResizable = false;
// При желании можно также запретить сворачивание/разворачивание:
if (!canMinMax)
{
presenter.IsMaximizable = false;
presenter.IsMinimizable = false;
}
}
}
}
// Кастомный Backdrop для Windows 10
public partial class Windows10AcrylicBackdrop : SystemBackdrop
{
DesktopAcrylicController? controller;
protected override void OnTargetConnected(ICompositionSupportsSystemBackdrop connectedTarget, XamlRoot xamlRoot)
{
// Call the base method to initialize the default configuration object.
base.OnTargetConnected(connectedTarget, xamlRoot);
// This example does not support sharing MicaSystemBackdrop instances.
if (controller is not null)
{
throw new Exception("This controller cannot be shared");
}
controller = new DesktopAcrylicController();
// Set configuration.
SystemBackdropConfiguration defaultConfig = GetDefaultSystemBackdropConfiguration(connectedTarget, xamlRoot);
controller.SetSystemBackdropConfiguration(defaultConfig);
// Add target.
controller.AddSystemBackdropTarget(connectedTarget);
controller.TintOpacity = 0.8f;
controller.LuminosityOpacity = 0.9f;
}
protected override void OnTargetDisconnected(ICompositionSupportsSystemBackdrop disconnectedTarget)
{
base.OnTargetDisconnected(disconnectedTarget);
controller?.RemoveSystemBackdropTarget(disconnectedTarget);
controller = default;
}
}
public static class ReadTextExt
{
public static string[] FileReadAllLines(this string filePath, Encoding? enc = null)
{
using var reader = new StreamReader(filePath, enc ?? Encoding.GetEncoding(1251), detectEncodingFromByteOrderMarks: true);
string content = reader.ReadToEnd().Replace("\r", "");
return content.Split("\n");
}
}