Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 336
  • Last Modified:

Rapid Mouse Movement When Dragging LineShape Endpoint Via ShapeContainerMouseMoveEventhandler Causes Disconnect Between Mouse and LineShape

I am calling shapecontainermousemoveeventhandler, shapecontainermousedowneventhandler, and shapecontainermouseupeventhandler with (Nothing, e) as parameters from within their respective Form 1 mouse events (see code below), and can successfully change LS color and mouse cursor when the mouse is nearby a LS endpoint.  

When I drag a selected LS endpoint slowly there are no issues.  However, if I whip the mouse pointer quickly while trying to move the LS endpoint, the mouse pointer will depart the LS endpoint leaving it wherever the disconnection occurred on the form.   Is there someway to

  Private Sub Form1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        ShapeContainerMouseMoveEventHandler(Nothing, e)
    End Sub
  Private Sub Form1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        ShapeContainerMouseDownEventHandler(Nothing, e)
    End Sub
    Private Sub Form1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        ShapeContainerMouseMoveEventHandler(Nothing, e)
    End Sub

  Public Sub ShapeContainerMouseMoveEventHandler(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        For Each ls As LineShape In Me.SC.Shapes 'Lines
            If MouseIsNearBy(ls.EndPoint) = True Then
                SelectedLS = ls
                SelectedLS.BorderColor = Color.Red
                ' Me.Refresh()
                NearLineEndPoint = True
                ls.Cursor = Cursors.Hand
            End If
            If MouseIsNearBy(ls.EndPoint) = False Then
                ls.BorderColor = Color.Black
                ' Me.Refresh()
                NearLineEndPoint = False
                ls.Cursor = Cursors.Default
            End If
        Next

        If NearLineEndPoint = True Then
            If (dragStartPoint) Then
                SelectedLS.StartPoint = New Point(oldStartPoint.X + e.X - oldMouseX, oldStartPoint.Y + e.Y - oldMouseY)
            End If
            If (dragEndPoint) Then
                For Each c As Control In Me.Controls
                    If TypeOf (c) Is PictureBox And dragEndPoint Then
                        If e.X > c.Left AndAlso e.X < c.Right AndAlso e.Y < c.Bottom AndAlso e.Y > c.Top Then
                            dropline = True
                            droplinex = c.Left + 2
                            dropliney = c.Top + (c.Height / 2) - 12
                            deltaxinsidebutton = e.X - droplinex
                            deltayinsidebutton = e.Y - dropliney
                            oldEndPoint.X = droplinex - e.X + oldMouseX
                            oldEndPoint.Y = dropliney - e.Y + oldMouseY
                            SelectedLS.EndPoint = New Point(droplinex, dropliney)
                            droplineobjectname = c.Name
                            dropcontrol = c
                            Exit For
                        Else
                            If dropline = True Then
                                oldMouseX = (e.X - droplinex)
                                oldMouseY = (e.Y - dropliney)
                            End If
                            dropline = False
                            SelectedLS.EndPoint = New Point(oldEndPoint.X + e.X - oldMouseX + deltaxinsidebutton, oldEndPoint.Y + e.Y - oldMouseY + deltayinsidebutton)
                        End If
                    End If
                Next
            End If
        End If

    End Sub

 Private Sub ShapeContainerMouseDownEventHandler(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If NearLineEndPoint = False Then Exit Sub

        If MouseIsNearBy(SelectedLS.EndPoint) Then '(SelectedLS.HitTest(MousePosition.X, MousePosition.Y)) Then

            oldMouseX = e.X
            oldMouseY = e.Y
            oldStartPoint = SelectedLS.StartPoint
            oldEndPoint = SelectedLS.EndPoint

            ' dragStartPoint = MouseIsNearBy(oldStartPoint)
            dragEndPoint = MouseIsNearBy(oldEndPoint)
            If (Not dragStartPoint AndAlso Not dragEndPoint) Then
                'If not drag either end, then drag both. 
                '    dragStartPoint = True
                ' dragEndPoint = True
            End If
            SelectedLS.SelectionColor = Color.Transparent
        End If
    End Sub

Open in new window

0
lep1
Asked:
lep1
  • 5
  • 5
1 Solution
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Shouldn't you only move the endpoint when the mouse is down?  Maybe you have that code omitted?

It seems to me that lines 12-26 should be done when no buttons are held down, and the rest should only be executed while the left button is down.
0
 
lep1Author Commented:
Are you saying move the moving code that's used when the left button is held down into the mousedown event and leave code like 12-26 in mousemove.   Correct me if I'm wrong, but don't most codes set a switch to mousedownwasclicked=yes and then update the dragging coordinates of an object inside the mousemove event?  Based on what I have seen, updates to anything while moving were always in the mousemoveevent, and the mousedown was only used to set a switch that the left button is down(??)
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
I meant something more like below:
    Public Sub ShapeContainerMouseMoveEventHandler(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        Select Case e.Button
            Case Windows.Forms.MouseButtons.None
                SelectedLS = Nothing
                NearLineEndPoint = False
                For Each ls As LineShape In Me.SC.Shapes 'Lines
                    If Not NearLineEndPoint AndAlso MouseIsNearBy(ls.EndPoint) Then
                        SelectedLS = ls
                        SelectedLS.BorderColor = Color.Red
                        NearLineEndPoint = True
                        ls.Cursor = Cursors.Hand
                    Else
                        ls.BorderColor = Color.Black
                        ls.Cursor = Cursors.Default
                    End If
                Next
                Me.Refresh()

            Case Windows.Forms.MouseButtons.Left
                If NearLineEndPoint = True Then
                    If (dragStartPoint) Then
                        SelectedLS.StartPoint = New Point(oldStartPoint.X + e.X - oldMouseX, oldStartPoint.Y + e.Y - oldMouseY)
                    End If
                    If (dragEndPoint) Then
                        For Each c As Control In Me.Controls
                            If TypeOf (c) Is PictureBox And dragEndPoint Then
                                If e.X > c.Left AndAlso e.X < c.Right AndAlso e.Y < c.Bottom AndAlso e.Y > c.Top Then
                                    dropline = True
                                    droplinex = c.Left + 2
                                    dropliney = c.Top + (c.Height / 2) - 12
                                    deltaxinsidebutton = e.X - droplinex
                                    deltayinsidebutton = e.Y - dropliney
                                    oldEndPoint.X = droplinex - e.X + oldMouseX
                                    oldEndPoint.Y = dropliney - e.Y + oldMouseY
                                    SelectedLS.EndPoint = New Point(droplinex, dropliney)
                                    droplineobjectname = c.Name
                                    dropcontrol = c
                                    Exit For
                                Else
                                    If dropline = True Then
                                        oldMouseX = (e.X - droplinex)
                                        oldMouseY = (e.Y - dropliney)
                                    End If
                                    dropline = False
                                    SelectedLS.EndPoint = New Point(oldEndPoint.X + e.X - oldMouseX + deltaxinsidebutton, oldEndPoint.Y + e.Y - oldMouseY + deltayinsidebutton)
                                End If
                            End If
                        Next
                    End If
                End If

        End Select
    End Sub

Open in new window


*Definitely save what you currently have.  It's hard to know the effects of changing the code when we can see only a tiny portion and don't have a working project to play with!
0
Technology Partners: 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!

 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Wow...did that really fix your problem?!  I was expecting that to ~maybe~ fix your issue, and simultaneously create a bunch of new ones.
0
 
lep1Author Commented:
You should know that for some strange reason, I identified that when the If statement in line 20 (and its "End If" in line 50) were enabled, you could move the mouse cursor quickly and the cursor would depart from the lineshape endpoint being dragged.   However, when line 20 (and 50) were commented out, the lineshape endpoint being dragged could keep up with the cursor, even when it was quickly whipped across the screen.  

I wonder why that caused the issue - since it was quite nasty of an effect?
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
I also fundamentally changed how NearLineEndPoint was being set:
                SelectedLS = Nothing
                NearLineEndPoint = False
                For Each ls As LineShape In Me.SC.Shapes 'Lines
                    If Not NearLineEndPoint AndAlso MouseIsNearBy(ls.EndPoint) Then
                        SelectedLS = ls
                        SelectedLS.BorderColor = Color.Red
                        NearLineEndPoint = True
                        ls.Cursor = Cursors.Hand
                    Else
                        ls.BorderColor = Color.Black
                        ls.Cursor = Cursors.Default
                    End If
                Next

Open in new window


Before, it was being set to False for every single LineShape that the cursor was NOT near.  Now it will be set to True when it gets a "hit" and will stay that way so that information is retained.  The other LineShapes still get reset to Black though.
0
 
lep1Author Commented:
Line 8 also needs to be changed to :  

Me.Cursor = Cursors.Hand

Open in new window

This way, as soon as the mouse cursor is near a lineshape endpoint, the mouse cursor will change.   The way its listed above, the cursor is really for the lineshape and not the mouse cursor.  The idea is that the line color and the mouse cursor should change when the user's mouse cursor is near the endpoint.  As soon as this occurs, the user can then drag the lineshape's endpoint.
0
 
lep1Author Commented:
I think the Me.Refresh() also causes too much flicker among all the connected lines.   It actually works more smoothly when dragging a line if the Me.Refresh() is commented out.  Very smooth!
0
 
lep1Author Commented:
Interesting, I left your line 20 intact, and there is no problem.  Did your modifications protect something that otherwise in my version made the move calculations seem slow allowing the mouse cursor to depart form the lineshape's endpoint if quickly whipped when the left button was down while dragging the endpoint?
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 5
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now