diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 5db3f69f85..ba348b7d18 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -15,6 +15,7 @@ using Avalonia.Input.Raw; using Avalonia.Platform; using Avalonia.Win32.Input; using Avalonia.Win32.Interop; +using static Avalonia.Win32.Interop.UnmanagedMethods; namespace Avalonia.Win32 { @@ -135,7 +136,7 @@ namespace Avalonia.Win32 { var placement = default(UnmanagedMethods.WINDOWPLACEMENT); UnmanagedMethods.GetWindowPlacement(_hwnd, ref placement); - + switch (placement.ShowCmd) { case UnmanagedMethods.ShowWindowCommand.Maximize: @@ -184,22 +185,32 @@ namespace Avalonia.Win32 public void SetSystemDecorations(bool value) { if (value == _decorated) + { return; - var style = (UnmanagedMethods.WindowStyles) UnmanagedMethods.GetWindowLong(_hwnd, -16); + } + + 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); + UnmanagedMethods.SetWindowLong(_hwnd, -16, (uint)style); + if (value) { var thickness = BorderThickness; + newRect = new Rect( windowRect.left - thickness.Left, windowRect.top - thickness.Top, @@ -207,19 +218,20 @@ namespace Avalonia.Win32 (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, + 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) @@ -268,7 +280,7 @@ namespace Avalonia.Win32 public void BeginMoveDrag() { - UnmanagedMethods.DefWindowProc(_hwnd, (int) UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN, + UnmanagedMethods.DefWindowProc(_hwnd, (int)UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN, new IntPtr((int)UnmanagedMethods.HitTestValues.HTCAPTION), IntPtr.Zero); } @@ -286,8 +298,8 @@ namespace Avalonia.Win32 public void BeginResizeDrag(WindowEdge edge) { - UnmanagedMethods.DefWindowProc(_hwnd, (int) UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN, - new IntPtr((int) EdgeDic[edge]), IntPtr.Zero); + UnmanagedMethods.DefWindowProc(_hwnd, (int)UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN, + new IntPtr((int)EdgeDic[edge]), IntPtr.Zero); } public Point Position @@ -303,8 +315,8 @@ namespace Avalonia.Win32 UnmanagedMethods.SetWindowPos( Handle.Handle, IntPtr.Zero, - (int) value.X, - (int) value.Y, + (int)value.X, + (int)value.Y, 0, 0, UnmanagedMethods.SetWindowPosFlags.SWP_NOSIZE | UnmanagedMethods.SetWindowPosFlags.SWP_NOACTIVATE); @@ -454,7 +466,7 @@ namespace Avalonia.Win32 : RawMouseEventType.MiddleButtonDown, DipFromLParam(lParam), GetMouseModifiers(wParam)); break; - + case UnmanagedMethods.WindowsMessage.WM_LBUTTONUP: case UnmanagedMethods.WindowsMessage.WM_RBUTTONUP: case UnmanagedMethods.WindowsMessage.WM_MBUTTONUP: @@ -462,9 +474,9 @@ namespace Avalonia.Win32 WindowsMouseDevice.Instance, timestamp, _owner, - msg == (int) UnmanagedMethods.WindowsMessage.WM_LBUTTONUP + msg == (int)UnmanagedMethods.WindowsMessage.WM_LBUTTONUP ? RawMouseEventType.LeftButtonUp - : msg == (int) UnmanagedMethods.WindowsMessage.WM_RBUTTONUP + : msg == (int)UnmanagedMethods.WindowsMessage.WM_RBUTTONUP ? RawMouseEventType.RightButtonUp : RawMouseEventType.MiddleButtonUp, DipFromLParam(lParam), GetMouseModifiers(wParam)); @@ -508,7 +520,7 @@ namespace Avalonia.Win32 timestamp, _owner, ScreenToClient(DipFromLParam(lParam)), - new Vector(-(ToInt32(wParam) >> 16) / wheelDelta,0), GetMouseModifiers(wParam)); + new Vector(-(ToInt32(wParam) >> 16) / wheelDelta, 0), GetMouseModifiers(wParam)); break; case UnmanagedMethods.WindowsMessage.WM_MOUSELEAVE: @@ -585,9 +597,9 @@ namespace Avalonia.Win32 var modifiers = WindowsKeyboardDevice.Instance.Modifiers; if (keys.HasFlag(UnmanagedMethods.ModifierKeys.MK_LBUTTON)) modifiers |= InputModifiers.LeftMouseButton; - if(keys.HasFlag(UnmanagedMethods.ModifierKeys.MK_RBUTTON)) - modifiers |= InputModifiers.RightMouseButton; - if(keys.HasFlag(UnmanagedMethods.ModifierKeys.MK_MBUTTON)) + if (keys.HasFlag(UnmanagedMethods.ModifierKeys.MK_RBUTTON)) + modifiers |= InputModifiers.RightMouseButton; + if (keys.HasFlag(UnmanagedMethods.ModifierKeys.MK_MBUTTON)) modifiers |= InputModifiers.MiddleMouseButton; return modifiers; } @@ -666,6 +678,8 @@ namespace Avalonia.Win32 { UnmanagedMethods.ShowWindowCommand command; + bool doShow = true; + switch (state) { case WindowState.Minimized: @@ -673,7 +687,31 @@ namespace Avalonia.Win32 break; case WindowState.Maximized: command = UnmanagedMethods.ShowWindowCommand.Maximize; + + if (!_decorated) + { + IntPtr monitor = MonitorFromWindow(_hwnd, MONITOR.MONITOR_DEFAULTTONEAREST); + + if (monitor != IntPtr.Zero) + { + MONITORINFO monitorInfo = new MONITORINFO(); + + if (UnmanagedMethods.GetMonitorInfo(monitor, monitorInfo)) + { + RECT rcMonitorArea = monitorInfo.rcMonitor; + + var x = monitorInfo.rcWork.left; + var y = monitorInfo.rcWork.top; + var cx = Math.Abs(monitorInfo.rcWork.right - x); + var cy = Math.Abs(monitorInfo.rcWork.bottom - y); + + doShow = false; + UnmanagedMethods.SetWindowPos(_hwnd, new IntPtr(-2), x, y, cx, cy, SetWindowPosFlags.SWP_SHOWWINDOW); + } + } + } break; + case WindowState.Normal: command = UnmanagedMethods.ShowWindowCommand.Restore; break; @@ -681,7 +719,11 @@ namespace Avalonia.Win32 throw new ArgumentException("Invalid WindowState."); } - UnmanagedMethods.ShowWindow(_hwnd, command); + if (doShow) + { + UnmanagedMethods.ShowWindow(_hwnd, command); + } + UnmanagedMethods.SetFocus(_hwnd); }