justAuser
justAuser

Reputation: 60

Resizing control at runtime

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

Answers (3)

Hans Passant
Hans Passant

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

LarsTech
LarsTech

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

leviathanbadger
leviathanbadger

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

Related Questions