Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Programmatically resizing a shape in VB.NET

Posted on 2011-03-18
7
Medium Priority
?
829 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
7 Comments
 
LVL 86

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 86

Accepted Solution

by:
Mike Tomlinson earned 500 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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 86

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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Make the most of your online learning experience.
Introduction to Processes
Starting up a Project
Suggested Courses

596 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