调整无边界表单的大小,该表单无处不在,没有空白 [英] Resize a borderless form that has controls everywhere, no empty space

查看:39
本文介绍了调整无边界表单的大小,该表单无处不在,没有空白的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序,该程序的 FormBorderStyle 设置为 None .我一直在网上寻找可以找到用于调整表单大小的有效代码,但是它仅在表单有空白空间且没有控件的情况下才有效.我的整个表单充满了控件,但每个边缘都包含控件,因此我无法在边缘中腾出空间.在 MouseDown 时,是否可以使用Windows API或其他方法来扩展大小调整范围,或者使用控件来触发大小调整事件?

解决方案

可以用不同的方法完成.此答案的主要思想是将面板作为内容容器放在窗体上,然后排除它的右下区域(大小控制矩形),这样该区域就不再成为面板上的对象,并且该矩形的所有鼠标事件都将路由到窗体上,甚至面板也不会绘制该区域.

要实现这一目标,请执行以下步骤:

  1. 创建表格并将边框样式属性设置为无"

  2. 将一个面板添加到表单作为内容所有者,并将其名称设置为panel1并将面板的Dock属性设置为Fill

  3. 覆盖

    这是在容器面板中带有一些控件的表单:

    如果将鼠标移到尺寸夹点上方,您将看到鼠标指针更改为右下角尺寸指针",您可以使用它来调整窗体的大小.

    您可以设置表单的 MinimumSize 广告和 MaximumSize ,以防止难看的表单太小或太大.

    代码:

    以下是完整的代码:

      private int公差= 16;private const int WM_NCHITTEST = 132;私有const int HTBOTTOMRIGHT = 17;私人Rectangle sizeGripRectangle;受保护的覆盖无效WndProc(参考消息m){开关(m.Msg){案例WM_NCHITTEST:base.WndProc(ref m);var hitPoint = this.PointToClient(new Point(m.LParam.ToInt32()& 0xffff,m.LParam.ToInt32()>>> 16));如果(sizeGripRectangle.Contains(hitPoint))m.Result =新的IntPtr(HTBOTTOMRIGHT);休息;默认:base.WndProc(ref m);休息;}}受保护的重写void OnSizeChanged(EventArgs e){base.OnSizeChanged(e);var region = new Region(new Rectangle(0,0,this.ClientRectangle.Width,this.ClientRectangle.Height));sizeGripRectangle =新Rectangle(this.ClientRectangle.Width-公差,this.ClientRectangle.Height-公差,公差,公差);region.Exclude(sizeGripRectangle);this.panel1.Region =地区;this.Invalidate();}受保护的重写void OnPaint(PaintEventArgs e){base.OnPaint(e);ControlPaint.DrawSizeGrip(e.Graphics,Color.Transparent,sizeGripRectangle);} 

    I have a program that has the FormBorderStyle set to 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?

    解决方案

    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

    2. Add a Panel to Form as content holder and set its Name to panel1 and set the Dock property of panel to Fill

    3. Override OnSizeChanged of form and set the region of panel same size as form and then exclude its bottom right corner. This way, the excluded region doesn't belong to panel anymore and all messages including WM_NCHITTEST will be received by our 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.

    5. Override OnPaint to draw size grip

    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.

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

    这篇关于调整无边界表单的大小,该表单无处不在,没有空白的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