XeZrunner
XeZrunner

Reputation: 245

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

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?

Upvotes: 3

Views: 4496

Answers (1)

Reza Aghaei
Reza Aghaei

Reputation: 125312

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:

enter image description here

and here is the form with some controls in container panel of it:

enter image description here

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

Upvotes: 9

Related Questions