1

enter image description hereI am trying to resize a red rectangle (via a class who inherit PictureBox) in a PictureBox containing an Image, but I have few issues with the method OnResize. I can resize this frame only with the corner bottom-right, which keep the ratio of the frame to 1.5 (landscape). But, when I am resizing the red rectangle, the resizing action should stop when it touch the right or bottom side, but it is working only partially: stop on the right side, but carry on on the bottom side (see pictures).

Below is the code of the OnResize method, but to fully understand the problem, you can follow this Google Drive Link which will give you a short version/application of what I am doing with the issue.

Any ideas are obviously welcome, as there is something I don't understand.

Thanks,

JLuc

    Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
    Try
        ' Minimum limits
        If Me.Width < 40 Then Me.Width = CInt(40 * Form1.dRatioImageWH)
        If Me.Height < 40 Then Me.Height = CInt(40 / Form1.dRatioImageWH)
        ' Keeping the ratio Width/Height = 1.5 (Landscape)
        If Form1.dRatioImageWH > 1 Then Me.Height = CInt(Me.Width / Form1.dRatioImageWH)
        ' Effect on Resize event
        If Me.Width > Form1.PictureBox1.Width - Me.Location.X Then Me.Width = Form1.PictureBox1.Width - Me.Location.X
        If Me.Height > Form1.PictureBox1.Height - Me.Location.Y Then Me.Height = Form1.PictureBox1.Height - Me.Location.Y
        ' Control to be redrawn
        Me.Invalidate()
        ' Raise the Resize event
        MyBase.OnResize(e)
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub
JLuc01
  • 187
  • 1
  • 12
  • 1
    I had a look at the project, it has a long list of issues to fix/avoid. If the idea here is a resizable _Rubber-Band_, then you need to study some examples like [Creating Custom Picturebox with Draggable and Resizable Selection Window](https://stackoverflow.com/questions/53756981/creating-custom-picturebox-with-draggable-and-resizable-selection-window/53774101#53774101). It's `c#` however converting it to `vb.net` is not an issue I presume. Keep it simple. – dr.null Jul 04 '21 at 22:55
  • 1
    Another example to draw directly over a `PictureBox`: [Draw Rectangle over PictureBox](https://stackoverflow.com/a/48484388/14171304). Yet another one [Drawing and scaling rectangle using a ratio](https://stackoverflow.com/a/54710125/14171304). Search for more to study. – dr.null Jul 04 '21 at 23:02
  • @dr.null, thanks for these nice examples, but my main issue is to resize a rectangle without getting out of my container (picturebox), which works on the right side, but not on the bottom side. What I don't understand is when "Me.Height > Form1.PictureBox1.Height - Me.Location.Y" is True, the next statement "Me.Height = Form1.PictureBox1.Height - Me.Location.Y" is ignored. – JLuc01 Jul 06 '21 at 19:01
  • One more thing, if I get rid of this line: "If Form1.dRatioImageWH > 1 Then Me.Height = CInt(Me.Width / Form1.dRatioImageWH)", then it will works, but I want to keep the ratio to 1.5 (dRatioImageWH = 1.501). – JLuc01 Jul 06 '21 at 19:12

2 Answers2

1

I remember having similar issues with OnResize until I realized that there also exists OnResizeEnd, which fires every time.

  • Apparently, OnResizeEnd is not a member of PictureBox, then I can't use it. Not sure it will help in my case. – JLuc01 Jul 06 '21 at 19:08
  • I'm afraid so. Then I can only recommend capturing the MouseUp event of the Form(with KeyPreview = True). [Here](https://stackoverflow.com/questions/7584307/user-control-resize) is a discussion of the same problem. – UnhandledException-InvalidChar Jul 06 '21 at 23:57
0

I found a way to achieve what I wanted. But, it sounds a bit complicated, then if you find something better, do not hesitate to tell me.

The idea is to find out where the left-up corner of my moving/resizing red rectangle is in the PictureBox rectangle ABCD. Is it in the rectangle ABC (impacting on the right side) or in the rectangle ADC (impacting on the bottom side). Then, adjust the right coding depending of the situation.

Follow this LINK for more explanation on the math's side.

    Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
    ' To redraw the whole image based on Glass window
    Try
        ' Minimum limits of Glass window
        If Me.Width < 40 Then Me.Width = CInt(40 * Form1.dRatioImageWH)
        If Me.Height < 40 Then Me.Height = CInt(40 / Form1.dRatioImageWH)
        ' ------------------------------------------------------------
        ' Adjust the right coding after checking if the Point P is within the appropriate triangle 
        ' How do I check whether a given point lies inside a triangle whose coordinates are given?
        ' If Area of ABC == Area of (PAB + PBC + PAC), then Point P is inside the triangle ABC
        ' ------------------------------------------------------------
        Dim A As New Point
        A.X = 0
        A.Y = 0
        Dim B As New Point
        B.X = 400
        B.Y = 0
        Dim C As New Point
        C.X = 400
        C.Y = 266
        Dim P As New Point
        P.X = Me.Location.X
        P.Y = Me.Location.Y
        ' Area of Triangle ABC (upper half of the PictureBox)
        Dim areaABC As Integer
        areaABC = (A.X * (B.Y - C.Y) + B.X * (C.Y - A.Y) + C.X * (A.Y - B.Y)) / 2
        ' Area of 3 Triangles inside the Triangle ABC based on Point P
        Dim areaPAB As Integer
        areaPAB = (P.X * (A.Y - B.Y) + A.X * (B.Y - P.Y) + B.X * (P.Y - A.Y)) / 2
        Dim areaPBC As Integer
        areaPBC = (P.X * (B.Y - C.Y) + B.X * (C.Y - P.Y) + C.X * (P.Y - B.Y)) / 2
        Dim areaPAC As Integer
        areaPAC = (P.X * (A.Y - C.Y) + A.X * (C.Y - P.Y) + C.X * (P.Y - A.Y)) / 2
        ' Target: keep the ratio Width/Height when resizing
        If (areaABC > areaPAB + areaPBC + areaPAC) = True Then
            ' Point P in Triangle ABC (upper half of the PictureBox)
            If Me.Height > Form1.PictureBox1.Height - Me.Location.Y Then
                Me.Height = Form1.PictureBox1.Height - Me.Location.Y
            Else
                Me.Height = CInt(Me.Width / Form1.dRatioImageWH)
            End If
        Else
            ' Point P in Triangle ADC (lower half of the PictureBox)
            If Me.Width > Form1.PictureBox1.Width - Me.Location.X Then
                Me.Width = Form1.PictureBox1.Width - Me.Location.X
            Else
                Me.Width = CInt(Me.Height * Form1.dRatioImageWH)
            End If
        End If
        ' Control to be redrawn
        Me.Invalidate()
            ' Raise the Resize event
            MyBase.OnResize(e)
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub
JLuc01
  • 187
  • 1
  • 12