Solved

C# - Resizing PictureBox with Drag Boxes

Posted on 2007-04-10
10
4,481 Views
Last Modified: 2011-10-03
Hi guys 'n gals,

What is the best approach to add drag boxes (I think that's the term used?) to a selected PictureBox, so that it may be resized?


Cheers!
0
Comment
Question by:Cyber-Drugs
  • 5
  • 5
10 Comments
 
LVL 30

Expert Comment

by:Alexandre Simões
ID: 18892203
There are more complicated solutions, but the easiest is to implement/use something like this:

http://www.codeproject.com/csharp/ResizeControlsRuntime.asp


Alex
0
 
LVL 4

Author Comment

by:Cyber-Drugs
ID: 18904320
How about creating some PictureBoxes, and then make them appear at the correct points of my selected object, add drag and drop capability to them, and when they are dragged, the selected object is resized. Would that be good method?
0
 
LVL 30

Expert Comment

by:Alexandre Simões
ID: 18905770
You want to simulate what happens at design-time on VS right?
That behavior can be implemented, directly, without using any kind of simulations, basically using the same designers and containers the VS does.

The fact is that this approach is hard to implement.
Take a look at the best of the few articles about this matter at:
http://divil.co.uk/net/articles/designers/hosting.asp

As I said, this isn't easy to implement, as neither is your suggested scenario.

You can also implement your own container that will behave as you want, but still those squares to resize will give you some headaches.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 30

Expert Comment

by:Alexandre Simões
ID: 18905805
Doing some digging and testing I came with the following...

I took the base code from:
http://www.thinksharp.org/?p=35

and changed it to the following...
I only implemented for the left side of the square, you must complete the rest.
Hope you like it...


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace YourNameSpace
{
      public partial class ResizablePanel : Panel
      {
        private Boolean _ResizeParent;

        private class NativeCalls
        {
            [DllImport("USER32.DLL", EntryPoint = "SendMessage")]
            public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref int lParam);

            [DllImport("user32")]
            public static extern int ReleaseCapture(IntPtr hwnd);
            public const int WM_SYSCOMMAND = 0x0112;
            public const int SC_DRAGMOVE = 0xF012;
            public const int SC_DRAGSIZE_N = 0xF003;
            public const int SC_DRAGSIZE_S = 0xF006;
            public const int SC_DRAGSIZE_E = 0xF002;
            public const int SC_DRAGSIZE_W = 0xF001;
            public const int SC_DRAGSIZE_NW = 0xF004;
            public const int SC_DRAGSIZE_NE = 0xF005;
            public const int SC_DRAGSIZE_SW = 0xF007;
            public const int SC_DRAGSIZE_SE = 0xF008;
        }

        public Boolean ResizeParent

        {
            get { return _ResizeParent; }
            set { _ResizeParent = value; }
        }

        public ResizablePanel()
        {
            InitializeComponent();
            MinimumSize = new Size(50, 50);
            Margin = new Padding(0, 0, 0, 0);
            Padding = new Padding(0, 0, 3, 3);
            BackColor = SystemColors.ControlLight;
        }

        private enum MousePos {NoWhere, Right, Bottom, Top, Left, BottomRight, BottomLeft, TopRight, TopLeft}

        private MousePos GetMousePos(Point location)

        {
            MousePos result = MousePos.NoWhere;

            Rectangle TestRect;

            int RightSize = Padding.Right;
            int BottomSize = Padding.Bottom;

                  // Resize left border
                  TestRect = new Rectangle(new Point(0, (this.Height/2) - 4), new Size(8, 8));
                  if (TestRect.Contains(location)) result = MousePos.Left;

                  // Resize bottom left border
                  TestRect = new Rectangle(new Point(0, this.Height - 9), new Size(8, 8));
                  if (TestRect.Contains(location)) result = MousePos.BottomLeft;

                  // Resize top left border
                  TestRect = new Rectangle(new Point(0, 0), new Size(8, 8));
                  if (TestRect.Contains(location)) result = MousePos.TopLeft;




            // Resize right border
            TestRect = new Rectangle(Width - RightSize, 0, Width - RightSize, Height - BottomSize);
            if (TestRect.Contains(location)) result = MousePos.Right;

            // Resize bottom border
            TestRect = new Rectangle(0, Height - BottomSize, Width - RightSize, Height);
            if (TestRect.Contains(location)) result = MousePos.Bottom;

            // Resize bottom Corner
            TestRect = new Rectangle(Width - RightSize, Height -BottomSize, Width, Height);
            if (TestRect.Contains(location)) result = MousePos.BottomRight;
            return result;
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            IntPtr hwnd = this.Handle;

            if ((ResizeParent) && (this.Parent != null) && (this.Parent.IsHandleCreated))
            {
                hwnd = Parent.Handle;
            }
            int nul = 0;
            MousePos mousePos = GetMousePos(e.Location);
            switch (mousePos)

            {
                        case MousePos.Left:
                              {
                                    NativeCalls.ReleaseCapture(hwnd);
                                    NativeCalls.SendMessage(hwnd, NativeCalls.WM_SYSCOMMAND, NativeCalls.SC_DRAGSIZE_W, ref nul);
                              } break;
                        case MousePos.BottomLeft:
                              {
                                    NativeCalls.ReleaseCapture(hwnd);
                                    NativeCalls.SendMessage(hwnd, NativeCalls.WM_SYSCOMMAND, NativeCalls.SC_DRAGSIZE_SW, ref nul);
                              } break;
                        case MousePos.TopLeft:
                              {
                                    NativeCalls.ReleaseCapture(hwnd);
                                    NativeCalls.SendMessage(hwnd, NativeCalls.WM_SYSCOMMAND, NativeCalls.SC_DRAGSIZE_NW, ref nul);
                              } break;
                case MousePos.Right:
                    {
                        NativeCalls.ReleaseCapture(hwnd);
                        NativeCalls.SendMessage(hwnd, NativeCalls.WM_SYSCOMMAND, NativeCalls.SC_DRAGSIZE_E, ref nul);
                    } break;
                case MousePos.Bottom:
                    {
                        NativeCalls.ReleaseCapture(hwnd);
                        NativeCalls.SendMessage(hwnd, NativeCalls.WM_SYSCOMMAND, NativeCalls.SC_DRAGSIZE_S, ref nul);
                    } break;
                case MousePos.BottomRight:

                    {
                        NativeCalls.ReleaseCapture(hwnd);
                        NativeCalls.SendMessage(hwnd, NativeCalls.WM_SYSCOMMAND, NativeCalls.SC_DRAGSIZE_SE, ref nul);

                    } break;
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)

        {
            base.OnMouseMove(e);

            MousePos mousePos = GetMousePos(e.Location);
            switch (mousePos)
            {
                        case MousePos.TopLeft: Cursor = Cursors.SizeNWSE; break;
                        case MousePos.Left: Cursor = Cursors.SizeWE; break;
                        case MousePos.BottomLeft: Cursor = Cursors.SizeNESW; break;
                case MousePos.Right: Cursor = Cursors.SizeWE; break;
                case MousePos.Bottom: Cursor = Cursors.SizeNS; break;
                case MousePos.BottomRight: Cursor = Cursors.SizeNWSE; break;
                default: Cursor = Cursors.Default; break;
            }
        }

        protected override void OnResize(EventArgs eventargs)

        {
            base.OnResize(eventargs);
            if (this.Width < this.MinimumSize.Width) this.Width = this.MinimumSize.Width;
            if (this.Height < this.MinimumSize.Height) this.Height = this.MinimumSize.Height;
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            Cursor = Cursors.Default;
        }

            private void ResizablePanel_Paint(object sender, PaintEventArgs e)
            {
                  this.PaintSquares(e.Graphics);
            }

            private void PaintSquares(Graphics g)
            {
                  Pen pen = new Pen(Color.Black);
                  Brush brush = new SolidBrush(Color.White);


                  g.FillRectangle(brush, new Rectangle(new Point(0, 0), new Size(8, 8)));
                  g.FillRectangle(brush, new Rectangle(new Point(0, (this.Height/2) - 4), new Size(8, 8)));
                  g.FillRectangle(brush, new Rectangle(new Point(0, this.Height - 9), new Size(8, 8)));


                  g.DrawRectangle(pen, new Rectangle(new Point(0, 0), new Size(8, 8)));
                  g.DrawRectangle(pen, new Rectangle(new Point(0, (this.Height / 2) - 4), new Size(8, 8)));
                  g.DrawRectangle(pen, new Rectangle(new Point(0, this.Height - 9), new Size(8, 8)));
            }

            private void ResizablePanel_Resize(object sender, EventArgs e)
            {
                  this.Invalidate();
            }

      }
}

0
 
LVL 4

Author Comment

by:Cyber-Drugs
ID: 18905979
I'll give it a try this evening, if it gives the functionality for just one side, I'm sure that I can work out how to attach it to the other sides.

Cheers! :o)
0
 
