WindowsForm - Flicker after resize - c#

I've a WinForm application (double buffer enabled) with a TableLayoutPanel containing some DataGridView, some ActiveX control (from NI TestStand) and some labels. I added some code to Form CellPaint event to draw borders where I need.
One label is showing, via Systems.Windows.Forms.Timer, the actual DateTime, incrementing each second. At each update the form is flickering. If I comment the code in CellPaint event, flickering stops.
Adding:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
solves the flickering issue with CellPaint code enabled, but only if I don't resize the form. After resize, flickering starts and never stops.
I tried several proposal found here on SO, with no luck, suspending layout as suggester here, using reflection to enable double buffering on each control.
How can I avoid the flickering also after the resize?
EDIT:
Here below the code related to Cellpaint event:
private void LayoutMainWindow_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
SuspendLayout();
if (e.Row == 0 && e.Column > 0)
{
DrawBottomBorder(e, 1);
}
if (e.Row == 1 && e.Column != 0)
{
DrawBottomBorder(e, 2);
}
if (e.Row <= 8 && e.Column == 0)
{
DrawRightBorder(e, 2);
}
if (e.Row == 2 && e.Column == 0)
{
DrawBottomBorder(e, 2);
}
if ((e.Row >= 2 && e.Row <= 7) && e.Column == 2)
{
DrawRightBorder(e, 2);
}
if (e.Row == 7 && e.Column <= 4)
{
DrawBottomBorder(e, 2);
}
if (e.Row >= 8 && e.Row <= 9)
{
DrawBottomBorder(e, 2);
}
if (e.Row == 9 && e.Column == 0)
{
DrawRightBorder(e, 2);
}
ResumeLayout();
}
private static void DrawRightBorder(TableLayoutCellPaintEventArgs e, float width)
{
Rectangle r = e.CellBounds;
using (Pen pen = new Pen(Color.Gray, width))
{
e.Graphics.DrawLine(pen, r.X + r.Width, r.Y, r.X + r.Width, r.Y + r.Height);
}
}
private static void DrawBottomBorder(TableLayoutCellPaintEventArgs e, float width)
{
Rectangle r = e.CellBounds;
using (Pen pen = new Pen(Color.Gray, width))
{
e.Graphics.DrawLine(pen, r.X, r.Y + r.Height, r.X + r.Width, r.Y + r.Height);
}
}

Thanks to TaW suggestion, as far as CellPaint is related to a TableLayout containing all the controls inside the Form:
private static void SetDoubleBuffered(Control c)
{
if (System.Windows.Forms.SystemInformation.TerminalServerSession)
return;
System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
aProp.SetValue(c, true, null);
}
And then:
SetDoubleBuffered(LayoutMainWindow);
It fixes my issue. Thank you very much guys.

Related

How to delete title bar while also keeping the window resizable? [duplicate]

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.
Some sample code that allow moving and resizing the form:
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) {
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);
}
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);
}
}
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;
}
}}
"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;
}
(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);
}
}
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) FormBorderStyle= Sizable or SizableToolWindows
(2) clear text in form text

C# UserControl scrollbar issues

