BorderStyle None 和 Dock Fill Child 可调整大小的表单
Resizable Form with BorderStyle None and Child with Dock Fill
我的目标是创建 window(使用 Windows 窗体),它可以像普通 Win10 windows 一样调整大小,但没有标题栏,所以我可以自己绘制它(就像 UWP 应用程序)。
我终于通过修改这段代码找到了一个非常好的工作答案:
我现在拥有的:
public class MyForm : Form
{
//Window Messages
public const uint WM_NCPAINT = 0x85;
public const uint WM_NCCALCSIZE = 0x83;
public const uint WM_NCHITTEST = 0x84;
//RECT Structure
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left, top, right, bottom;
}
//WINDOWPOS Structure
[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPOS
{
public IntPtr hwnd;
public IntPtr hwndinsertafter;
public int x, y, cx, cy;
public int flags;
}
//NCCALCSIZE_PARAMS Structure
[StructLayout(LayoutKind.Sequential)]
public struct NCCALCSIZE_PARAMS
{
public RECT rgrc0, rgrc1, rgrc2;
public WINDOWPOS lppos;
}
//Window Procedure Hook
protected override void WndProc(ref Message m)
{
//Don't style window in designer...
if (DesignMode)
base.WndProc(ref m);
//Handle Message
switch ((uint)m.Msg)
{
case WM_NCCALCSIZE: WmNCCalcSize(ref m); break;
default: base.WndProc(ref m); break;
}
}
//WM_NCCALCSIZE
private void WmNCCalcSize(ref Message m)
{
//Check WPARAM
if (m.WParam != IntPtr.Zero) //TRUE
{
//When TRUE, LPARAM Points to a NCCALCSIZE_PARAMS structure
var nccsp = (NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALCSIZE_PARAMS));
//We're adjusting the size of the client area here. Right now, the client area is the whole form.
//Adding to the Top, Bottom, Left, and Right will size the client area.
nccsp.rgrc0.top += 0; //30-pixel top border
nccsp.rgrc0.bottom -= 8; //4-pixel bottom (resize) border
nccsp.rgrc0.left += 8; //4-pixel left (resize) border
nccsp.rgrc0.right -= 8; //4-pixel right (resize) border
//Set the structure back into memory
Marshal.StructureToPtr(nccsp, m.LParam, true);
}
else //FALSE
{
//When FALSE, LPARAM Points to a RECT structure
var clnRect = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
//Like before, we're adjusting the rectangle...
//Adding to the Top, Bottom, Left, and Right will size the client area.
clnRect.top += 0; //30-pixel top border
clnRect.bottom -= 8; //4-pixel bottom (resize) border
clnRect.left += 8; //4-pixel left (resize) border
clnRect.right -= 8; //4-pixel right (resize) border
//Set the structure back into memory
Marshal.StructureToPtr(clnRect, m.LParam, true);
}
//Return Zero
m.Result = IntPtr.Zero;
}
}
我的目标是创建 window(使用 Windows 窗体),它可以像普通 Win10 windows 一样调整大小,但没有标题栏,所以我可以自己绘制它(就像 UWP 应用程序)。
我终于通过修改这段代码找到了一个非常好的工作答案:
我现在拥有的:
public class MyForm : Form
{
//Window Messages
public const uint WM_NCPAINT = 0x85;
public const uint WM_NCCALCSIZE = 0x83;
public const uint WM_NCHITTEST = 0x84;
//RECT Structure
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left, top, right, bottom;
}
//WINDOWPOS Structure
[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPOS
{
public IntPtr hwnd;
public IntPtr hwndinsertafter;
public int x, y, cx, cy;
public int flags;
}
//NCCALCSIZE_PARAMS Structure
[StructLayout(LayoutKind.Sequential)]
public struct NCCALCSIZE_PARAMS
{
public RECT rgrc0, rgrc1, rgrc2;
public WINDOWPOS lppos;
}
//Window Procedure Hook
protected override void WndProc(ref Message m)
{
//Don't style window in designer...
if (DesignMode)
base.WndProc(ref m);
//Handle Message
switch ((uint)m.Msg)
{
case WM_NCCALCSIZE: WmNCCalcSize(ref m); break;
default: base.WndProc(ref m); break;
}
}
//WM_NCCALCSIZE
private void WmNCCalcSize(ref Message m)
{
//Check WPARAM
if (m.WParam != IntPtr.Zero) //TRUE
{
//When TRUE, LPARAM Points to a NCCALCSIZE_PARAMS structure
var nccsp = (NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALCSIZE_PARAMS));
//We're adjusting the size of the client area here. Right now, the client area is the whole form.
//Adding to the Top, Bottom, Left, and Right will size the client area.
nccsp.rgrc0.top += 0; //30-pixel top border
nccsp.rgrc0.bottom -= 8; //4-pixel bottom (resize) border
nccsp.rgrc0.left += 8; //4-pixel left (resize) border
nccsp.rgrc0.right -= 8; //4-pixel right (resize) border
//Set the structure back into memory
Marshal.StructureToPtr(nccsp, m.LParam, true);
}
else //FALSE
{
//When FALSE, LPARAM Points to a RECT structure
var clnRect = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
//Like before, we're adjusting the rectangle...
//Adding to the Top, Bottom, Left, and Right will size the client area.
clnRect.top += 0; //30-pixel top border
clnRect.bottom -= 8; //4-pixel bottom (resize) border
clnRect.left += 8; //4-pixel left (resize) border
clnRect.right -= 8; //4-pixel right (resize) border
//Set the structure back into memory
Marshal.StructureToPtr(clnRect, m.LParam, true);
}
//Return Zero
m.Result = IntPtr.Zero;
}
}