Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 253 lines (210 sloc) 10.442 kB
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
1 using System;
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
2 using System.Linq;
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
3 using System.Runtime.InteropServices;
4 using System.Windows;
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
5 using System.Windows.Controls;
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
6 using System.Windows.Interactivity;
7 using System.Windows.Interop;
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
8 using System.Windows.Media;
9 using MahApps.Metro.Controls;
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
10 using MahApps.Metro.Native;
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
11
12 namespace MahApps.Metro.Behaviours
13 {
14 public class BorderlessWindowBehavior : Behavior<Window>
15 {
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
16 [DllImport("dwmapi", PreserveSig = false)]
17 public static extern bool DwmIsCompositionEnabled();
18
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
19 [DllImport("dwmapi")]
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
20 private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
21
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
22 [DllImport("user32")]
23 public static extern IntPtr DefWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
24
25 [DllImport("user32")]
26 internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);
27
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
28 [DllImport("user32")]
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
29 internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);
30
70b8729 Fixed the no-shadow issue on a non-resizable window
sirWest authored
31 [DllImport("dwmapi.dll", PreserveSig = true)]
32 private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
33
34 [DllImport("dwmapi.dll")]
35 private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMarInset);
36
37 [StructLayout(LayoutKind.Sequential)]
38 private struct Margins
39 {
40 internal int leftWidth;
41 internal int rightWidth;
42 internal int topHeight;
43 internal int bottomHeight;
44 }
45
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
46 private HwndSource m_hwndSource;
47 private IntPtr m_hwnd;
48
49 public static DependencyProperty ResizeWithGripProperty = DependencyProperty.Register("ResizeWithGrip", typeof(bool), typeof(BorderlessWindowBehavior), new PropertyMetadata(true));
50 public static DependencyProperty AutoSizeToContentProperty = DependencyProperty.Register("AutoSizeToContent", typeof(bool), typeof(BorderlessWindowBehavior), new PropertyMetadata(false));
51
52 private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
53 {
54
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
55 var mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
56
57 // Adjust the maximized size and position to fit the work area of the correct monitor
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
58
59 System.IntPtr monitor = MonitorFromWindow(hwnd, Constants.MONITOR_DEFAULTTONEAREST);
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
60
61 if (monitor != System.IntPtr.Zero)
62 {
63
64 MONITORINFO monitorInfo = new MONITORINFO();
65 GetMonitorInfo(monitor, monitorInfo);
66 RECT rcWorkArea = monitorInfo.rcWork;
67 RECT rcMonitorArea = monitorInfo.rcMonitor;
68 mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left);
69 mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);
70 mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left);
71 mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);
72 }
73
74 Marshal.StructureToPtr(mmi, lParam, true);
75 }
76
a85b006 small change with borderlesswindowbehaviour
aeoth authored
77 public bool ResizeWithGrip
78 {
79 get { return (bool)GetValue(ResizeWithGripProperty); }
80 set { SetValue(ResizeWithGripProperty, value); }
81 }
82
e726ab7 Minor restyles (to make themeable) for ListView/GridView stuff.
aeoth authored
83 public bool AutoSizeToContent
84 {
85 get { return (bool)GetValue(AutoSizeToContentProperty); }
86 set { SetValue(AutoSizeToContentProperty, value); }
87 }
88
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
89 public Border Border { get; set; }
e726ab7 Minor restyles (to make themeable) for ListView/GridView stuff.
aeoth authored
90
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
91 protected override void OnAttached()
92 {
f2a7b14 @distantcam Added MetroWindow. Fixed BorderlessWindowStyle to be used in a template.
distantcam authored
93 if (HwndSource.FromVisual(AssociatedObject) != null)
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
94 AddHwndHook();
95 else
96 AssociatedObject.SourceInitialized += AssociatedObject_SourceInitialized;
97
98 AssociatedObject.WindowStyle = WindowStyle.None;
a85b006 small change with borderlesswindowbehaviour
aeoth authored
99
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
100 if (AssociatedObject is MetroWindow)
101 {
b8acc7d Fixed #37, can now show/hide min/max buttons from a metrowindow
aeoth authored
102 var window = ((MetroWindow) AssociatedObject);
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
103 //MetroWindow already has a border we can use
104 AssociatedObject.Loaded += (s, e) =>
105 {
b8acc7d Fixed #37, can now show/hide min/max buttons from a metrowindow
aeoth authored
106 var ancestors = window.GetPart<Border>("PART_Border");
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
107 Border = ancestors;
b8acc7d Fixed #37, can now show/hide min/max buttons from a metrowindow
aeoth authored
108
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
109 };
b8acc7d Fixed #37, can now show/hide min/max buttons from a metrowindow
aeoth authored
110
111 if (AssociatedObject.ResizeMode == ResizeMode.NoResize)
112 {
113 window.ShowMaxRestoreButton = false;
70b8729 Fixed the no-shadow issue on a non-resizable window
sirWest authored
114 window.ShowMinButton = false;
115 window.MaxWidth = window.Width;
116 window.MaxHeight = window.Height;
117 ResizeWithGrip = false;
118 }
119 else if (AssociatedObject.ResizeMode == ResizeMode.CanMinimize)
120 {
121 window.ShowMaxRestoreButton = false;
b8acc7d Fixed #37, can now show/hide min/max buttons from a metrowindow
aeoth authored
122 window.MaxWidth = window.Width;
123 window.MaxHeight = window.Height;
124 ResizeWithGrip = false;
125 }
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
126 }
127 else {
128 //Other windows may not, easiest to just inject one!
129 var content = (UIElement) AssociatedObject.Content;
130 AssociatedObject.Content = null;
131
132 Border = new Border
133 {
134 Child = content,
135 BorderBrush = new SolidColorBrush(Colors.Black)
136 };
137
138 AssociatedObject.Content = Border;
139 }
b8acc7d Fixed #37, can now show/hide min/max buttons from a metrowindow
aeoth authored
140
402502a Added a small top and bottom border to tooltip - it was a bit weird b…
sirWest authored
141 if (ResizeWithGrip)
142 AssociatedObject.ResizeMode = ResizeMode.CanResizeWithGrip;
143
e726ab7 Minor restyles (to make themeable) for ListView/GridView stuff.
aeoth authored
144 if (AutoSizeToContent)
145 AssociatedObject.Loaded += (s, e) =>
146 {
147 //Temp fix, thanks @lynnx
148 AssociatedObject.SizeToContent = SizeToContent.Height;
149 AssociatedObject.SizeToContent = AutoSizeToContent
150 ? SizeToContent.WidthAndHeight
151 : SizeToContent.Manual;
152 };
153
b8acc7d Fixed #37, can now show/hide min/max buttons from a metrowindow
aeoth authored
154
155
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
156 base.OnAttached();
157 }
158
159 protected override void OnDetaching()
160 {
161 RemoveHwndHook();
162 base.OnDetaching();
163 }
164
165 private void AddHwndHook()
166 {
167 m_hwndSource = HwndSource.FromVisual(AssociatedObject) as HwndSource;
168 m_hwndSource.AddHook(HwndHook);
169 m_hwnd = new WindowInteropHelper(AssociatedObject).Handle;
170 }
171
172 private void RemoveHwndHook()
173 {
174 AssociatedObject.SourceInitialized -= AssociatedObject_SourceInitialized;
175 m_hwndSource.RemoveHook(HwndHook);
176 }
177
178 private void AssociatedObject_SourceInitialized(object sender, EventArgs e)
179 {
180 AddHwndHook();
70b8729 Fixed the no-shadow issue on a non-resizable window
sirWest authored
181
182 var helper = new WindowInteropHelper(AssociatedObject);
183 var val = 2;
184 DwmSetWindowAttribute(helper.Handle, 2, ref val, 4);
185 var m = new Margins
186 {
187 bottomHeight = -1,
188 leftWidth = -1,
189 rightWidth = -1,
190 topHeight = -1
191 };
192 DwmExtendFrameIntoClientArea(helper.Handle, ref m);
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
193 }
194
195 private IntPtr HwndHook(IntPtr hWnd, int message, IntPtr wParam, IntPtr lParam, ref bool handled)
196 {
197 IntPtr returnval = IntPtr.Zero;
198 switch (message)
199 {
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
200 case Constants.WM_CREATE:
e726ab7 Minor restyles (to make themeable) for ListView/GridView stuff.
aeoth authored
201 handled = true;
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
202 var create = (CREATESTRUCT)Marshal.PtrToStructure(lParam, typeof(CREATESTRUCT));
203 if (create.style == Constants.WS_MAXIMIZE)
204 {
205 MessageBox.Show("Got here");
206 }
e726ab7 Minor restyles (to make themeable) for ListView/GridView stuff.
aeoth authored
207 break;
208
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
209 case Constants.WM_NCCALCSIZE:
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
210 /* Hides the border */
211 handled = true;
212 break;
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
213 case Constants.WM_NCPAINT:
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
214 {
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
215 if (Environment.OSVersion.Version.Major >= 6 && DwmIsCompositionEnabled())
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
216 {
217 var m = new MARGINS { bottomHeight = 1, leftWidth = 1, rightWidth = 1, topHeight = 1 };
218 DwmExtendFrameIntoClientArea(m_hwnd, ref m);
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
219 if (Border != null)
220 Border.BorderThickness = new Thickness(0);
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
221 }
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
222 else
223 {
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
224 if (Border != null)
225 Border.BorderThickness = new Thickness(1);
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
226 }
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
227 handled = true;
228 }
229 break;
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
230 case Constants.WM_NCACTIVATE:
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
231 {
232 /* As per http://msdn.microsoft.com/en-us/library/ms632633(VS.85).aspx , "-1" lParam
233 * "does not repaint the nonclient area to reflect the state change." */
234 returnval = DefWindowProc(hWnd, message, wParam, new IntPtr(-1));
235 handled = true;
236 }
237 break;
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
238 case Constants.WM_GETMINMAXINFO:
239 /* http://blogs.msdn.com/b/llobo/archive/2006/08/01/maximizing-window-_2800_with-windowstyle_3d00_none_2900_-considering-taskbar.aspx */
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
240 WmGetMinMaxInfo(hWnd, lParam);
9ea6547 House cleaning - moved native structs to their own files, moved const…
aeoth authored
241
c139dbf @akoeplinger fixed typo...
akoeplinger authored
242 /* Setting handled to false enables the application to process it's own Min/Max requirements,
3b53873 @akoeplinger Fixed #21: MetroWindow doesn't respect MinWidth/MinHeight
akoeplinger authored
243 * as mentioned by jason.bullard (comment from September 22, 2011) on http://gallery.expression.microsoft.com/ZuneWindowBehavior/ */
244 handled = false;
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
245 break;
246 }
247
49b5109 Added a fake border for cases where DWM is disabled or XP
aeoth authored
248
849b1d2 Added JMorril's BorderlessWindowBehaviour
aeoth authored
249 return returnval;
250 }
251 }
252 }
Something went wrong with that request. Please try again.