Hello,

I'm receiving an error message (ArgumentException was unhandled - Parameter is not valid) when I'm trying to capture a portion of the screen with a rectangle.

It works great when drawing the rectangle with clickPoint.X < lastPoint.X and clickPoint.Y < lastPoint.Y, but when lastPoint.X or/and lastPoint.Y is lower than clickPoint.X or/and clickPoint.Y it throws the exception mentioned above.

Here is the code:

public partial class captureForm : Form
    {
        public bool mouseBtnClicked;

        public Point clickPoint = new Point();
        public Point lastPoint = new Point();
        
        public Bitmap areaCapture;

        public captureForm()
        {
            InitializeComponent();
            formPropreties();
            backGround();

            this.MouseDown += new MouseEventHandler(mouse_Click);
            this.MouseUp += new MouseEventHandler(mouse_Up);
            this.MouseMove += new MouseEventHandler(mouse_Move);
            mouseBtnClicked = false;
        }

        public void formPropreties()
        {
            this.ControlBox = false;
            this.Text = string.Empty;
            this.ShowInTaskbar = false;
            this.WindowState = FormWindowState.Maximized;
            this.Cursor = Cursors.Cross;
            this.DoubleBuffered = true;
        }

        public void backGround()
        {
            Size screenBounds = Screen.PrimaryScreen.Bounds.Size;
            Bitmap capture = new Bitmap(screenBounds.Width, screenBounds.Height);
            Graphics W = Graphics.FromImage(capture);
            W.CopyFromScreen(Point.Empty, Point.Empty, screenBounds);
            this.BackgroundImage = capture;
        }

        private void mouse_Click(object sender, MouseEventArgs e)
        {
            mouseBtnClicked = true;
            clickPoint.X = e.X;
            clickPoint.Y = e.Y;
            lastPoint.X = -1;
            lastPoint.Y = -1;
        }

        public void drawnRectangle(Point p1, Point p2)
        {
            Rectangle rc = new Rectangle();

            p1 = PointToScreen(p1);
            p2 = PointToScreen(p2);

            if (p1.X < p2.X)
            {
                rc.X = p1.X;
                rc.Width = p2.X - p1.X;
            }
            else
            {
                rc.X = p2.X;
                rc.Width = p1.X - p2.X;
            }

            if (p1.Y < p2.Y)
            {
                rc.Y = p1.Y;
                rc.Height = p2.Y - p1.Y;
            }
            else
            {
                rc.Y = p2.Y;
                rc.Height = p1.Y - p2.Y;
            }
            ControlPaint.DrawReversibleFrame(rc, Color.Black, FrameStyle.Dashed);
        }

        public void mouse_Up(object sender, MouseEventArgs e)
        {
            mouseBtnClicked = false;
            if (lastPoint.X != 1)
            {
                Point currentPoint = new Point(e.X, e.Y);
                drawnRectangle(clickPoint, lastPoint);
            }

            Point StartPoint = new Point(clickPoint.X + 1, clickPoint.Y + 1);
            Point hideBorder = new Point( - 1, - 1);
            Rectangle rc = new Rectangle(clickPoint.X, clickPoint.Y, lastPoint.X - clickPoint.X, lastPoint.Y - clickPoint.Y);
            areaCapture = new Bitmap(rc.Width, rc.Height);
            using (Graphics c = Graphics.FromImage(areaCapture))
            {
                c.CopyFromScreen(StartPoint, hideBorder, rc.Size);
            }
            DialogResult = DialogResult.OK;
        }

        private void mouse_Move(object sender, MouseEventArgs e)
        {
            Point currentPoint = new Point(e.X, e.Y);
            if (mouseBtnClicked)
            {
                if (lastPoint.X != -1)
                {
                    drawnRectangle(clickPoint, lastPoint);
                }
                lastPoint = currentPoint;
                drawnRectangle(clickPoint, currentPoint);
            }
        }
    }

Thank you

Hello,

I'm receiving an error message (ArgumentException was unhandled - Parameter is not valid) when I'm trying to capture a portion of the screen with a rectangle.

It works great when drawing the rectangle with clickPoint.X < lastPoint.X and clickPoint.Y < lastPoint.Y, but when lastPoint.X or/and lastPoint.Y is lower than clickPoint.X or/and clickPoint.Y it throws the exception mentioned above.

It's because you are trying to create a rectangle with negative size. Try wrapping your 'lastPoint.X - clickPoint.X' inside of Math.Abs:

Rectangle rc = new Rectangle(clickPoint.X, clickPoint.Y, Math.Abs(lastPoint.X - clickPoint.X), Math.Abs(lastPoint.Y - clickPoint.Y));

You will need to determine which point (clickPoint or lastPoint) is the starting point for the rectangle copy, otherwise it will copy an area equal in size to what you selected, but not from where you wanted it to do so.

Edited 6 Years Ago by Momerath: n/a

It's because you are trying to create a rectangle with negative size. Try wrapping your 'lastPoint.X - clickPoint.X' inside of Math.Abs:

Rectangle rc = new Rectangle(clickPoint.X, clickPoint.Y, Math.Abs(lastPoint.X - clickPoint.X), Math.Abs(lastPoint.Y - clickPoint.Y));

You will need to determine which point (clickPoint or lastPoint) is the starting point for the rectangle copy, otherwise it will copy an area equal in size to what you selected, but not from where you wanted it to do so.

Thank you! That solved my problem.
I have no idea how to determine which point is first...

The coordinate you give when creating a rectangle sets the top left corner. If the user drags a square from bottom to top or right to left then the first clicked location wont necesarrily be the top left corner.
If you compare the X and Y values of the lastPoint and clickPoint and use the lowest of each then you will have the top left corner. For instance, if user clicks at 10,10 and drags to 5,5 you want the rectangle to originate at 5,5. If the user clicks 5,10 and drags to 10,5 you still want it to originate at 5,5. Each time, the rectangle should be created at (lowestX, lowestY).

Hope that helps :)

This article has been dead for over six months. Start a new discussion instead.