From 8f24ccf44181db5617048cc0779cf284f0349a6e Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Fri, 11 Dec 2015 04:11:57 +0300 Subject: [PATCH] Added Window::HasSystemDecorations property --- .../Platform/SkiaPlatform/WindowImpl.cs | 3 ++ src/Gtk/Perspex.Gtk/WindowImpl.cs | 2 + src/Perspex.Controls/Platform/IWindowImpl.cs | 5 +++ .../Platform/PlatformManager.cs | 1 + src/Perspex.Controls/Window.cs | 18 ++++++++ .../Perspex.Win32/Interop/UnmanagedMethods.cs | 3 ++ src/Windows/Perspex.Win32/WindowImpl.cs | 43 +++++++++++++++++++ src/iOS/Perspex.iOS/PerspexView.cs | 5 +++ 8 files changed, 80 insertions(+) diff --git a/src/Android/Perspex.Android/Platform/SkiaPlatform/WindowImpl.cs b/src/Android/Perspex.Android/Platform/SkiaPlatform/WindowImpl.cs index b7125a56ed..09aa7a165c 100644 --- a/src/Android/Perspex.Android/Platform/SkiaPlatform/WindowImpl.cs +++ b/src/Android/Perspex.Android/Platform/SkiaPlatform/WindowImpl.cs @@ -94,6 +94,9 @@ namespace Perspex.Android.Platform.SkiaPlatform this.Visibility = ViewStates.Invisible; } + public void SetSystemDecorations(bool enabled) + { + } public void Invalidate(Rect rect) { if (Holder?.Surface?.IsValid == true) base.Invalidate(); diff --git a/src/Gtk/Perspex.Gtk/WindowImpl.cs b/src/Gtk/Perspex.Gtk/WindowImpl.cs index 64b1beb779..afeaaf9ff0 100644 --- a/src/Gtk/Perspex.Gtk/WindowImpl.cs +++ b/src/Gtk/Perspex.Gtk/WindowImpl.cs @@ -170,6 +170,8 @@ namespace Perspex.Gtk return Disposable.Empty; } + public void SetSystemDecorations(bool enabled) => Decorated = enabled; + void ITopLevelImpl.Activate() { Activate(); diff --git a/src/Perspex.Controls/Platform/IWindowImpl.cs b/src/Perspex.Controls/Platform/IWindowImpl.cs index f8bd6588cd..e27d94b41e 100644 --- a/src/Perspex.Controls/Platform/IWindowImpl.cs +++ b/src/Perspex.Controls/Platform/IWindowImpl.cs @@ -33,5 +33,10 @@ namespace Perspex.Platform /// Hides the window. /// void Hide(); + + /// + /// Enables of disables system window decorations (title bar, buttons, etc) + /// + void SetSystemDecorations(bool enabled); } } diff --git a/src/Perspex.Controls/Platform/PlatformManager.cs b/src/Perspex.Controls/Platform/PlatformManager.cs index 1e13b926c0..735b810d91 100644 --- a/src/Perspex.Controls/Platform/PlatformManager.cs +++ b/src/Perspex.Controls/Platform/PlatformManager.cs @@ -178,6 +178,7 @@ namespace Perspex.Controls.Platform public IDisposable ShowDialog() => _window.ShowDialog(); public void Hide() => _popup.Hide(); + public void SetSystemDecorations(bool enabled) => _window.SetSystemDecorations(enabled); } public static IWindowImpl CreateWindow() diff --git a/src/Perspex.Controls/Window.cs b/src/Perspex.Controls/Window.cs index 1e7855e204..7798bde1f4 100644 --- a/src/Perspex.Controls/Window.cs +++ b/src/Perspex.Controls/Window.cs @@ -49,6 +49,12 @@ namespace Perspex.Controls public static readonly PerspexProperty SizeToContentProperty = PerspexProperty.Register(nameof(SizeToContent)); + /// + /// Enables of disables system window decorations (title bar, buttons, etc) + /// + public static readonly PerspexProperty HasSystemDecorationsProperty = + PerspexProperty.Register(nameof(HasSystemDecorations), true); + /// /// Defines the property. /// @@ -66,6 +72,8 @@ namespace Perspex.Controls { BackgroundProperty.OverrideDefaultValue(typeof(Window), Brushes.White); TitleProperty.Changed.AddClassHandler((s, e) => s.PlatformImpl.SetTitle((string)e.NewValue)); + HasSystemDecorationsProperty.Changed.AddClassHandler( + (s, e) => s.PlatformImpl.SetSystemDecorations((bool) e.NewValue)); } /// @@ -114,6 +122,16 @@ namespace Perspex.Controls set { SetValue(TitleProperty, value); } } + /// + /// Enables of disables system window decorations (title bar, buttons, etc) + /// + /// + public bool HasSystemDecorations + { + get { return GetValue(HasSystemDecorationsProperty); } + set { SetValue(HasSystemDecorationsProperty, value); } + } + /// Type IStyleable.StyleKey => typeof(Window); diff --git a/src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs index 5e281b5678..b19d771512 100644 --- a/src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs @@ -571,6 +571,9 @@ namespace Perspex.Win32.Interop [DllImport("user32.dll", SetLastError = true)] public static extern uint GetWindowLong(IntPtr hWnd, int nIndex); + [DllImport("user32.dll", SetLastError = true)] + public static extern uint SetWindowLong(IntPtr hWnd, int nIndex, uint value); + [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect); diff --git a/src/Windows/Perspex.Win32/WindowImpl.cs b/src/Windows/Perspex.Win32/WindowImpl.cs index 3ae9dc26cb..03fcd7cc6d 100644 --- a/src/Windows/Perspex.Win32/WindowImpl.cs +++ b/src/Windows/Perspex.Win32/WindowImpl.cs @@ -37,6 +37,8 @@ namespace Perspex.Win32 private bool _isActive; + private bool _decorated = true; + public WindowImpl() { CreateWindow(); @@ -145,6 +147,47 @@ namespace Perspex.Win32 UnmanagedMethods.ShowWindow(_hwnd, UnmanagedMethods.ShowWindowCommand.Hide); } + public void SetSystemDecorations(bool value) + { + if (value == _decorated) + return; + var style = (UnmanagedMethods.WindowStyles) UnmanagedMethods.GetWindowLong(_hwnd, -16); + style |= UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW; + if (!value) + style ^= UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW; + + UnmanagedMethods.RECT windowRect; + + UnmanagedMethods.GetWindowRect(_hwnd, out windowRect); + Rect newRect; + var oldThickness = BorderThickness; + + UnmanagedMethods.SetWindowLong(_hwnd, -16, (uint) style); + if (value) + { + var thickness = BorderThickness; + 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); + + + _decorated = value; + + + } + public void Invalidate(Rect rect) { var r = new UnmanagedMethods.RECT diff --git a/src/iOS/Perspex.iOS/PerspexView.cs b/src/iOS/Perspex.iOS/PerspexView.cs index 4adfb98790..52fe69d8d1 100644 --- a/src/iOS/Perspex.iOS/PerspexView.cs +++ b/src/iOS/Perspex.iOS/PerspexView.cs @@ -124,6 +124,11 @@ namespace Perspex.iOS //Not supported } + public void SetSystemDecorations(bool enabled) + { + //Not supported + } + public override void TouchesEnded(NSSet touches, UIEvent evt) { var touch = touches.AnyObject as UITouch;