我有一个FormBorderStyle
设置为None
的程序。我一直在网上寻找并找到一个用于调整表单大小的工作代码,但只有在表单空白且没有控件的情况下它才有效。我的整个表单充满了控件,每个边都有控件,我无法在边缘创造空间。有没有办法使用Windows API或其他东西来扩展调整大小的手柄,或者在MouseDown
时使用控件来触发调整大小事件?
答案 0 :(得分:5)
可以用不同的方式完成。这个答案的主要思想是将一个面板放在窗体上作为内容容器,然后排除它的右下区域(大小夹点矩形),这样该区域就不再是面板了,那个矩形的所有鼠标事件都将被路由到窗体,甚至小组也没有画出那个区域。
要实现这一目标,请执行以下步骤:
Crate Form并将BorderStyle属性设置为None
将Panel添加到Form作为内容持有者,并将其Name设置为panel1并将Panel的Dock属性设置为Fill
覆盖表单的OnSizeChanged
并将面板区域设置为与表单相同的大小,然后排除其右下角。这样,被排除的区域就不再属于专家组,所有包含WM_NCHITTEST
的消息都将由我们WndProc
收到;小组甚至没有画出那个区域。
覆盖WndProc
以获取WM_NCHITTEST
消息,如果该点位于我们在OnSizeChanges
中定义的区域,则显示调整大小指针并准备调整大小。
覆盖OnPaint
以绘制尺寸抓地
<强>截图:强>
以下是在容器面板中包含一些控件的表单:
如果将鼠标移到尺寸夹点上,您将看到鼠标指针变为“正确尺寸指针”,您可以使用它调整表单大小。
您可以设置表单的MinimumSize
ad MaximumSize
,以防止丑陋的太小或太大的形式。
<强>代码:强>
这是完整的代码:
private int tolerance = 16;
private const int WM_NCHITTEST = 132;
private const int HTBOTTOMRIGHT = 17;
private Rectangle sizeGripRectangle;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_NCHITTEST:
base.WndProc(ref m);
var hitPoint = this.PointToClient(new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16));
if (sizeGripRectangle.Contains(hitPoint))
m.Result = new IntPtr(HTBOTTOMRIGHT);
break;
default:
base.WndProc(ref m);
break;
}
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
var region = new Region(new Rectangle(0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height));
sizeGripRectangle = new Rectangle(this.ClientRectangle.Width - tolerance, this.ClientRectangle.Height - tolerance, tolerance, tolerance);
region.Exclude(sizeGripRectangle);
this.panel1.Region = region;
this.Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
ControlPaint.DrawSizeGrip(e.Graphics, Color.Transparent, sizeGripRectangle);
}