浏览代码

use Action to set flags and recalculate wmstyles.

Dan Walmsley 7 年之前
父节点
当前提交
3ce39fe7a0
共有 2 个文件被更改,包括 64 次插入59 次删除
  1. 33 31
      samples/ControlCatalog/DecoratedWindow.xaml
  2. 31 28
      src/Windows/Avalonia.Win32/WindowImpl.cs

+ 33 - 31
samples/ControlCatalog/DecoratedWindow.xaml

@@ -3,36 +3,38 @@
         x:Class="ControlCatalog.DecoratedWindow"
         Title="Avalonia Control Gallery"
         xmlns:local="clr-namespace:ControlCatalog" HasSystemDecorations="False" Name="Window">
-  <Grid RowDefinitions="5,*,5" ColumnDefinitions="5,*,5">
-    <DockPanel  Grid.Column="1"  Grid.Row="1" >
-      <Grid Name="TitleBar" Background="LightBlue" DockPanel.Dock="Top" ColumnDefinitions="Auto,*,Auto">
-      <TextBlock VerticalAlignment="Center" Margin="5,0,0,0">Title</TextBlock>
-        <StackPanel Grid.Column="2" Orientation="Horizontal">
-          <StackPanel.Styles>
-            <Style Selector="Button">
-              <Setter Property="Margin" Value="2"/>
-            </Style>
-          </StackPanel.Styles>
-        <Button Name="MinimizeButton">_</Button>
-        <Button Name="MaximizeButton">[ ]</Button>
-        <Button Name="CloseButton">X</Button>
-        </StackPanel>
-      </Grid>
-      <Border Background="White" Margin="5">
-        <StackPanel>
-        <TextBlock>Hello world!</TextBlock>
+    <Grid RowDefinitions="5,*,5" ColumnDefinitions="5,*,5">
+        <DockPanel  Grid.Column="1"  Grid.Row="1" >
+            <Grid Name="TitleBar" Background="LightBlue" DockPanel.Dock="Top" ColumnDefinitions="Auto,*,Auto">
+                <TextBlock VerticalAlignment="Center" Margin="5,0,0,0">Title</TextBlock>
+                <StackPanel Grid.Column="2" Orientation="Horizontal">
+                    <StackPanel.Styles>
+                        <Style Selector="Button">
+                            <Setter Property="Margin" Value="2"/>
+                        </Style>
+                    </StackPanel.Styles>
+                    <Button Name="MinimizeButton">_</Button>
+                    <Button Name="MaximizeButton">[ ]</Button>
+                    <Button Name="CloseButton">X</Button>
+                </StackPanel>
+            </Grid>
+            <Border Background="White" Margin="5">
+                <StackPanel>
+                    <TextBlock>Hello world!</TextBlock>
 
-        <CheckBox IsChecked="{Binding ElementName=Window, Path=HasSystemDecorations}">Decorated</CheckBox>
-        </StackPanel>
-      </Border>
-    </DockPanel>
-    <Border Name="TopLeft" Background="Red"/>
-    <Border Name="TopRight" Background="Red" Grid.Column="2" />
-    <Border Name="BottomLeft" Background="Red" Grid.Row="2" />
-    <Border Name="BottomRight" Background="Red"  Grid.Row="2" Grid.Column="2"/>
-    <Border Name="Top" Background="Blue" Grid.Column="1" />
-    <Border Name="Right" Background="Blue" Grid.Row="1"  Grid.Column="2" />
-    <Border Name="Bottom" Background="Blue" Grid.Row="2" Grid.Column="1"  />
-    <Border Name="Left" Background="Blue"  Grid.Row="1" />
-  </Grid>
+                    <CheckBox IsChecked="{Binding ElementName=Window, Path=HasSystemDecorations}">Decorated</CheckBox>
+
+                    <CheckBox IsChecked="{Binding ElementName=Window, Path=CanResize}">CanResize</CheckBox>
+                </StackPanel>
+            </Border>
+        </DockPanel>
+        <Border Name="TopLeft" Background="Red"/>
+        <Border Name="TopRight" Background="Red" Grid.Column="2" />
+        <Border Name="BottomLeft" Background="Red" Grid.Row="2" />
+        <Border Name="BottomRight" Background="Red"  Grid.Row="2" Grid.Column="2"/>
+        <Border Name="Top" Background="Blue" Grid.Column="1" />
+        <Border Name="Right" Background="Blue" Grid.Row="1"  Grid.Column="2" />
+        <Border Name="Bottom" Background="Blue" Grid.Row="2" Grid.Column="1"  />
+        <Border Name="Left" Background="Blue"  Grid.Row="1" />
+    </Grid>
 </Window>

