public partial class frmBlurBehind : Form
{
public frmBlurBehind()
{
InitializeComponent();
// Remove the border if this is meant to be a border-less Form
// FormBorderStyle = FormBorderStyle.None;
if (IsDWMCompositionEnabled()) {
if (Environment.OSVersion.Version.Major > 6) {
Dwm.Windows10EnableBlurBehind(Handle);
}
else {
Dwm.WindowEnableBlurBehind(Handle);
}
// Set Drop shadow of a border-less Form
if (FormBorderStyle == FormBorderStyle.None) {
Dwm.WindowBorderlessDropShadow(Handle, 2);
}
}
}
private bool IsDWMCompositionEnabled() =>
Environment.OSVersion.Version.Major >= 6 && Dwm.IsCompositionEnabled();
// Eventually, if this is a border-less Form, reapply the attribute if DWM Composition changes
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
switch (m.Msg) {
case Dwm.WM_DWMCOMPOSITIONCHANGED:
if (IsDWMCompositionEnabled()) {
Dwm.DWMNCRENDERINGPOLICY policy = Dwm.DWMNCRENDERINGPOLICY.Enabled;
Dwm.WindowSetAttribute(Handle, Dwm.DWMWINDOWATTRIBUTE.NCRenderingPolicy, (int)policy);
Dwm.WindowBorderlessDropShadow(Handle, 2);
m.Result = IntPtr.Zero;
}
break;
default:
break;
}
}
}
Dwm类包含上面使用的所有互操作函数和结构,以及在此上下文中可能有用的一系列其他方法
[SuppressUnmanagedCodeSecurity]
public class Dwm {
public const int WM_DWMCOMPOSITIONCHANGED = 0x031E;
public struct MARGINS {
public int leftWidth;
public int rightWidth;
public int topHeight;
public int bottomHeight;
public MARGINS(int LeftWidth, int RightWidth, int TopHeight, int BottomHeight)
{
leftWidth = LeftWidth;
rightWidth = RightWidth;
topHeight = TopHeight;
bottomHeight = BottomHeight;
}
public void NoMargins()
{
leftWidth = 0;
rightWidth = 0;
topHeight = 0;
bottomHeight = 0;
}
public void SheetOfGlass()
{
leftWidth = -1;
rightWidth = -1;
topHeight = -1;
bottomHeight = -1;
}
}
[Flags]
public enum DWM_BB {
Enable = 1,
BlurRegion = 2,
TransitionOnMaximized = 4
}
// https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
public enum DWMWINDOWATTRIBUTE : uint {
NCRenderingEnabled = 1, //Get atttribute
NCRenderingPolicy, //Enable or disable non-client rendering
TransitionsForceDisabled,
AllowNCPaint,
CaptionButtonBounds, //Get atttribute
NonClientRtlLayout,
ForceIconicRepresentation,
Flip3DPolicy,
ExtendedFrameBounds, //Get atttribute
HasIconicBitmap,
DisallowPeek,
ExcludedFromPeek,
Cloak,
Cloaked, //Get atttribute. Returns a DWMCLOACKEDREASON
FreezeRepresentation,
PassiveUpdateMode,
UseHostBackDropBrush,
AccentPolicy = 19, // Win 10 (undocumented)
ImmersiveDarkMode = 20, // Win 11 22000
WindowCornerPreference = 33, // Win 11 22000
BorderColor, // Win 11 22000
CaptionColor, // Win 11 22000
TextColor, // Win 11 22000
VisibleFrameBorderThickness, // Win 11 22000
SystemBackdropType // Win 11 22621
}
public enum DWMCLOACKEDREASON : uint {
DWM_CLOAKED_APP = 0x0000001, //cloaked by its owner application.
DWM_CLOAKED_SHELL = 0x0000002, //cloaked by the Shell.
DWM_CLOAKED_INHERITED = 0x0000004 //inherited from its owner window.
}
public enum DWMNCRENDERINGPOLICY : uint {
UseWindowStyle, // Enable/disable non-client rendering based on window style
Disabled, // Disabled non-client rendering; window style is ignored
Enabled, // Enabled non-client rendering; window style is ignored
};
public enum DWMACCENTSTATE {
ACCENT_DISABLED = 0,
ACCENT_ENABLE_GRADIENT = 1,
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
ACCENT_ENABLE_BLURBEHIND = 3,
ACCENT_INVALID_STATE = 4
}
[Flags]
public enum CompositionAction : uint {
DWM_EC_DISABLECOMPOSITION = 0,
DWM_EC_ENABLECOMPOSITION = 1
}
// Values designating how Flip3D treats a given window.
enum DWMFLIP3DWINDOWPOLICY : uint {
Default, // Hide or include the window in Flip3D based on window style and visibility.
ExcludeBelow, // Display the window under Flip3D and disabled.
ExcludeAbove, // Display the window above Flip3D and enabled.
};
public enum ThumbProperties_dwFlags : uint {
RectDestination = 0x00000001,
RectSource = 0x00000002,
Opacity = 0x00000004,
Visible = 0x00000008,
SourceClientAreaOnly = 0x00000010
}
[StructLayout(LayoutKind.Sequential)]
public struct AccentPolicy {
public DWMACCENTSTATE AccentState;
public int AccentFlags;
public int GradientColor;
public int AnimationId;
public AccentPolicy(DWMACCENTSTATE accentState, int accentFlags, int gradientColor, int animationId)
{
AccentState = accentState;
AccentFlags = accentFlags;
GradientColor = gradientColor;
AnimationId = animationId;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct DWM_BLURBEHIND {
public DWM_BB dwFlags;
public int fEnable;
public IntPtr hRgnBlur;
public int fTransitionOnMaximized;
public DWM_BLURBEHIND(bool enabled)
{
dwFlags = DWM_BB.Enable;
fEnable = (enabled) ? 1 : 0;
hRgnBlur = IntPtr.Zero;
fTransitionOnMaximized = 0;
}
public Region Region => Region.FromHrgn(hRgnBlur);
public bool TransitionOnMaximized {
get => fTransitionOnMaximized > 0;
set {
fTransitionOnMaximized = (value) ? 1 : 0;
dwFlags |= DWM_BB.TransitionOnMaximized;
}
}
public void SetRegion(Graphics graphics, Region region)
{
hRgnBlur = region.GetHrgn(graphics);
dwFlags |= DWM_BB.BlurRegion;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct WinCompositionAttrData {
public DWMWINDOWATTRIBUTE Attribute;
public IntPtr Data; //Will point to an AccentPolicy struct, where Attribute will be DWMWINDOWATTRIBUTE.AccentPolicy
public int SizeOfData;
public WinCompositionAttrData(DWMWINDOWATTRIBUTE attribute, IntPtr data, int sizeOfData)
{
Attribute = attribute;
Data = data;
SizeOfData = sizeOfData;
}
}
private static int GetBlurBehindPolicyAccentFlags()
{
int drawLeftBorder = 20;
int drawTopBorder = 40;
int drawRightBorder = 80;
int drawBottomBorder = 100;
return (drawLeftBorder | drawTopBorder | drawRightBorder | drawBottomBorder);
}
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa969508(v=vs.85).aspx
[DllImport("dwmapi.dll")]
internal static extern int DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind);
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmEnableComposition(CompositionAction uCompositionAction);
//https://msdn.microsoft.com/it-it/library/windows/desktop/aa969512(v=vs.85).aspx
[DllImport("dwmapi.dll")]
internal static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa969515(v=vs.85).aspx
[DllImport("dwmapi.dll")]
internal static extern int DwmGetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attr, ref int attrValue, int attrSize);
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa969524(v=vs.85).aspx
[DllImport("dwmapi.dll")]
internal static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attr, ref int attrValue, int attrSize);
[DllImport("User32.dll", SetLastError = true)]
internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WinCompositionAttrData data);
[DllImport("dwmapi.dll")]
internal static extern int DwmIsCompositionEnabled(ref int pfEnabled);
public static bool IsCompositionEnabled()
{
int pfEnabled = 0;
int result = DwmIsCompositionEnabled(ref pfEnabled);
return (pfEnabled == 1) ? true : false;
}
public static bool IsNonClientRenderingEnabled(IntPtr hWnd)
{
int gwaEnabled = 0;
int result = DwmGetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingEnabled, ref gwaEnabled, sizeof(int));
return gwaEnabled == 1;
}
public static bool WindowSetAttribute(IntPtr hWnd, DWMWINDOWATTRIBUTE attribute, int attributeValue)
{
int result = DwmSetWindowAttribute(hWnd, attribute, ref attributeValue, sizeof(int));
return (result == 0);
}
public static void Windows10EnableBlurBehind(IntPtr hWnd)
{
DWMNCRENDERINGPOLICY policy = DWMNCRENDERINGPOLICY.Enabled;
WindowSetAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingPolicy, (int)policy);
AccentPolicy accPolicy = new AccentPolicy() {
AccentState = DWMACCENTSTATE.ACCENT_ENABLE_BLURBEHIND,
};
int accentSize = Marshal.SizeOf(accPolicy);
IntPtr accentPtr = Marshal.AllocHGlobal(accentSize);
Marshal.StructureToPtr(accPolicy, accentPtr, false);
var data = new WinCompositionAttrData(DWMWINDOWATTRIBUTE.AccentPolicy, accentPtr, accentSize);
SetWindowCompositionAttribute(hWnd, ref data);
Marshal.FreeHGlobal(accentPtr);
}
public static bool WindowEnableBlurBehind(IntPtr hWnd)
{
DWMNCRENDERINGPOLICY policy = DWMNCRENDERINGPOLICY.Enabled;
WindowSetAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingPolicy, (int)policy);
DWM_BLURBEHIND dwm_BB = new DWM_BLURBEHIND(true);
int result = DwmEnableBlurBehindWindow(hWnd, ref dwm_BB);
return result == 0;
}
public static bool WindowExtendIntoClientArea(IntPtr hWnd, MARGINS margins)
{
// Extend frame on the bottom of client area
int result = DwmExtendFrameIntoClientArea(hWnd, ref margins);
return result == 0;
}
public static bool WindowBorderlessDropShadow(IntPtr hWnd, int shadowSize)
{
MARGINS margins = new MARGINS(0, shadowSize, 0, shadowSize);
int result = DwmExtendFrameIntoClientArea(hWnd, ref margins);
return result == 0;
}
public static bool WindowSheetOfGlass(IntPtr hWnd)
{
MARGINS margins = new MARGINS();
//Margins set to All:-1 - Sheet Of Glass effect
margins.SheetOfGlass();
int result = DwmExtendFrameIntoClientArea(hWnd, ref margins);
return result == 0;
}
public static bool WindowDisableRendering(IntPtr hWnd)
{
int ncrp = (int)DWMNCRENDERINGPOLICY.Disabled;
// Disable non-client area rendering on the window.
int result = DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.NCRenderingPolicy, ref ncrp, sizeof(int));
return result == 0;
}
} //DWM
1条答案
按热度按时间p1iqtdky1#
应用了模糊效果的
WinForms
Form
,使用:Windows 7 ⇒ DwmEnableBlurBehindWindow()显示工作站功能。
Windows 10 / 11 ⇒**
SetWindowCompositionAttribute()
**User32
功能(未记录)如何应用“背景模糊”效果:
Windows 7操作系统:
Windows需要向DwmSetWindowAttribute()注册呈现策略,将DWMWINDOWATTRIBUTE枚举器设置为
NCRenderingPolicy
并启用它,将DWMNCRENDERINGPOLICY枚举器设置为Enabled
。您可能还希望重写窗体的类
WndProc
;收到WM_DWMCOMPOSITIONCHANGED消息(通知Aero合成状态)时,验证DWM合成是否启用。在显示Window界面之前,调用DwmEnableBlurBehindWindow(),将其DWM_BLURBEHIND结构相关字段(
dwFlags
和fEnable
)设置为1
。在这里,我从窗体的构造函数调用它。
Windows 10和Windows 11:
此代码使用了尚未记录的**
SetWindowCompositionAttribute()
函数。User32
函数仅需要使用内部结构,这里称为WinCompositionAttrData
,其中Attribute
成员被设置为DWMWINDOWATTRIBUTE.AccentPolicy
,并且Data
成员被设置为内部结构的指针,这里称为AccentPolicy
,其中AccentState
成员被设置为DWMACCENTSTATE.ACCENT_ENABLE_BLURBEHIND
**“DWM合成”始终处于启用状态。无需验证或替代
WndProc
即可处理DWM合成更改。在代码中更清楚:
(As注意,如果窗体的背景色为白色,则
BlurBehind
效果不起作用)请参阅关于
DwmExtendFrameIntoClientArea()
实现的另一个问题。Dwm
类包含上面使用的所有互操作函数和结构,以及在此上下文中可能有用的一系列其他方法这是
Form.BackColor
设置为MidnightBlue
的示例结果:上面有一些控件: