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