避免窗口最大化時遮蓋任務欄

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     }
View Code

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章