Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

76 bug maximize window to cover taskbar height when window width is limited #82

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/MicaWPF.Core/Controls/MicaWindow/MicaWindowInteropHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution.
// </copyright>

using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
Expand Down Expand Up @@ -42,6 +43,22 @@ protected override void OnInitialized(EventArgs e)
base.OnInitialized(e);
}

protected Size GetHostingScreenSize()
{
var windowHwnd = new WindowInteropHelper(this).EnsureHandle();

var mi = default(InteropValues.MONITORINFO);
mi.cbSize = (uint)Marshal.SizeOf(mi);

var monitor = InteropMethods.MonitorFromWindow(windowHwnd, 2);
InteropMethods.GetMonitorInfo(monitor, ref mi);

var width = mi.rcWork.right - mi.rcWork.left;
var height = mi.rcWork.bottom - mi.rcWork.top;

return new Size(width, height);
}

private nint ShowSnapLayout(nint lparam, ref bool handled)
{
var x = (short)(lparam.ToInt32() & 0xffff);
Expand Down Expand Up @@ -119,6 +136,24 @@ private nint HwndSourceHook(nint hwnd, int msg, nint n, nint lparam, ref bool ha
break;
case InteropValues.HwndSourceMessages.WM_NCLBUTTONDOWN:
HideMaximiseAndMinimiseButton(lparam, ref handled);
break;
case InteropValues.HwndSourceMessages.WM_GETMINMAXINFO:
var mmiNullable = (InteropValues.MINMAXINFO?)Marshal.PtrToStructure(lparam, typeof(InteropValues.MINMAXINFO));
if (mmiNullable.HasValue)
{
var mmi = mmiNullable.Value;
var screen = GetHostingScreenSize();
if (MaxWidth < screen.Width)
{
mmi.ptMaxPosition.X = (int)((screen.Width - MaxWidth) / 2);
mmi.ptMaxSize.X = (int)MaxWidth;
mmi.ptMaxSize.Y = (int)screen.Height + 8;

Marshal.StructureToPtr(mmi, lparam, true);
handled = true;
}
}

break;
case InteropValues.HwndSourceMessages.WM_WINDOWPOSCHANGING:
var button = WindowState == WindowState.Maximized ? ButtonRestore : ButtonMax;
Expand Down
4 changes: 2 additions & 2 deletions src/MicaWPF.Core/Interop/InteropMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public static DWMCOLORIZATIONPARAMS GetDwmGetColorizationParameters()
/// <param name="handle">A handle to the window of interest.</param>
/// <param name="flags">Determines the function's return value if the window does not intersect any display monitor.</param>
/// <returns>If the window intersects one or more display monitor rectangles, the return value is an HMONITOR handle to the display monitor that has the largest area of intersection with the window.</returns>
[LibraryImport(ExternDll.User32)]
[LibraryImport(ExternDll.User32, SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static partial nint MonitorFromWindow(nint handle, uint flags);

Expand All @@ -143,7 +143,7 @@ public static DWMCOLORIZATIONPARAMS GetDwmGetColorizationParameters()
/// <param name="hMonitor">A handle to the display monitor of interest.</param>
/// <param name="lpmi">A pointer to a MONITORINFO or MONITORINFOEX structure that receives information about the specified display monitor.</param>
/// <returns>If the function succeeds, the return value is true. If the function fails, the return value is false.</returns>
[LibraryImport(ExternDll.User32)]
[LibraryImport(ExternDll.User32, EntryPoint = "GetMonitorInfoW")]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool GetMonitorInfo(nint hMonitor, ref MONITORINFO lpmi);
Expand Down
219 changes: 205 additions & 14 deletions src/MicaWPF.Core/Interop/InteropValues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,206 @@ public enum DWM_WINDOW_CORNER_PREFERENCE
DWMWCP_ROUNDSMALL = 3,
}

public enum DeviceCap
{
/// <summary>
/// Device driver version.
/// </summary>
DRIVERVERSION = 0,

/// <summary>
/// Device classification.
/// </summary>
TECHNOLOGY = 2,

/// <summary>
/// Horizontal size in millimeters.
/// </summary>
HORZSIZE = 4,

/// <summary>
/// Vertical size in millimeters.
/// </summary>
VERTSIZE = 6,

/// <summary>
/// Horizontal width in pixels.
/// </summary>
HORZRES = 8,

/// <summary>
/// Vertical height in pixels.
/// </summary>
VERTRES = 10,

/// <summary>
/// Number of bits per pixel.
/// </summary>
BITSPIXEL = 12,

/// <summary>
/// Number of planes.
/// </summary>
PLANES = 14,

/// <summary>
/// Number of brushes the device has.
/// </summary>
NUMBRUSHES = 16,

/// <summary>
/// Number of pens the device has.
/// </summary>
NUMPENS = 18,

/// <summary>
/// Number of markers the device has.
/// </summary>
NUMMARKERS = 20,

/// <summary>
/// Number of fonts the device has.
/// </summary>
NUMFONTS = 22,

/// <summary>
/// Number of colors the device supports.
/// </summary>
NUMCOLORS = 24,

/// <summary>
/// Size required for device descriptor.
/// </summary>
PDEVICESIZE = 26,

/// <summary>
/// Curve capabilities.
/// </summary>
CURVECAPS = 28,

/// <summary>
/// Line capabilities.
/// </summary>
LINECAPS = 30,

/// <summary>
/// Polygonal capabilities.
/// </summary>
POLYGONALCAPS = 32,

/// <summary>
/// Text capabilities.
/// </summary>
TEXTCAPS = 34,

/// <summary>
/// Clipping capabilities.
/// </summary>
CLIPCAPS = 36,

/// <summary>
/// Bitblt capabilities.
/// </summary>
RASTERCAPS = 38,

/// <summary>
/// Length of the X leg.
/// </summary>
ASPECTX = 40,

/// <summary>
/// Length of the Y leg.
/// </summary>
ASPECTY = 42,

/// <summary>
/// Length of the hypotenuse.
/// </summary>
ASPECTXY = 44,

/// <summary>
/// Shading and Blending caps.
/// </summary>
SHADEBLENDCAPS = 45,

/// <summary>
/// Logical pixels inch in X.
/// </summary>
LOGPIXELSX = 88,

/// <summary>
/// Logical pixels inch in Y.
/// </summary>
LOGPIXELSY = 90,

/// <summary>
/// Number of entries in physical palette.
/// </summary>
SIZEPALETTE = 104,

/// <summary>
/// Number of reserved entries in palette.
/// </summary>
NUMRESERVED = 106,

/// <summary>
/// Actual color resolution.
/// </summary>
COLORRES = 108,

// Printing related DeviceCaps. These replace the appropriate Escapes

/// <summary>
/// Physical Width in device units.
/// </summary>
PHYSICALWIDTH = 110,

/// <summary>
/// Physical Height in device units.
/// </summary>
PHYSICALHEIGHT = 111,

/// <summary>
/// Physical Printable Area x margin.
/// </summary>
PHYSICALOFFSETX = 112,

/// <summary>
/// Physical Printable Area y margin.
/// </summary>
PHYSICALOFFSETY = 113,

/// <summary>
/// Scaling factor x.
/// </summary>
SCALINGFACTORX = 114,

/// <summary>
/// Scaling factor y.
/// </summary>
SCALINGFACTORY = 115,

/// <summary>
/// Current vertical refresh rate of the display device (for displays only) in Hz.
/// </summary>
VREFRESH = 116,

/// <summary>
/// Vertical height of entire desktop in pixels.
/// </summary>
DESKTOPVERTRES = 117,

/// <summary>
/// Horizontal width of entire desktop in pixels.
/// </summary>
DESKTOPHORZRES = 118,

/// <summary>
/// Preferred blt alignment.
/// </summary>
BLTALIGNMENT = 119,
}

[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
Expand All @@ -56,28 +256,19 @@ public struct DWMCOLORIZATIONPARAMS
public bool fOpaque;
}

[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;

public RECT(int left, int top, int right, int bottom)
{
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}
public int left;
public int top;
public int right;
public int bottom;
}

[StructLayout(LayoutKind.Sequential)]
public struct MONITORINFO
{
public int cbSize;
public uint cbSize;
public RECT rcMonitor;
public RECT rcWork;
public uint dwFlags;
Expand Down