Browse Source

WindowImpl on Win32 when no system decorations will not cover taskbar.

pull/806/head
Dan Walmsley 10 years ago
parent
commit
49f2d7b477
  1. 90
      src/Windows/Avalonia.Win32/WindowImpl.cs

90
src/Windows/Avalonia.Win32/WindowImpl.cs

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

Loading…
Cancel
Save