避免窗口最大化时遮盖任务栏
WPF窗口最大化时有个很不好的现象是:如果窗口的WindowStyle被直接或间接地设置为None,那么最大化窗口后,窗口将铺满整个屏幕而将任务栏盖住。
调用FullScreenManager.RepairWpfWindowFullScreenBehavior(this);

1 public static class FullScreenManager 2 { 3 public static void RepairWpfWindowFullScreenBehavior(Window wpfWindow) 4 { 5 if (wpfWindow == null) 6 { 7 return; 8 } 9 10 if (wpfWindow.WindowState == WindowState.Maximized) 11 { 12 wpfWindow.WindowState = WindowState.Normal; 13 wpfWindow.Loaded += delegate { wpfWindow.WindowState = WindowState.Maximized; }; 14 } 15 16 wpfWindow.SourceInitialized += delegate 17 { 18 IntPtr handle = (new WindowInteropHelper(wpfWindow)).Handle; 19 HwndSource source = HwndSource.FromHwnd(handle); 20 if (source != null) 21 { 22 source.AddHook(WindowProc); 23 } 24 }; 25 } 26 27 private static IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 28 { 29 switch (msg) 30 { 31 case 0x0024: 32 WmGetMinMaxInfo(hwnd, lParam); 33 handled = true; 34 break; 35 } 36 37 return (IntPtr)0; 38 } 39 40 private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam) 41 { 42 var mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); 43 44 // Adjust the maximized size and position to fit the work area of the correct monitor 45 int MONITOR_DEFAULTTONEAREST = 0x00000002; 46 IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); 47 48 if (monitor != IntPtr.Zero) 49 { 50 var monitorInfo = new MONITORINFO(); 51 GetMonitorInfo(monitor, monitorInfo); 52 RECT rcWorkArea = monitorInfo.rcWork; 53 RECT rcMonitorArea = monitorInfo.rcMonitor; 54 mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left); 55 mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top); 56 mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left); 57 mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top); 58 } 59 60 Marshal.StructureToPtr(mmi, lParam, true); 61 } 62 63 64 [DllImport("user32")] 65 internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi); 66 67 /// <summary> 68 /// 69 /// </summary> 70 [DllImport("User32")] 71 internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags); 72 73 #region Nested type: MINMAXINFO 74 75 [StructLayout(LayoutKind.Sequential)] 76 internal struct MINMAXINFO 77 { 78 public POINT ptReserved; 79 public POINT ptMaxSize; 80 public POINT ptMaxPosition; 81 public POINT ptMinTrackSize; 82 public POINT ptMaxTrackSize; 83 }; 84 85 #endregion 86 87 #region Nested type: MONITORINFO 88 89 /// <summary> 90 /// </summary> 91 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 92 internal class MONITORINFO 93 { 94 /// <summary> 95 /// </summary> 96 public int cbSize = Marshal.SizeOf(typeof(MONITORINFO)); 97 98 /// <summary> 99 /// </summary> 100 public RECT rcMonitor; 101 102 /// <summary> 103 /// </summary> 104 public RECT rcWork; 105 106 /// <summary> 107 /// </summary> 108 public int dwFlags; 109 } 110 111 #endregion 112 113 #region Nested type: POINT 114 115 /// <summary> 116 /// POINT aka POINTAPI 117 /// </summary> 118 [StructLayout(LayoutKind.Sequential)] 119 internal struct POINT 120 { 121 /// <summary> 122 /// x coordinate of point. 123 /// </summary> 124 public int x; 125 126 /// <summary> 127 /// y coordinate of point. 128 /// </summary> 129 public int y; 130 131 /// <summary> 132 /// Construct a point of coordinates (x,y). 133 /// </summary> 134 public POINT(int x, int y) 135 { 136 this.x = x; 137 this.y = y; 138 } 139 } 140 141 #endregion 142 143 #region Nested type: RECT 144 145 /// <summary> Win32 </summary> 146 [StructLayout(LayoutKind.Sequential, Pack = 0)] 147 internal struct RECT 148 { 149 /// <summary> Win32 </summary> 150 public int left; 151 152 /// <summary> Win32 </summary> 153 public int top; 154 155 /// <summary> Win32 </summary> 156 public int right; 157 158 /// <summary> Win32 </summary> 159 public int bottom; 160 161 /// <summary> Win32 </summary> 162 public static readonly RECT Empty; 163 164 /// <summary> Win32 </summary> 165 public int Width 166 { 167 get { return Math.Abs(right - left); } // Abs needed for BIDI OS 168 } 169 170 /// <summary> Win32 </summary> 171 public int Height 172 { 173 get { return bottom - top; } 174 } 175 176 /// <summary> Win32 </summary> 177 public RECT(int left, int top, int right, int bottom) 178 { 179 this.left = left; 180 this.top = top; 181 this.right = right; 182 this.bottom = bottom; 183 } 184 185 186 /// <summary> Win32 </summary> 187 public RECT(RECT rcSrc) 188 { 189 left = rcSrc.left; 190 top = rcSrc.top; 191 right = rcSrc.right; 192 bottom = rcSrc.bottom; 193 } 194 195 /// <summary> Win32 </summary> 196 public bool IsEmpty 197 { 198 get 199 { 200 // BUGBUG : On Bidi OS (hebrew arabic) left > right 201 return left >= right || top >= bottom; 202 } 203 } 204 205 /// <summary> Return a user friendly representation of this struct </summary> 206 public override string ToString() 207 { 208 if (this == Empty) 209 { 210 return "RECT {Empty}"; 211 } 212 return "RECT { left : " + left + " / top : " + top + " / right : " + right + " / bottom : " + bottom + 213 " }"; 214 } 215 216 /// <summary> Determine if 2 RECT are equal (deep compare) </summary> 217 public override bool Equals(object obj) 218 { 219 if (!(obj is Rect)) 220 { 221 return false; 222 } 223 return (this == (RECT)obj); 224 } 225 226 /// <summary>Return the HashCode for this struct (not garanteed to be unique)</summary> 227 public override int GetHashCode() 228 { 229 return left.GetHashCode() + top.GetHashCode() + right.GetHashCode() + bottom.GetHashCode(); 230 } 231 232 233 /// <summary> Determine if 2 RECT are equal (deep compare)</summary> 234 public static bool operator ==(RECT rect1, RECT rect2) 235 { 236 return (rect1.left == rect2.left && rect1.top == rect2.top && rect1.right == rect2.right && 237 rect1.bottom == rect2.bottom); 238 } 239 240 /// <summary> Determine if 2 RECT are different(deep compare)</summary> 241 public static bool operator !=(RECT rect1, RECT rect2) 242 { 243 return !(rect1 == rect2); 244 } 245 } 246 247 #endregion 248 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!