How to support snap layout in WinForms for windows 11. I'm using c# 10.
My application's custom maximize button shows only tooltip.
MainForm's WndProc code:
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_NCHITTEST:
base.WndProc(ref m);
if (WindowState == FormWindowState.Normal && m.Result == (IntPtr)HitTestValues.HTCLIENT)
m.Result = (IntPtr)(PointToClient(new(m.LParam.ToInt32())) switch
{
var v when v.Y <= resizeAreaSize && v.X <= resizeAreaSize => HitTestValues.HTTOPLEFT,
var v when v.Y <= resizeAreaSize && v.X < Width - resizeAreaSize => HitTestValues.HTTOP,
var v when v.Y <= resizeAreaSize => HitTestValues.HTTOPRIGHT,
var v when v.Y <= Height - resizeAreaSize && v.X <= resizeAreaSize => HitTestValues.HTLEFT,
var v when v.Y <= Height - resizeAreaSize && v.X > Width - resizeAreaSize => HitTestValues.HTRIGHT,
var v when v.Y <= Height - resizeAreaSize => (HitTestValues)m.Result,
var v when v.X <= resizeAreaSize => HitTestValues.HTBOTTOMLEFT,
var v when v.X <= Width - resizeAreaSize => HitTestValues.HTBOTTOM,
_ => HitTestValues.HTBOTTOMRIGHT,
});
return;
case WM_NCCALCSIZE:
return;
case WM_SYSCOMMAND:
(formSize, Size) = (m.WParam.ToInt32() & 0xFFF0) switch
{
SC_MINIMIZE => (ClientSize, Size),
SC_RESTORE => (formSize, formSize),
_ => (formSize, Size),
};
(m.WParam.ToInt32() switch
{
MY_FULLSCREENMENU => fullScreenToolStripMenuItem_Click,
MY_COMPACTOVERLAYMENU => compactToolStripMenuItem_Click,
_ => (Action<object, EventArgs>)((s, e) => {})
})(null, null);
break;
}
base.WndProc(ref m);
Console.WriteLine(m.ToString());
}
Constant int value:
private const int WM_NCCALCSIZE = 0x0083;
private const int WM_SYSCOMMAND = 0x0112;
private const int WM_POPUPSYSTEMMENU = 0x313;
private const int WM_MOUSEMOVE = 0x0200;
private const int WM_NCHITTEST = 0x0084;
private const int WS_SYSMENU = 0x80000;
private const int WS_MINIMIZEBOX = 0x20000;
private const int WS_MAXIMIZEBOX = 0x10000;
private const int SC_MINIMIZE = 0xF020;
private const int SC_RESTORE = 0xF120;
private const int resizeAreaSize = 10;
public const int MY_FULLSCREENMENU = 1020202020;
public const int MY_COMPACTOVERLAYMENU = 1001303000;
public const int MF_BYPOSITION = 0x400;
public const int MF_SEPARATOR = 0x800;
And HitTestValue enum of c# is on this link.
I want to support the snap layout on my maximize button. max button variable's name is maxbtn
.
I didn't find any snap layout for WinForms. It only give me results for UWP (Universal Windows Platform) and WPF (Windows Presentation Foundation).
I've digged a bit into this, and you can check here for some documentation: https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/apply-snap-layout-menu
You have to override WndProc on your custom button allowing it to respond appropriately to WM_NCHITTEST (with a return value of HTMAXBUTTON for the maximize/restore button).
you can try something like this:
protected override void WndProc(ref Message m)
{
if (m.Msg == (int)WinApi.WM_NCHITTEST && buttonType == WindowButtons.Maximize)
{
m.Result = new IntPtr((int)WinApi.HitTest.HTMAXBUTTON);
}
else
{
base.WndProc(ref m);
}
}
with WinApi.WM_NCHITTEST:
public const int WM_NCHITTEST = 0x84;
and WinApi.HitTest:
public enum HitTest
{
HTNOWHERE = 0,
HTCLIENT = 1,
HTCAPTION = 2,
HTGROWBOX = 4,
HTSIZE = HTGROWBOX,
HTMINBUTTON = 8,
HTMAXBUTTON = 9,
HTLEFT = 10,
HTRIGHT = 11,
HTTOP = 12,
HTTOPLEFT = 13,
HTTOPRIGHT = 14,
HTBOTTOM = 15,
HTBOTTOMLEFT = 16,
HTBOTTOMRIGHT = 17,
HTREDUCE = HTMINBUTTON,
HTZOOM = HTMAXBUTTON,
HTSIZEFIRST = HTLEFT,
HTSIZELAST = HTBOTTOMRIGHT,
HTTRANSPARENT = -1
}