+ 31 - 28
src/Windows/Avalonia.Win32/WindowImpl.cs

@@ -271,9 +271,7 @@ namespace Avalonia.Win32
                 return;
             }
 
-            _decorated = value;
-
-            UpdateWMStyles();
+            UpdateWMStyles(()=> _decorated = value);
         }
 
         public void Invalidate(Rect rect)
@@ -886,8 +884,13 @@ namespace Avalonia.Win32
             }
         }
 
-        private void UpdateWMStyles()
+        private void UpdateWMStyles(Action change)
         {
+            var decorated = _decorated;
+            var resizable = _resizable;
+
+            change();
+
             var style = (WindowStyles)GetWindowLong(_hwnd, (int)WindowLongParam.GWL_STYLE);
 
             const WindowStyles controlledFlags = WindowStyles.WS_OVERLAPPEDWINDOW;
@@ -912,31 +915,33 @@ namespace Avalonia.Win32
 
             UnmanagedMethods.GetWindowRect(_hwnd, out var windowRect);
 
-            Rect newRect;
-
-            if (_decorated)
+            if (decorated != _decorated)
             {
-                var thickness = BorderThickness;
+                Rect newRect;
 
-                newRect = new Rect(
-                    windowRect.left - thickness.Left,
-                    windowRect.top - thickness.Top,
-                    (windowRect.right - windowRect.left) + (thickness.Left + thickness.Right),
-                    (windowRect.bottom - windowRect.top) + (thickness.Top + thickness.Bottom));
-            }
-            else
-            {
-                newRect = new Rect(
-                    windowRect.left + oldThickness.Left,
-                    windowRect.top + oldThickness.Top,
-                    (windowRect.right - windowRect.left) - (oldThickness.Left + oldThickness.Right),
-                    (windowRect.bottom - windowRect.top) - (oldThickness.Top + oldThickness.Bottom));
-            }
+                if (_decorated)
+                {
+                    var thickness = BorderThickness;
 
-            UnmanagedMethods.SetWindowPos(_hwnd, IntPtr.Zero, (int)newRect.X, (int)newRect.Y, (int)newRect.Width,
-                (int)newRect.Height,
-                UnmanagedMethods.SetWindowPosFlags.SWP_NOZORDER | UnmanagedMethods.SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_FRAMECHANGED);
+                    newRect = new Rect(
+                        windowRect.left - thickness.Left,
+                        windowRect.top - thickness.Top,
+                        (windowRect.right - windowRect.left) + (thickness.Left + thickness.Right),
+                        (windowRect.bottom - windowRect.top) + (thickness.Top + thickness.Bottom));
+                }
+                else
+                {
+                    newRect = new Rect(
+                        windowRect.left + oldThickness.Left,
+                        windowRect.top + oldThickness.Top,
+                        (windowRect.right - windowRect.left) - (oldThickness.Left + oldThickness.Right),
+                        (windowRect.bottom - windowRect.top) - (oldThickness.Top + oldThickness.Bottom));
+                }
 
+                UnmanagedMethods.SetWindowPos(_hwnd, IntPtr.Zero, (int)newRect.X, (int)newRect.Y, (int)newRect.Width,
+                    (int)newRect.Height,
+                    UnmanagedMethods.SetWindowPosFlags.SWP_NOZORDER | UnmanagedMethods.SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_FRAMECHANGED);
+            }
         }
 
         public void CanResize(bool value)
@@ -946,9 +951,7 @@ namespace Avalonia.Win32
                 return;
             }
 
-            _resizable = value;
-
-            UpdateWMStyles();
+            UpdateWMStyles(()=> _resizable = value);
         }
 
         public void SetTopmost(bool value)