Solved

Programmatically resizing a shape in VB.NET

Posted on 2011-03-18
7
803 Views
Last Modified: 2012-05-11
I'm struggling with a control that I'm tring to build.
I want to be able to resize a simple rectangle by dragging out either the right or the left edge, or if I click on the middle drag the whole rectangle left and right.

Below is my code which works quite well if I move the mouse very slowly.  Unfortunately, if you move the mouse too quick it jumps off the rectangle and stops the resizing.  As drgmode is left active I have to find a way to jump my mouse back onto the rectangle and click to get drgmode back to null.

Is there a way of ensuring the mouse does not slip off the rectangle?  Or has anyone got any code that is tried and tested on this?

Thanks


Sample Code:

    Private Sub rsMarker_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles rsMarker.MouseDown
        drgStart = Cursor.Position.X
        rsMarker.BorderColor = Color.White
        Select Case e.X
            Case Is <= CInt(rsMarker.Width / 10)
                Cursor.Current = Cursors.SizeWE
                drgMode = "Back"
            Case Is > CInt(rsMarker.Width - (rsMarker.Width / 10))
                Cursor.Current = Cursors.SizeWE
                drgMode = "Forward"
            Case Else
                Cursor.Current = Cursors.SizeAll
                drgMode = "Move"
        End Select
    End Sub

    Private Sub rsMarker_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles rsMarker.MouseMove
        Select Case drgMode
            Case Is = "Back"
                rsMarker.Width -= Cursor.Position.X - drgStart
                rsMarker.Left += Cursor.Position.X - drgStart
            Case Is = "Forward"
                rsMarker.Width += Cursor.Position.X - drgStart
            Case Is = "Move"
                rsMarker.Left += Cursor.Position.X - drgStart
            Case Else
                Select Case e.X
                    Case Is <= CInt(rsMarker.Width / 5)
                        Cursor.Current = Cursors.SizeWE
                    Case Is > CInt(rsMarker.Width - (rsMarker.Width / 5))
                        Cursor.Current = Cursors.SizeWE
                    Case Else
                        Cursor.Current = Cursors.SizeAll
                End Select
        End Select
        drgStart = Cursor.Position.X
    End Sub

    Private Sub rsMarker_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles rsMarker.MouseUp
        rsMarker.BorderColor = Color.Black
        drgMode = ""
    End Sub

Open in new window

0
Comment
Question by:MikeDFarrant
  • 3
  • 2
7 Comments
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 35169495
"Is there a way of ensuring the mouse does not slip off the rectangle?"

Yes.  Only attempt to move or resize your control when the mouse button is actually DOWN.  When the mouse is dragged with the button down, it will still fire the MouseMove() event when the cursor is outside the bounds of the control.

Still use your "drgMode" to track what kind of resize is occurring, but you'd need to integrate it with this kind of structure:
Private Sub rsMarker_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles rsMarker.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then

        ElseIf e.Button = Windows.Forms.MouseButtons.None Then

        End If
    End Sub

    Private Sub rsMarker_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles rsMarker.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
         
            ' ... this will fire OUTSIDE the control as long as the mouse is held down ...

        ElseIf e.Button = Windows.Forms.MouseButtons.None Then

        End If
    End Sub

Open in new window

0
 

Author Comment

by:MikeDFarrant
ID: 35170156
Thanks Idle_Mind.  

This did get around one problem.  Now it will only move if my mouse is down - which is great.

Unfortunately the mouse still can jump out of the rectangle and then it does stop resizing/moving.

0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 125 total points
ID: 35170212
If the mouse is down you'll still get MouseMove() events even when it leaves the bounds of the control.

Show me your current MouseDown() and MouseMove() events.

Just to show what I mean, watch how the box moves even when my cursor is BELOW and OUTSIDE the bounds of the control:
Public Class Form1

    Private drgStart As Integer

    Private Sub rsMarker_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles rsMarker.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            drgStart = Cursor.Position.X
        End If
    End Sub

    Private Sub rsMarker_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles rsMarker.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            rsMarker.Left += Cursor.Position.X - drgStart
            drgStart = Cursor.Position.X
        End If
    End Sub

