Solved

Programmatically resizing a shape in VB.NET

Posted on 2011-03-18
7
802 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
Comment Utility
"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
Comment Utility
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
Comment Utility
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:MikeDFarrant
Comment Utility
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
Comment Utility
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
Comment Utility
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

771 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

11 Experts available now in Live!

Get 1:1 Help Now