LVL 30

Accepted Solution

by:
Alexandre Simões earned 500 total points
ID: 18906646
I made some adjustments... now you can also drag the panel and the size squares don't appear behind the possible child controls of the form...





using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace YourNameSpace
{
      public partial class ResizablePanel : Panel
      {
        private Boolean _ResizeParent;

        private class NativeCalls
        {
            [DllImport("USER32.DLL", EntryPoint = "SendMessage")]
            public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref int lParam);

            [DllImport("user32")]
            public static extern int ReleaseCapture(IntPtr hwnd);
            public const int WM_SYSCOMMAND = 0x0112;
            public const int SC_DRAGMOVE = 0xF012;
            public const int SC_DRAGSIZE_N = 0xF003;
            public const int SC_DRAGSIZE_S = 0xF006;
            public const int SC_DRAGSIZE_E = 0xF002;
            public const int SC_DRAGSIZE_W = 0xF001;
            public const int SC_DRAGSIZE_NW = 0xF004;
            public const int SC_DRAGSIZE_NE = 0xF005;
            public const int SC_DRAGSIZE_SW = 0xF007;
            public const int SC_DRAGSIZE_SE = 0xF008;
        }

        public Boolean ResizeParent

        {
            get { return _ResizeParent; }
            set { _ResizeParent = value; }
        }

        public ResizablePanel()
        {
            InitializeComponent();
            MinimumSize = new Size(50, 50);
            Margin = new Padding(0, 0, 0, 0);
            Padding = new Padding(8, 8, 8, 8);
            BackColor = SystemColors.ControlLight;
        }

        private enum MousePos {NoWhere, Move, Right, Bottom, Top, Left, BottomRight, BottomLeft, TopRight, TopLeft}

        private MousePos GetMousePos(Point location)

        {
            MousePos result = MousePos.NoWhere;

            Rectangle TestRect;

            int RightSize = Padding.Right;
            int BottomSize = Padding.Bottom;


                  // Move control
                  TestRect = new Rectangle(0, 0, Width, Height);
                  if (TestRect.Contains(location)) result = MousePos.Move;


                  // Resize left border
                  TestRect = new Rectangle(new Point(0, (this.Height/2) - 4), new Size(8, 8));
                  if (TestRect.Contains(location)) result = MousePos.Left;

                  // Resize bottom left border
                  TestRect = new Rectangle(new Point(0, this.Height - 8), new Size(8, 8));
                  if (TestRect.Contains(location)) result = MousePos.BottomLeft;

                  // Resize top left border
                  TestRect = new Rectangle(new Point(0, 0), new Size(8, 8));
                  if (TestRect.Contains(location)) result = MousePos.TopLeft;




            // Resize right border
            TestRect = new Rectangle(Width - RightSize, 0, Width - RightSize, Height - BottomSize);
            if (TestRect.Contains(location)) result = MousePos.Right;

            // Resize bottom border
            TestRect = new Rectangle(0, Height - BottomSize, Width - RightSize, Height);
            if (TestRect.Contains(location)) result = MousePos.Bottom;

            // Resize bottom Corner
            TestRect = new Rectangle(Width - RightSize, Height -BottomSize, Width, Height);
            if (TestRect.Contains(location)) result = MousePos.BottomRight;







            return result;
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            IntPtr hwnd = this.Handle;

            if ((ResizeParent) && (this.Parent != null) && (this.Parent.IsHandleCreated))
            {
                hwnd = Parent.Handle;
            }
            int nul = 0;
            MousePos mousePos = GetMousePos(e.Location);
            switch (mousePos)

            {
                        case MousePos.Left:
                              {
                                    NativeCalls.ReleaseCapture(hwnd);
                                    NativeCalls.SendMessage(hwnd, NativeCalls.WM_SYSCOMMAND, NativeCalls.SC_DRAGSIZE_W, ref nul);
                              } break;
                        case MousePos.BottomLeft:
                              {
                                    NativeCalls.ReleaseCapture(hwnd);
                                    NativeCalls.SendMessage(hwnd, NativeCalls.WM_SYSCOMMAND, NativeCalls.SC_DRAGSIZE_SW, ref nul);
                              } break;
                        case MousePos.TopLeft:
                              {
                                    NativeCalls.ReleaseCapture(hwnd);
                                    NativeCalls.SendMessage(hwnd, NativeCalls.WM_SYSCOMMAND, NativeCalls.SC_DRAGSIZE_NW, ref nul);
                              } break;
                case MousePos.Right:
                    {
                        NativeCalls.ReleaseCapture(hwnd);
                        NativeCalls.SendMessage(hwnd, NativeCalls.WM_SYSCOMMAND, NativeCalls.SC_DRAGSIZE_E, ref nul);
                    } break;
                case MousePos.Bottom:
                    {
                        NativeCalls.ReleaseCapture(hwnd);
                        NativeCalls.SendMessage(hwnd, NativeCalls.WM_SYSCOMMAND, NativeCalls.SC_DRAGSIZE_S, ref nul);
                    } break;
                case MousePos.BottomRight:

                    {
                        NativeCalls.ReleaseCapture(hwnd);
                        NativeCalls.SendMessage(hwnd, NativeCalls.WM_SYSCOMMAND, NativeCalls.SC_DRAGSIZE_SE, ref nul);

                    } break;
                        case MousePos.Move:
                              {
                                    NativeCalls.ReleaseCapture(hwnd);
                                    NativeCalls.SendMessage(hwnd, NativeCalls.WM_SYSCOMMAND, NativeCalls.SC_DRAGMOVE, ref nul);

                              } break;
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)

        {
            base.OnMouseMove(e);
                  
            MousePos mousePos = GetMousePos(e.Location);
            switch (mousePos)
            {
                        case MousePos.TopLeft: Cursor = Cursors.SizeNWSE; break;
                        case MousePos.Left: Cursor = Cursors.SizeWE; break;
                        case MousePos.BottomLeft: Cursor = Cursors.SizeNESW; break;
                case MousePos.Right: Cursor = Cursors.SizeWE; break;
                case MousePos.Bottom: Cursor = Cursors.SizeNS; break;
                case MousePos.BottomRight: Cursor = Cursors.SizeNWSE; break;
                        case MousePos.Move: Cursor = Cursors.SizeAll; break;
                default: Cursor = Cursors.Default; break;
            }
        }

        protected override void OnResize(EventArgs eventargs)

        {
            base.OnResize(eventargs);
            if (this.Width < this.MinimumSize.Width) this.Width = this.MinimumSize.Width;
            if (this.Height < this.MinimumSize.Height) this.Height = this.MinimumSize.Height;
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            Cursor = Cursors.Default;
        }

            private void ResizablePanel_Paint(object sender, PaintEventArgs e)
            {
                  //this.PaintSquares(e.Graphics);
            }

            protected override void OnPaint(PaintEventArgs e)
            {

                  // At design-time there are already resize squares, we don't need owrs.
                  if (!this.DesignMode)
                  {
                        PaintSquares(e.Graphics);
                  }

                  base.OnPaint(e);
            }

            private void PaintSquares(Graphics g)
            {
                  Pen pen = new Pen(Color.Black);
                  Brush brush = new SolidBrush(Color.White);

                  //g.FillRectangle(brush, new Rectangle(new Point(0, 0), new Size(8, 8)));
                  //g.FillRectangle(brush, new Rectangle(new Point(0, (this.Height/2) - 4), new Size(8, 8)));
                  //g.FillRectangle(brush, new Rectangle(new Point(0, this.Height - 9), new Size(8, 8)));


                  ControlPaint.DrawBorder3D(g, new Rectangle(new Point(0, 0), new Size(8, 8)));
                  ControlPaint.DrawBorder3D(g, new Rectangle(new Point(0, (this.Height / 2) - 4), new Size(8, 8)));
                  ControlPaint.DrawBorder3D(g, new Rectangle(new Point(0, this.Height - 8), new Size(8, 8)));
            }

            private void ResizablePanel_Resize(object sender, EventArgs e)
            {
                  this.Invalidate();
            }

      }
}
0
 
LVL 4

Author Comment

by:Cyber-Drugs
ID: 18913382
Hey Alex,

Just added your code into my project, and tried to compile (just to test I copied it over correctly), and got this error:

Error      1      The name 'InitializeComponent' does not exist in the current context


I copied the code into a new class, but in the same namespace, was I meant to copy it into the same Class, as I noticed there is a reference to:

InitializeComponent();
0
 
LVL 4

Author Comment

by:Cyber-Drugs
ID: 18913387
Just commented that out, and tried it out...

The bottom left square smudges over the Panel.
The top left square both resizes and moves the Panel (while resizing).

It looks very good, but looks like I need to do some research into the bugs. If it's ok with you, I would like to keep this question open until I've got a complete version, so who-ever else may have this problem, can have a completed product?

Cheers for all the help thus far. :o)
0
 
LVL 4

Author Comment

by:Cyber-Drugs
ID: 18952563
Taking me a bit too long to fix this, your solution works, just needs tweaking. When I finish it, I will post the code for everyone else to make use of.

Cheers!
0
 
LVL 30

Expert Comment

by:Alexandre Simões
ID: 18953764
I made some changes myself... :)

I'll post them back here too.

Alex
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Although it is an old technology, serial ports are still being used by many hardware manufacturers. If you develop applications in C#, Microsoft .NET framework has SerialPort class to communicate with the serial ports.  I needed to…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Are you ready to implement Active Directory best practices without reading 300+ pages? You're in luck. In this webinar hosted by Skyport Systems, you gain insight into Microsoft's latest comprehensive guide, with tips on the best and easiest way…

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question