127 lines
4.2 KiB
C#
127 lines
4.2 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Windows;
|
|
using System.Windows.Interop;
|
|
|
|
namespace ClashWidget.Helpers;
|
|
|
|
internal static class NativeMethods
|
|
{
|
|
[DllImport("user32.dll")]
|
|
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
|
|
int X, int Y, int cx, int cy, uint uFlags);
|
|
|
|
[DllImport("dwmapi.dll")]
|
|
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr,
|
|
ref int attrValue, int attrSize);
|
|
|
|
[DllImport("dwmapi.dll")]
|
|
private static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd,
|
|
ref MARGINS margins);
|
|
|
|
[DllImport("user32.dll")]
|
|
private static extern int SetWindowCompositionAttribute(IntPtr hwnd,
|
|
ref WindowCompositionAttributeData data);
|
|
|
|
[DllImport("user32.dll")]
|
|
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
|
|
|
|
[DllImport("user32.dll")]
|
|
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
|
|
|
|
private static readonly IntPtr HWND_TOPMOST = new(-1);
|
|
private const uint SWP_NOMOVE = 0x0002;
|
|
private const uint SWP_NOSIZE = 0x0001;
|
|
private const uint SWP_NOACTIVATE = 0x0010;
|
|
private const uint SWP_SHOWWINDOW = 0x0040;
|
|
private const int GWL_EXSTYLE = -20;
|
|
private const int WS_EX_TOOLWINDOW = 0x00000080;
|
|
private const int WS_EX_APPWINDOW = 0x00040000;
|
|
private const int DWMWA_SYSTEMBACKDROP_TYPE = 38;
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct MARGINS { public int Left, Right, Top, Bottom; }
|
|
|
|
private enum AccentState { ACCENT_DISABLED = 0, ACCENT_ENABLE_ACRYLICBLURBEHIND = 4 }
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct AccentPolicy
|
|
{
|
|
public AccentState AccentState;
|
|
public int AccentFlags;
|
|
public int GradientColor;
|
|
public int AnimationId;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct WindowCompositionAttributeData
|
|
{
|
|
public WindowCompositionAttribute Attribute;
|
|
public IntPtr Data;
|
|
public int SizeOfData;
|
|
}
|
|
|
|
private enum WindowCompositionAttribute { WCA_ACCENT_POLICY = 19 }
|
|
|
|
public static void ApplyAcrylic(Window window)
|
|
{
|
|
var hwnd = new WindowInteropHelper(window).EnsureHandle();
|
|
|
|
// Extend DWM frame into entire client area
|
|
var margins = new MARGINS { Left = -1, Right = -1, Top = -1, Bottom = -1 };
|
|
DwmExtendFrameIntoClientArea(hwnd, ref margins);
|
|
|
|
// Try Win11 modern API first
|
|
int backdrop = 3; // DWMSBT_TRANSIENTWINDOW = Acrylic
|
|
int hr = DwmSetWindowAttribute(hwnd, DWMWA_SYSTEMBACKDROP_TYPE, ref backdrop, sizeof(int));
|
|
|
|
if (hr != 0)
|
|
{
|
|
// Fallback: Win10 acrylic
|
|
try
|
|
{
|
|
var accent = new AccentPolicy
|
|
{
|
|
AccentState = AccentState.ACCENT_ENABLE_ACRYLICBLURBEHIND,
|
|
AccentFlags = 2,
|
|
GradientColor = 0x01FFFFFF
|
|
};
|
|
var data = new WindowCompositionAttributeData
|
|
{
|
|
Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY,
|
|
SizeOfData = Marshal.SizeOf<AccentPolicy>(),
|
|
Data = Marshal.AllocHGlobal(Marshal.SizeOf<AccentPolicy>())
|
|
};
|
|
Marshal.StructureToPtr(accent, data.Data, false);
|
|
SetWindowCompositionAttribute(hwnd, ref data);
|
|
Marshal.FreeHGlobal(data.Data);
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
|
|
public static void SetTopmost(Window window)
|
|
{
|
|
try
|
|
{
|
|
var hwnd = new WindowInteropHelper(window).EnsureHandle();
|
|
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
|
|
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
public static void HideFromTaskbar(Window window)
|
|
{
|
|
try
|
|
{
|
|
var hwnd = new WindowInteropHelper(window).EnsureHandle();
|
|
int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
|
|
exStyle |= WS_EX_TOOLWINDOW;
|
|
exStyle &= ~WS_EX_APPWINDOW;
|
|
SetWindowLong(hwnd, GWL_EXSTYLE, exStyle);
|
|
}
|
|
catch { }
|
|
}
|
|
}
|