Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

C# - Resizing PictureBox with Drag Boxes

Posted on 2007-04-10
10
Medium Priority
?
4,696 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
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!

 
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 2000 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

Tech or Treat!

Submit an article about your scariest tech experience—and the solution—and you’ll be automatically entered to win one of 4 fantastic tech gadgets.

Question has a verified solution.

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

Article by: Ivo
C# And Nullable Types Since 2.0 C# has Nullable(T) Generic Structure. The idea behind is to allow value type objects to have null values just like reference types have. This concerns scenarios where not all data sources have values (like a databa…
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…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…
Suggested Courses

636 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