Solved

Programmatically resizing a shape in VB.NET

Posted on 2011-03-18
7
805 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
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 

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

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Help Required 2 30
Import a txt file into a DataGridView and TextBox 20 34
Convert datetime to time string 10 19
printf performancy 11 33
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…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
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 …
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 …

786 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