I'm having trouble setting the VerticalScroll/HorizontalScroll.Value property. Every time I set the value, the scrollbar moves, then snaps back (see screenshot below)
Here is the code for my user control:
using System.Drawing;
using System.Windows.Forms;
namespace MyGanttChart
{
public class Chart : UserControl
{
public Chart()
{
HorizontalScroll.Visible = true;
VerticalScroll.Visible = true;
}
protected override void OnMouseWheel(MouseEventArgs e)
{
base.OnMouseWheel(e);
ScrollEventType scrollType = ScrollEventType.SmallIncrement;
if (e.Delta > 0)
scrollType = ScrollEventType.SmallDecrement;
ScrollOrientation orientation = ScrollOrientation.VerticalScroll;
if (ModifierKeys == Keys.Shift)
orientation = ScrollOrientation.HorizontalScroll;
ScrollEventArgs args = new ScrollEventArgs(scrollType, 1, orientation);
OnScroll(args);
}
protected override void OnScroll(ScrollEventArgs se)
{
base.OnScroll(se);
if (se.ScrollOrientation == ScrollOrientation.HorizontalScroll)
{
//if (se.Type == ScrollEventType.SmallIncrement || se.Type == ScrollEventType.LargeIncrement)
// X -= HorizontalScroll.LargeChange; // se.NewValue;
//else if (se.Type == ScrollEventType.SmallDecrement || se.Type == ScrollEventType.LargeDecrement)
// X += HorizontalScroll.LargeChange;
if ((se.Type == ScrollEventType.SmallIncrement || se.Type == ScrollEventType.LargeIncrement) &&
HorizontalScroll.Value + HorizontalScroll.LargeChange <= HorizontalScroll.Maximum)
{
HorizontalScroll.Value += HorizontalScroll.LargeChange;
}
else if ((se.Type == ScrollEventType.SmallDecrement || se.Type == ScrollEventType.LargeDecrement) &&
HorizontalScroll.Value - HorizontalScroll.LargeChange >= HorizontalScroll.Minimum)
{
HorizontalScroll.Value -= HorizontalScroll.LargeChange;
}
}
else if (se.ScrollOrientation == ScrollOrientation.VerticalScroll)
{
//if (se.Type == ScrollEventType.SmallIncrement || se.Type == ScrollEventType.LargeIncrement)
// Y -= VerticalScroll.LargeChange;
//else if (se.Type == ScrollEventType.SmallDecrement || se.Type == ScrollEventType.LargeDecrement)
// Y += VerticalScroll.LargeChange;
if ((se.Type == ScrollEventType.SmallIncrement || se.Type == ScrollEventType.LargeIncrement) &&
VerticalScroll.Value + VerticalScroll.LargeChange <= VerticalScroll.Maximum)
{
VerticalScroll.Value += VerticalScroll.LargeChange;
}
else if ((se.Type == ScrollEventType.SmallDecrement || se.Type == ScrollEventType.LargeDecrement) &&
VerticalScroll.Value - VerticalScroll.LargeChange >= VerticalScroll.Minimum)
{
VerticalScroll.Value -= VerticalScroll.LargeChange;
}
}
this.Invalidate(); //Force the control to redraw
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (!this.DesignMode)
Draw(e.Graphics, e.ClipRectangle);
}
public float X = 0;
public float Y = 0;
private void Draw(Graphics graphics, Rectangle rect)
{
graphics.TranslateTransform(X, Y);
graphics.Clear(Color.White);
Point center = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
graphics.DrawString("hi", this.Font, new SolidBrush(Color.Black), center.X, center.Y, new StringFormat() { Alignment = StringAlignment.Center});
graphics.Flush();
}
}
}
(The control view currently does not move - I had that working with the X and Y values, but I'm working on the scrollbar values right now)
I've seen this question but setting the value twice or calling PerformLayout() does not seem to work for me. Any suggestions?
From what I see of your code, you don't need any custom code to manage the scrolling of your drawing.
First, you need to add a child panel inside your usercontrol which will be the container of the drawing. So you move the drawing code to this panel. You must ensure that this panel will resize itself if the drawing needs to be bigger. This is what will show the scrollbars on the usercontrol.
Second, you must set the AutoScroll property of your usercontrol to True. Doing so will ensure that any child control having a size or a position exceeding the usercontrol size can be scrolled. Have a look at the AutoScrollMargin property too. This is done automagically by the framework, so no other code is needed. Isn't it beautiful?
Finally, you can remove the two scrollbars you added.
Edit:
Moreover, when you draw, you don't need to compensate for the scrolling position. You just draw with origin 0,0 without taking care of the scroll. In addition, doing it this way will prevent any flickering caused by constantly redrawing.

Create Boundary for a Control Resize

I am creating a label control that allows resizing from the top and bottom of the label. It also only slides vertically when moved. I created the boundaries for its movement and for the bottom part of the resizable label, but I'm having trouble figuring out what I'm doing wrong for the top part. Whenever the mouse is dragged outside of the bounds from the top, it triggers the preset length of 450 pixels. I am using .SetBounds along with Math.Min.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace EventTest
{
public partial class Form1 : Form
{
Point label1_MousePoint_01 = new Point();
Point label1_Start_01 = new Point();
Point label1_End_01 = new Point();
int label1_MouseSwitch_01;
public Form1()
{
InitializeComponent();
label1.MouseDown += Label1_MouseDown;
label1.MouseUp += Label1_MouseUp;
label1.MouseMove += Label1_MouseMove;
}
// Mouse Move Event
private void Label1_MouseMove(object sender, MouseEventArgs e)
{
if ((e.X < label1.Width && e.X > 0 && e.Y > 0 && e.Y < 4) || (e.X < label1.Width && e.X > 0 && e.Y > label1.Height - 4 && e.Y < label1.Height))
{
Cursor.Current = Cursors.SizeNS;
}
// Mouse Event Top Move
if (label1_MouseSwitch_01 == 1)
{
label1.SetBounds(0, Math.Max(e.Y + label1.Location.Y - label1_MousePoint_01.Y, 40), 120, Math.Min(label1.Height - e.Y + label1_MousePoint_01.Y, 450));
}
// Mouse Event Bottom Move
else if (label1_MouseSwitch_01 == 2)
{
label1.Height = Math.Min(660 - label1.Location.Y, e.Location.Y);
}
// Mouse Event Grab and Move
else if (label1_MouseSwitch_01 == 3)
{
int ny = Math.Min(Math.Max((label1.Location.Y - label1_MousePoint_01.Y + e.Y), 40), 660 - label1.Height);
label1.Location = new Point(0, ny);
}
}
// Mouse Up Event
private void Label1_MouseUp(object sender, MouseEventArgs e)
{
label1_MouseSwitch_01 = 0;
if (label1.Height < 20)
{
label1.Height = 20;
}
}
// Mouse Down Event
private void Label1_MouseDown(object sender, MouseEventArgs e)
{
label1_Start_01.Y = label1.Height;
label1_End_01.Y = label1.Top;
// Set Mouse Switch
if (e.Button == MouseButtons.Left)
{
label1_MousePoint_01 = e.Location;
if (e.Y > 0 && e.Y < 4)
{
Cursor.Current = Cursors.SizeNS;
label1_MouseSwitch_01 = 1;
}
else if (e.Y > label1.Height - 4 && e.Y < label1.Height)
{
Cursor.Current = Cursors.SizeNS;
label1_MouseSwitch_01 = 2;
}
else if (e.Y > 4 && e.Y < label1.Height - 4)
{
label1_MouseSwitch_01 = 3;
}
}
}
// Snap To Every 20 Pixels
public int RoundEr(int i)
{
return ((int)Math.Round(i / 20.0)) * 20;
}
}
}

How to align picture in center and assign its size mode to auto size at the same time?

I've got panel on the form for scrolling and picturebox on panel. When I assign SizeMode to CenterImage, scrolling doesn't work and when assigned to AutoSize then the picture isn't in center.
Is there any posibility for making both - to be able to scroll and picture to be placed in center?
You can try using this simple Panel control that will handle the two requirements for you:
public class PanelImage : Panel {
private Image image;
public PanelImage() {
this.DoubleBuffered = true;
this.ResizeRedraw = true;
}
public Image Image {
get { return image; }
set {
image = value;
if (image != null) {
this.AutoScrollMinSize = image.Size;
}
this.Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e) {
e.Graphics.Clear(Color.White);
if (image != null) {
Point p = this.AutoScrollPosition;
if (image.Width < this.ClientSize.Width) {
p.X = (this.ClientSize.Width / 2) - (image.Width / 2);
}
if (image.Height < this.ClientSize.Height) {
p.Y = (this.ClientSize.Height / 2) - (image.Height / 2);
}
e.Graphics.DrawImage(image, p);
}
base.OnPaint(e);
}
}

How to move and resize a form without a border?

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.
Some sample code that allow moving and resizing the form:
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) {
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);
}
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);
}
}
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;
}
}}
"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;
}
(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);
}
}
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) FormBorderStyle= Sizable or SizableToolWindows
(2) clear text in form text

Categories