Link to home
Start Free TrialLog in
Avatar of Cyber-Drugs
Cyber-DrugsFlag for United Kingdom of Great Britain and Northern Ireland

asked on

C# - Resizing PictureBox with Drag Boxes

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!
Avatar of Alexandre Simões
Alexandre Simões
Flag of Switzerland image

There are more complicated solutions, but the easiest is to implement/use something like this:

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


Alex
Avatar of Cyber-Drugs

ASKER

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?
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.
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();
            }

      }
}

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)
ASKER CERTIFIED SOLUTION
Avatar of Alexandre Simões
Alexandre Simões
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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();
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)
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!
I made some changes myself... :)

I'll post them back here too.

Alex