Solved

C# - Resizing PictureBox with Drag Boxes

Posted on 2007-04-10
10
4,554 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

 
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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Summary: Persistence is the capability of an application to store the state of objects and recover it when necessary. This article compares the two common types of serialization in aspects of data access, readability, and runtime cost. A ready-to…
This article introduced a TextBox that supports transparent background.   Introduction TextBox is the most widely used control component in GUI design. Most GUI controls do not support transparent background and more or less do not have the…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…

696 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