Does anyone know how I can resize a winform when it has no border. I don't want the default border that Windows has, so I changed the property "FormBorderStyle" to "None". This removed the border, although now it can't be resized. I've figured out how to move the form around, I just need to know how to resize it.
7 Answers
Some sample code that allows moving and resizing the form, intentionally not making it pretty. Adjust to your liking:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.ResizeRedraw, true);
}
private const int cGrip = 16; // Grip size
private const int cCaption = 32; // Caption bar height;
protected override void OnPaint(PaintEventArgs e) {
// Paint the grip in lower right corner
Rectangle rc = new Rectangle(this.ClientSize.Width - cGrip, this.ClientSize.Height - cGrip, cGrip, cGrip);
ControlPaint.DrawSizeGrip(e.Graphics, this.BackColor, rc);
// Paint the simulated caption bar
rc = new Rectangle(0, 0, this.ClientSize.Width, cCaption);
e.Graphics.FillRectangle(Brushes.DarkBlue, rc);
}
protected override void WndProc(ref Message m) {
if (m.Msg == 0x84) { // Trap WM_NCHITTEST
Point pos = new Point(m.LParam.ToInt32());
pos = this.PointToClient(pos);
if (pos.Y < cCaption) {
m.Result = (IntPtr)2; // HTCAPTION
return;
}
if (pos.X >= this.ClientSize.Width - cGrip && pos.Y >= this.ClientSize.Height - cGrip) {
m.Result = (IntPtr)17; // HTBOTTOMRIGHT
return;
}
}
base.WndProc(ref m);
}
}
-
-
1If you don't want the bar on top just don't override OnPaint(). The rest of the code is solid. Thanks a bunch mate :)– kurtCommented Apr 21, 2016 at 22:32
-
2To remove the top border and ONLY have the sizer grip, simply remove the last two lines of the OnPaint method:
rc = new Rectangle(0, 0, this.ClientSize.Width, cCaption); e.Graphics.FillRectangle(Brushes.DarkBlue, rc);
Commented Jun 25, 2020 at 17:49 -
2Nevermind. I had panel in my form with
dock: fill
so it was completely covering client area and mouse was always hovering over control and was never at client area thusWM_NCHITTEST
was never firing... simply undocking worked. Commented Jul 1, 2021 at 16:25 -
1This works but there is a lot of "shaking" of the controls inside the form when pulling left or top. The same happens to the opposite edge of the form itself. It seems the call to WM_NCHITTEST comes after the form has moved (or something) and the code kind of sets it back in place. Not a big deal but nasty looking thing. The DoubleBuffered and ResizeRedraw flags do not fix it.– user1908746Commented Sep 8, 2022 at 7:17
Here's a complete example of a customized form with all 8 points of resizing:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None; // no borders
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.ResizeRedraw, true); // this is to avoid visual artifacts
}
protected override void OnPaint(PaintEventArgs e) // you can safely omit this method if you want
{
e.Graphics.FillRectangle(Brushes.Green, Top);
e.Graphics.FillRectangle(Brushes.Green, Left);
e.Graphics.FillRectangle(Brushes.Green, Right);
e.Graphics.FillRectangle(Brushes.Green, Bottom);
}
private const int
HTLEFT = 10,
HTRIGHT = 11,
HTTOP = 12,
HTTOPLEFT = 13,
HTTOPRIGHT = 14,
HTBOTTOM = 15,
HTBOTTOMLEFT = 16,
HTBOTTOMRIGHT = 17;
const int _ = 10; // you can rename this variable if you like
Rectangle Top { get { return new Rectangle(0, 0, this.ClientSize.Width, _); } }
Rectangle Left { get { return new Rectangle(0, 0, _, this.ClientSize.Height); } }
Rectangle Bottom { get { return new Rectangle(0, this.ClientSize.Height - _, this.ClientSize.Width, _); } }
Rectangle Right { get { return new Rectangle(this.ClientSize.Width - _, 0, _, this.ClientSize.Height); } }
Rectangle TopLeft { get { return new Rectangle(0, 0, _, _); } }
Rectangle TopRight { get { return new Rectangle(this.ClientSize.Width - _, 0, _, _); } }
Rectangle BottomLeft { get { return new Rectangle(0, this.ClientSize.Height - _, _, _); } }
Rectangle BottomRight { get { return new Rectangle(this.ClientSize.Width - _, this.ClientSize.Height - _, _, _); } }
protected override void WndProc(ref Message message)
{
base.WndProc(ref message);
if (message.Msg == 0x84) // WM_NCHITTEST
{
var cursor = this.PointToClient(Cursor.Position);
if (TopLeft.Contains(cursor)) message.Result = (IntPtr)HTTOPLEFT;
else if (TopRight.Contains(cursor)) message.Result = (IntPtr)HTTOPRIGHT;
else if (BottomLeft.Contains(cursor)) message.Result = (IntPtr)HTBOTTOMLEFT;
else if (BottomRight.Contains(cursor)) message.Result = (IntPtr)HTBOTTOMRIGHT;
else if (Top.Contains(cursor)) message.Result = (IntPtr)HTTOP;
else if (Left.Contains(cursor)) message.Result = (IntPtr)HTLEFT;
else if (Right.Contains(cursor)) message.Result = (IntPtr)HTRIGHT;
else if (Bottom.Contains(cursor)) message.Result = (IntPtr)HTBOTTOM;
}
}}
-
2a little error. edges and corners are overlapping so for example top one that is returning
new Rectangle(0, 0, this.ClientSize.Width, _);
must returnnew Rectangle(_, 0, this.ClientSize.Width - _, _);
in order to leave small square for corner square... other edges will also have offsets accordingly Commented Jul 1, 2021 at 16:57 -
1The "error" doesn't make a difference since the corners are checked before the edges– PenguinCommented Jan 25, 2022 at 2:26
"Sizer" is the light blue panel in the right bottom corner
int Mx;
int My;
int Sw;
int Sh;
bool mov;
void SizerMouseDown(object sender, MouseEventArgs e)
{
mov = true;
My = MousePosition.Y;
Mx = MousePosition.X;
Sw = Width;
Sh = Height;
}
void SizerMouseMove(object sender, MouseEventArgs e)
{
if (mov == true) {
Width = MousePosition.X - Mx + Sw;
Height = MousePosition.Y - My + Sh;
}
}
void SizerMouseUp(object sender, MouseEventArgs e)
{
mov = false;
}
-
1A nice solution! However instead of a blue panel I used a small picture box showing an image of the resize dot pattern, with the Cursor property set to "SizeAll" so that the cursor changes to resize arrows when you are over the box.– JonPCommented Jan 15, 2020 at 10:55
(elaborate : in comment 2)
Resize "Form" From All place And Move it >>> Full Code <<<<<
//First u most to add this Class
class ReSize
{
private bool Above, Right, Under, Left, Right_above, Right_under, Left_under, Left_above;
int Thickness=6; //Thickness of border u can cheang it
int Area = 8; //Thickness of Angle border
/// <summary>
/// Constructor
/// </summary>
/// <param name="thickness">set thickness of form border</param>
public ReSize(int thickness)
{
Thickness = thickness;
}
/// <summary>
/// Constructor set thickness of form border=1
/// </summary>
public ReSize()
{
Thickness = 10;
}
//Get Mouse Position
public string getMosuePosition(Point mouse, Form form)
{
bool above_underArea = mouse.X > Area && mouse.X < form.ClientRectangle.Width - Area; /* |\AngleArea(Left_Above)\(=======above_underArea========)/AngleArea(Right_Above)/| */ //Area===>(==)
bool right_left_Area = mouse.Y > Area && mouse.Y < form.ClientRectangle.Height - Area;
bool _Above=mouse.Y <= Thickness; //Mouse in Above All Area
bool _Right= mouse.X >= form.ClientRectangle.Width - Thickness;
bool _Under=mouse.Y >= form.ClientRectangle.Height - Thickness;
bool _Left=mouse.X <= Thickness;
Above = _Above && (above_underArea); if (Above) return "a"; /*Mouse in Above All Area WithOut Angle Area */
Right = _Right && (right_left_Area); if (Right) return "r";
Under = _Under && (above_underArea); if (Under) return "u";
Left = _Left && (right_left_Area); if (Left) return "l";
Right_above =/*Right*/ (_Right && (!right_left_Area)) && /*Above*/ (_Above && (!above_underArea)); if (Right_above) return "ra"; /*if Mouse Right_above */
Right_under =/* Right*/((_Right) && (!right_left_Area)) && /*Under*/(_Under && (!above_underArea)); if (Right_under) return "ru"; //if Mouse Right_under
Left_under = /*Left*/((_Left) && (!right_left_Area)) && /*Under*/ (_Under && (!above_underArea)); if (Left_under) return "lu"; //if Mouse Left_under
Left_above = /*Left*/((_Left) && (!right_left_Area)) && /*Above*/(_Above && (!above_underArea)); if (Left_above) return "la"; //if Mouse Left_above
return "";
}
}
Then Form cs
public partial class FormGDI : Form
{
ReSize resize = new ReSize(); // ReSize Class "/\" To Help Resize Form <None Style>
public FormGDI()
{
InitializeComponent();
this.SetStyle(ControlStyles.ResizeRedraw, true);
}
private const int cGrip = 16; // Grip size
private const int cCaption = 32; // Caption bar height;
protected override void OnPaint(PaintEventArgs e)
{
//this if you want to draw (if)
Color theColor = Color.FromArgb(10, 20, 20, 20);
theColor = Color.DarkBlue;
int BORDER_SIZE = 4;
ControlPaint.DrawBorder(e.Graphics, ClientRectangle,
theColor, BORDER_SIZE, ButtonBorderStyle.Dashed,
theColor, BORDER_SIZE, ButtonBorderStyle.Dashed,
theColor, BORDER_SIZE, ButtonBorderStyle.Dashed,
theColor, BORDER_SIZE, ButtonBorderStyle.Dashed);
Rectangle rc = new Rectangle(this.ClientSize.Width - cGrip, this.ClientSize.Height - cGrip, cGrip, cGrip);
ControlPaint.DrawSizeGrip(e.Graphics, this.BackColor, rc);
rc = new Rectangle(0, 0, this.ClientSize.Width, cCaption);
e.Graphics.FillRectangle(Brushes.DarkBlue, rc);
base.OnPaint(e);
}
//set MinimumSize to Form
public override Size MinimumSize
{
get
{
return base.MinimumSize;
}
set
{
base.MinimumSize = new Size(179, 51);
}
}
//
//override WndProc
//
protected override void WndProc(ref Message m)
{
//****************************************************************************
int x = (int)(m.LParam.ToInt64() & 0xFFFF); //get x mouse position
int y = (int)((m.LParam.ToInt64() & 0xFFFF0000) >> 16); //get y mouse position you can gave (x,y) it from "MouseEventArgs" too
Point pt = PointToClient(new Point(x, y));
if (m.Msg == 0x84)
{
switch (resize.getMosuePosition(pt, this))
{
case "l": m.Result = (IntPtr)10; return; // the Mouse on Left Form
case "r": m.Result = (IntPtr)11; return; // the Mouse on Right Form
case "a": m.Result = (IntPtr)12; return;
case "la": m.Result = (IntPtr)13; return;
case "ra": m.Result = (IntPtr)14; return;
case "u": m.Result = (IntPtr)15; return;
case "lu": m.Result = (IntPtr)16; return;
case "ru": m.Result = (IntPtr)17; return; // the Mouse on Right_Under Form
case "": m.Result = pt.Y < 32 /*mouse on title Bar*/ ? (IntPtr)2 : (IntPtr)1; return;
}
}
base.WndProc(ref m);
}
}
-
-
elaborate : first id make resize class it's have one method this method to determine position of mouse form calculate (
point mouse
) and (Form form
)to get width and height of form then and the most importanstWndProc
Override Method this method haveref Message m
param whenm.msg=0x84
value u can set m.result=10 that mean you callform
to resize from left andm.Result=11
callform
from Right and ....to 17 but whenm.Result=2 you call to move the
form` and whenm.Result=1
that mean calldon't do any thing
Commented Sep 25, 2014 at 9:41 -
1it helps, but it doens't handle scrolling, it creates new border 'lines' through the form when scrolling Commented Dec 10, 2014 at 22:18
The simplest way is to assign mouse events to the form or the title bar, whatever you want to be hold for moving. You can move a BorderLess Form with assigning these methods to there events as names in method.
int movX,movY;
bool isMoving;
private void onMouseDown(object sender, MouseEventArgs e)
{
// Assign this method to mouse_Down event of Form or Panel,whatever you want
isMoving = true;
movX = e.X;
movY = e.Y;
}
private void onMouseMove(object sender, MouseEventArgs e)
{
// Assign this method to Mouse_Move event of that Form or Panel
if (isMoving)
{
this.SetDesktopLocation(MousePosition.X - movX, MousePosition.Y - movY);
}
}
private void onMouseUp(object sender, MouseEventArgs e)
{
// Assign this method to Mouse_Up event of Form or Panel.
isMoving = false;
}
If you don't mind a short bar at the top, you can use a "regular" sizable form with the .ControlBox
set to false and .Text
(the caption bar at the top) set to an empty string.
You'll end up with a resizable form that looks like the Task Manager when you double-click on a chart. The advantage of this method is that when you resize it from the left, the right border does not jerk. The same is also when you resize it from the top.
this.FormBorderStyle = FormBorderStyle.Sizable;
this.ControlBox = false;
this.Text = "";
-
-
1