Solved

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

Posted on 2013-05-22
10
319 Views
Last Modified: 2013-05-25
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
Comment
Question by:lep1
  • 5
  • 5
10 Comments
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 39188285
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
 

Author Comment

by:lep1
ID: 39195862
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
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 500 total points
ID: 39196972
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
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 39197013
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
 

Author Comment

by:lep1
ID: 39197019
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
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

 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 39197025
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
 

Author Comment

by:lep1
ID: 39197040
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
 

Author Comment

by:lep1
ID: 39197043
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
 

Author Comment

by:lep1
ID: 39197048
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
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 39197055
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
How do I get the id from URL? 19 47
Duplicate a row 2 29
Hovering effect 9 29
System32Int Error 8 44
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

708 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

16 Experts available now in Live!

Get 1:1 Help Now