PLEASE DON’T FLAG AS DUPLICATE! As I found the related Stackoverflow questions, but they didn’t work.
I am creating a window with WindowStyle="None"
AllowTransparency="True"
. So I am trying to make a fully custom window. I tried to make the windows features working with it, like layout bar, animated state change.
I found this answer:
public void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (this.WindowState == WindowState.Maximized)
{
this.BorderThickness = new System.Windows.Thickness(8);
}
else
{
this.BorderThickness = new System.Windows.Thickness(0);
}
}
While it is not bad, I would like to solve the root problem if I can. It is because I assume that it will be fixed, and don’t want to change everything back in each of my apps. Also, I don’t know if it’s a Win 11 related problem or other versions have too.
Also I found this answer:
IntPtr myStyle = new IntPtr(WS.WS_CAPTION | WS.WS_CLIPCHILDREN | WS.WS_MINIMIZEBOX | WS.WS_SYSMENU | WS.WS_SIZEBOX | WS.WS_MAXIMIZEBOX); // ADD "| WS.WS_MAXIMIZEBOX " to enable snap bar
SetWindowLongPtr(new HandleRef(null, handle), GWL_STYLE, myStyle);
This is all and good, but when I add the WS.WS_MAXIMIZEBOX
to the myStyle
then if I Mmaximize the window, it will be 8 pixels bigger than the screen (minus the taskbar). Now I assume that I searched a lot and I could not find a working answer. On most places I found this answer to work (not for me):
private void WindowLoaded(object sender, RoutedEventArgs e)
{
handle = new WindowInteropHelper(window).Handle;
HwndSource.FromHwnd(handle).AddHook(new HwndSourceHook(WindowProc));
IntPtr myStyle = new IntPtr(WS.WS_CAPTION | WS.WS_CLIPCHILDREN | WS.WS_MINIMIZEBOX | WS.WS_SYSMENU | WS.WS_SIZEBOX | WS.WS_MAXIMIZEBOX); // ADD "| WS.WS_MAXIMIZEBOX " to enable snap bar
SetWindowLongPtr(new HandleRef(null, handle), GWL_STYLE, myStyle);
}
private static IntPtr WindowProc(
System.IntPtr hwnd,
int msg,
System.IntPtr wParam,
System.IntPtr lParam,
ref bool handled)
{
switch (msg)
{
case 0x0024:/* WM_GETMINMAXINFO */
WmGetMinMaxInfo(hwnd, lParam);
handled = true;
break;
}
return (IntPtr)0;
}
public static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
{
MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
int MONITOR_DEFAULTTONEAREST = 0x00000002;
IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (monitor != IntPtr.Zero)
{
MONITORINFO monitorInfo = new MONITORINFO();
GetMonitorInfo(monitor, monitorInfo);
RECT rcWorkArea = monitorInfo.rcWork;
RECT rcMonitorArea = monitorInfo.rcMonitor;
mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left) // + 1;
mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top) // + 1;
mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left) // - 1;
mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top) // - 1;
}
Marshal.StructureToPtr(mmi, lParam, true);
}
So when I remove the WS.WS_MAXIMIZEBOX
style then it works.
But I need it for the snap bar.
So when I add it, it ONLY works if I either
mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top) - {number here > 0};
mmi.ptMaxSize.x = Math.Abs(rcWorkArea.bottom - rcWorkArea.top) - {number here > 0};
OR
mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top) + {number here > 0};
mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.top - rcMonitorArea.top) + {number here > 0};
It works if I do any of above. But if I can, I would like not to create a pixel gap on any of the sides.
So I am here seeking for help. How can I make it work without the need of a gap.