Link to home
Start Free TrialLog in
Avatar of lep1
lep1

asked on

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

Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

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.
Avatar of lep1
lep1

ASKER

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(??)
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Wow...did that really fix your problem?!  I was expecting that to ~maybe~ fix your issue, and simultaneously create a bunch of new ones.
Avatar of lep1

ASKER

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?
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.
Avatar of lep1

ASKER

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.
Avatar of lep1

ASKER

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!
Avatar of lep1

ASKER

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?