简体   繁体   English

调整无边框表单的大小,控件无处不在,没有空白区域

[英]Resize a borderless form that has controls everywhere, no empty space

I have a program that has the FormBorderStyle set to None . 我有一个将FormBorderStyle设置为None I've been looking online and found a working code for resizing the form, but it only works when the form has empty space where there are no controls. 我一直在网上寻找并找到一个用于调整表单大小的工作代码,但只有在表单空白且没有控件的情况下它才有效。 My entire form is full of controls though, each edge has controls in it, and there is no way I could make space in the edges. 我的整个表单充满了控件,每个边都有控件,我无法在边缘创造空间。 Is there a way to use the Windows APIs or something to extend the resize grip or perhaps use a control to trigger the resize event when MouseDown ? 有没有办法使用Windows API或其他东西来扩展调整大小的手柄或者可能使用控件来触发MouseDown时的resize事件?

It can be done in different ways. 它可以以不同的方式完成。 The main idea in this answer is putting a panel on form as content container, then exclude bottom right region of it (size grip rectangle) so this region is not belogns to panel anymore and all mouse events of that rectangle will be routed to form, and even panel doesn't draw that region. 这个答案的主要思想是将一个面板放在窗体上作为内容容器,然后排除它的右下角区域(大小夹点矩形),这样该区域就不再是面板了,那个矩形的所有鼠标事件都将被路由到窗体,甚至小组也没有画出那个区域。

To achieve that, do the following steps: 为此,请执行以下步骤:

  1. Crate Form and set BorderStyle property to None Crate Form并将BorderStyle属性设置为None

  2. Add a Panel to Form as content holder and set its Name to panel1 and set the Dock property of panel to Fill 将Panel添加到Form作为内容持有者,并将其Name设置为panel1,并将Panel的Dock属性设置为Fill

  3. Override OnSizeChanged of form and set the region of panel same size as form and then exclude its bottom right corner. 覆盖OnSizeChanged并将面板区域设置为与窗体相同的大小,然后排除其右下角。 This way, the excluded region doesn't belong to panel anymore and all messages including WM_NCHITTEST will be received by our WndProc ; 这样,排除的区域不再属于面板,包括WM_NCHITTEST所有消息都将由我们的WndProc接收; the panel even doesn't draw that region. 小组甚至没有绘制该区域。

  4. Override WndProc to get WM_NCHITTEST message and if the point is in the region that we defined in OnSizeChanges , the show resize pointer and prepare to resize. 覆盖WndProc以获取WM_NCHITTEST消息,如果该点位于我们在OnSizeChanges定义的区域,则show resize指针并准备调整大小。

  5. Override OnPaint to draw size grip 覆盖OnPaint以绘制尺寸夹点

Screenshot: 截图:

在此输入图像描述

and here is the form with some controls in container panel of it: 这是在容器面板中有一些控件的表单:

在此输入图像描述

If you move your mouse over size grip, you will see your mouse pointer changes to Bottom Right Size Pointer and you can resize your form using it. 如果将鼠标移动到尺寸夹点上,您将看到鼠标指针变为“右下角尺寸指针”,您可以使用它调整窗体大小。

You can set MinimumSize ad MaximumSize of the form to prevent ugly too small or too large form. 您可以设置MinimumSize ad MaximumSize ,以防止丑陋的太小或太大的表单。

Code: 码:

Here is complete code: 这是完整的代码:

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM