WinForms添加模糊效果的窗口设置Maximized后无法正常最大化
问题原因
- 构造函数属性执行顺序错误:
InitializeComponent()是加载设计器配置(包括你设置的WindowState = Maximized)的核心方法,你将自定义样式、边框设置、透明度配置放在了它的前后错误位置,设计器配置会覆盖你提前设置的自定义属性,导致窗口状态不符合预期。 - 无边框窗口最大化默认预留边距:WinForms 无边框窗口设置为最大化时,系统会默认预留原窗口边框的约8px边距,这是系统内置的兼容逻辑,就是你看到的左上角空白区域。
修复方案
按以下步骤调整代码即可:
- 把
InitializeComponent()移到构造函数第一行,确保设计器配置先加载,再应用自定义属性 - 重写
WndProc方法处理WM_GETMINMAXINFO消息,移除最大化时的默认边距 - 把
EnableBlur调用移到窗口句柄初始化完成之后执行,避免句柄未就绪导致效果失效
修正后完整代码
using System.Runtime.InteropServices; namespace WF4 { public partial class Form1 : Form { // 处理最大化消息需要的API常量 private const int WM_GETMINMAXINFO = 0x0024; public Form1() { // 设计器配置必须第一行加载 InitializeComponent(); // 基础样式配置 SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true); SetStyle(ControlStyles.SupportsTransparentBackColor, true); BackColor = Color.LimeGreen; TransparencyKey = Color.LimeGreen; FormBorderStyle = FormBorderStyle.None; WindowState = FormWindowState.Maximized; } protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); // 句柄创建完成后再启用模糊效果 this.EnableBlur(); } // 重写消息处理,移除最大化默认边距 protected override void WndProc(ref Message m) { if (m.Msg == WM_GETMINMAXINFO) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(m.LParam, typeof(MINMAXINFO)); // 设置最大化尺寸为当前屏幕的完整尺寸 Screen currentScreen = Screen.FromHandle(this.Handle); Rectangle workingArea = currentScreen.Bounds; mmi.ptMaxPosition.X = workingArea.Left; mmi.ptMaxPosition.Y = workingArea.Top; mmi.ptMaxSize.X = workingArea.Width; mmi.ptMaxSize.Y = workingArea.Height; Marshal.StructureToPtr(mmi, m.LParam, true); } base.WndProc(ref m); } private void Form1_Load(object sender, EventArgs e) { } private void Form1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { MessageBox.Show("Hllo"); } } // 定义WM_GETMINMAXINFO需要的结构体 [StructLayout(LayoutKind.Sequential)] public struct POINT { public int X; public int Y; } [StructLayout(LayoutKind.Sequential)] public struct MINMAXINFO { public POINT ptReserved; public POINT ptMaxSize; public POINT ptMaxPosition; public POINT ptMinTrackSize; public POINT ptMaxTrackSize; } } public static class WindowExtension { [DllImport("user32.dll")] static internal extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data); public static void EnableBlur(this Form @this) { var accent = new AccentPolicy(); accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND; var accentStructSize = Marshal.SizeOf(accent); var accentPtr = Marshal.AllocHGlobal(accentStructSize); Marshal.StructureToPtr(accent, accentPtr, false); var Data = new WindowCompositionAttributeData(); Data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY; Data.SizeOfData = accentStructSize; Data.Data = accentPtr; SetWindowCompositionAttribute(@this.Handle, ref Data); Marshal.FreeHGlobal(accentPtr); } } enum AccentState { ACCENT_DISABLED = 0, ACCENT_ENABLE_GRADIENT = 1, ACCENT_ENABLE_TRANSPARENTGRADIENT = 2, ACCENT_ENABLE_BLURBEHIND = 3, ACCENT_INVALID_STATE = 4 } struct AccentPolicy { public AccentState AccentState; public int AccentFlags; public int GradientColor; public int AnimationId; } struct WindowCompositionAttributeData { public WindowCompositionAttribute Attribute; public IntPtr Data; public int SizeOfData; } enum WindowCompositionAttribute { WCA_ACCENT_POLICY = 19 } }
内容的提问来源于stack exchange,提问作者Extorc Productions
相关产品推荐
相关产品推荐

