Reputation: 60
I have own control and I need to resize runtime by dragging. To resize bottom and right borders I use this:
protected override void OnMouseDown(MouseEventArgs e)
{
SL = new System.Drawing.Point(Location.X + e.Location.X, Location.Y + e.Location.Y);
SP = new System.Drawing.Point(Location.X, Location.Y);
if (e.X <= m)
_OnLeft = true;
if (e.X >= Width - m)
_OnRight = true;
if (e.Y <= m)
_OnTop = true;
if (e.Y >= Height - m)
_OnBottom = true;
}
protected override void OnMouseMove(MouseEventArgs e)
{
// Change Width - right
if (_OnRight && (!_OnTop && !_OnBottom))
{
if (e.X <= 1)
return;
Width = e.X;
return;
}
// Change Height - bottom
if (_OnBottom && (!_OnLeft && !_OnRight))
{
if (e.Y <= 1)
return;
Height = e.Y;
return;
}
}
All works fine. But I have problems with Top and Left resizing:
// Change Width - left
if (_OnLeft && (!_OnTop && !_OnBottom))
{
// Problem part - I don't know condition to return
if (Width + Left - e.X <= 1)
return;
Left += e.X - SL.X + SP.X;
// How to get right width
Width += Left - e.X;
return;
}
// Change Height - top
if (_OnTop && (!_OnLeft && !_OnRight))
{
// Problem part - I don't know condition to return
if (Height + Top - e.Y <= 1)
return;
Top += e.Y - SL.Y + SP.Y;
// How to get right height
Height += Top - e.Y;
return;
}
Something like that. Have ideas?
Upvotes: 2
Views: 4597
Reputation: 942408
A completely out-of-box solution is to turn a form into a control. A form already supports resizing so no extra work needs to be done. Start a new Winforms project, add an extra form and try this code to see what it looks like:
public Form1() {
InitializeComponent();
var ctl = new Form2();
ctl.ControlBox = false;
ctl.Text = "";
ctl.Location = new Point(10, 10);
ctl.MinimumSize = new Size(10, 10);
ctl.TopLevel = false;
ctl.Visible = true;
this.Controls.Add(ctl);
ctl.Size = new Size(100, 100);
}
Upvotes: 3
Reputation: 81675
Try changing your code to this:
For the left:
int oldLeft = Left;
Left += e.X - SL.X + SP.X;
// How to get right width
// Width += Left - e.X;
Width += oldLeft - Left;
For the top:
int oldTop = Top;
Top += e.Y - SL.Y + SP.Y;
// How to get right height
// Height += Top - e.Y;
Height += oldTop - Top;
Upvotes: 1
Reputation: 1712
Pretty much the only way to cleanly allow .NET control resizing is to use P/Invoke. This exact code is not tested, but I have used this resizing method many times so it should work:
First, the P/Invoke external declarations:
private static class UnsafeNativeMethods
{
[DllImport("user32.dll")]
public static extern bool ReleaseCapture();
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
}
Next, call the P/Invoke functions to have the operating system handle the resize:
protected override void OnMouseDown(MouseEventArgs e)
{
int msg = -1; //if (msg == -1) at the end of this, then the mousedown is not a drag.
if (e.Y < 8)
{
msg = 12; //Top
if (e.X < 25) msg = 13; //Top Left
if (e.X > Width - 25) msg = 14; //Top Right
}
else if (e.X < 8)
{
msg = 10; //Left
if (e.Y < 17) msg = 13;
if (e.Y > Height - 17) msg = 16;
}
else if (e.Y > Height - 9)
{
msg = 15; //Bottom
if (e.X < 25) msg = 16;
if (e.X > Width - 25) msg = 17;
}
else if (e.X > Width - 9)
{
msg = 11; //Right
if (e.Y < 17) msg = 14;
if (e.Y > Height - 17) msg = 17;
}
if (msg != -1)
{
UnsafeNativeMethods.ReleaseCapture(); //Release current mouse capture
UnsafeNativeMethods.SendMessage(Handle, 0xA1, new IntPtr(msg), IntPtr.Zero);
//Tell the OS that you want to drag the window.
}
}
Finally, override OnMouseMove to change the cursor based on where it is on the control. I'll leave that part to you, because it's almost the same code as the previous snippet.
Upvotes: 3