in src/Windows/Avalonia.Win32/WindowImpl.cs [1403:1551]
private void UpdateWindowProperties(WindowProperties newProperties, bool forceChanges = false)
{
var oldProperties = _windowProperties;
// Calling SetWindowPos will cause events to be sent and we need to respond
// according to the new values already.
_windowProperties = newProperties;
if (oldProperties.IsFullScreen == newProperties.IsFullScreen)
{
var exStyle = WindowStyles.WS_EX_WINDOWEDGE | (UseRedirectionBitmap ? 0 : WindowStyles.WS_EX_NOREDIRECTIONBITMAP);
if ((oldProperties.ShowInTaskbar != newProperties.ShowInTaskbar) || forceChanges)
{
if (newProperties.ShowInTaskbar)
{
exStyle |= WindowStyles.WS_EX_APPWINDOW;
if (_hiddenWindowIsParent)
{
// Can't enable the taskbar icon by clearing the parent window unless the window
// is hidden. Hide the window and show it again with the same activation state
// when we've finished. Interestingly it seems to work fine the other way.
var shown = IsWindowVisible(_hwnd);
var activated = GetActiveWindow() == _hwnd;
if (shown)
Hide();
_hiddenWindowIsParent = false;
SetParent(null);
if (shown)
Show(activated, false);
}
}
else
{
// To hide a non-owned window's taskbar icon we need to parent it to a hidden window.
if (_parent is null)
{
SetWindowLongPtr(_hwnd, (int)WindowLongParam.GWL_HWNDPARENT, OffscreenParentWindow.Handle);
_hiddenWindowIsParent = true;
}
exStyle &= ~WindowStyles.WS_EX_APPWINDOW;
}
}
if (newProperties.ShowInTaskbar)
{
exStyle |= WindowStyles.WS_EX_APPWINDOW;
}
else
{
exStyle &= ~WindowStyles.WS_EX_APPWINDOW;
}
WindowStyles style = WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_OVERLAPPEDWINDOW | WindowStyles.WS_CLIPSIBLINGS;
if (this is EmbeddedWindowImpl)
style |= WindowStyles.WS_CHILD;
if (IsWindowVisible(_hwnd))
style |= WindowStyles.WS_VISIBLE;
if (newProperties.IsResizable || newProperties.WindowState == WindowState.Maximized)
style |= WindowStyles.WS_THICKFRAME;
else
style &= ~WindowStyles.WS_THICKFRAME;
if (newProperties.IsMinimizable)
style |= WindowStyles.WS_MINIMIZEBOX;
else
style &= ~WindowStyles.WS_MINIMIZEBOX;
if (newProperties.IsMaximizable || (newProperties.WindowState == WindowState.Maximized && newProperties.IsResizable))
style |= WindowStyles.WS_MAXIMIZEBOX;
else
style &= ~WindowStyles.WS_MAXIMIZEBOX;
const WindowStyles fullDecorationFlags = WindowStyles.WS_CAPTION | WindowStyles.WS_BORDER;
if (newProperties.Decorations == SystemDecorations.Full)
{
style |= fullDecorationFlags;
}
else
{
style &= ~(fullDecorationFlags | WindowStyles.WS_THICKFRAME);
if (newProperties.Decorations == SystemDecorations.BorderOnly && newProperties.WindowState != WindowState.Maximized && newProperties.IsResizable)
{
style |= WindowStyles.WS_THICKFRAME | WindowStyles.WS_BORDER;
}
else if(newProperties.WindowState == WindowState.Maximized && _isClientAreaExtended)
{
style |= WindowStyles.WS_THICKFRAME;
}
}
var windowStates = GetWindowStateStyles();
style &= ~WindowStateMask;
style |= windowStates;
_savedWindowInfo.Style = style;
_savedWindowInfo.ExStyle = exStyle;
if (WindowStylesCallback is { } callback)
{
var (s, e) = callback((uint)style, (uint)exStyle);
style = (WindowStyles)s;
exStyle = (WindowStyles)e;
}
SetStyle(style);
SetExtendedStyle(exStyle);
}
else
SetFullScreen(newProperties.IsFullScreen);
if (!_isFullScreenActive && ((oldProperties.Decorations != newProperties.Decorations) || forceChanges))
{
var margin = newProperties.Decorations == SystemDecorations.BorderOnly ? 1 : 0;
var margins = new MARGINS
{
cyBottomHeight = margin,
cxRightWidth = margin,
cxLeftWidth = margin,
cyTopHeight = margin
};
DwmExtendFrameIntoClientArea(_hwnd, ref margins);
if (_shown || forceChanges)
{
SetWindowPos(_hwnd, IntPtr.Zero, 0, 0, 0 ,0,
SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE |
SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOMOVE |
SetWindowPosFlags.SWP_FRAMECHANGED);
}
}
// Ensure window state if decorations change
if (_shown && oldProperties.Decorations != newProperties.Decorations)
ShowWindow(WindowState, false);
}