End Class

Open in new window


Idle-Mind-434476.flv
0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 

Author Comment

by:MikeDFarrant
ID: 35195465
I totally agree that it should work the way you describe (and demonstrate) I was really surprised when I saw what was happening with mine.

Anyway, I've played around and still my mouse seemed to 'drop' the object as it exited its confines.  I'm wondering if it is something to do with the shape being inside a custom control.
My solution in the end was to clip the cursor to the rectangle whilst the mouse is down.  This works really well (Code attached).  I hate admitting defeat but I really had to move on.

Thanks anyway... if anyone else is able to reproduce my problem and finds a proper solution please post it here.

Thanks,

Mike
Private Sub rsMarker_MouseDown(ByVal sender As Object, _
                ByVal e As System.Windows.Forms.MouseEventArgs) Handles rsMarker.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Cursor.Clip = rsMarker.RectangleToScreen(rsMarker.ClientRectangle) '<< Clip Cursor
            drgStart = Cursor.Position.X
            rsMarker.BorderColor = Color.White
            Select Case e.X
                Case Is <= CInt(rsMarker.Width / 5)
                    Cursor.Current = Cursors.SizeWE
                    drgMode = "Back"
                Case Is > CInt(rsMarker.Width - (rsMarker.Width / 5))
                    Cursor.Current = Cursors.SizeWE
                    drgMode = "Forward"
                Case Else
                    Cursor.Current = Cursors.SizeAll
                    drgMode = "Move"
            End Select
        End If

    End Sub

    Private Sub rsMarker_MouseMove(ByVal sender As Object, _
                ByVal e As System.Windows.Forms.MouseEventArgs) Handles rsMarker.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Select Case drgMode
                Case Is = "Back"
                    rsMarker.Width -= Cursor.Position.X - drgStart
                    rsMarker.Left += Cursor.Position.X - drgStart
                    moving = True
                Case Is = "Forward"
                    rsMarker.Width += Cursor.Position.X - drgStart
                    moving = True
                Case Is = "Move"
                    rsMarker.Left += Cursor.Position.X - drgStart
                    moving = True
                Case Else
            End Select
            drgStart = Cursor.Position.X
            Cursor.Clip = rsMarker.RectangleToScreen(rsMarker.ClientRectangle) ' <<< clip cursor
        Else
            Select Case e.X
                Case Is <= CInt(rsMarker.Width / 5)
                    Cursor.Current = Cursors.SizeWE
                Case Is > CInt(rsMarker.Width - (rsMarker.Width / 5))
                    Cursor.Current = Cursors.SizeWE
                Case Else
                    Cursor.Current = Cursors.SizeAll
            End Select
        End If
    End Sub

    Private Sub rsMarker_MouseUp(ByVal sender As Object, _ 
                ByVal e As System.Windows.Forms.MouseEventArgs) Handles rsMarker.MouseUp
        rsMarker.BorderColor = Color.Black
        drgMode = ""
        Cursor.Clip = Rectangle.Empty ' << remove clip restriction
    End Sub

Open in new window

0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 35195478
Yeah...I think we'd have to play with your actual custom controls to figure out.  Sorry we couldn't solve it for ya...  =\

Glad you got something working though.
0
 
LVL 53

Expert Comment

by:Dhaest
ID: 35718310
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Calling web service and its methods dynamically 2 43
detecting  the added row index in a datagridview 3 62
Error in page 3 46
Automated testing suggestions? 2 29
Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
Displaying an arrayList in a listView using the default adapter is rarely the best solution. To get full control of your display data, and to be able to refresh it after editing, requires the use of a custom adapter.
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

863 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

Need Help in Real-Time?

Connect with top rated Experts

28 Experts available now in Live!

Get 1:1 Help Now