Solved

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

Posted on 2013-05-22
10
325 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
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
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
 
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

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
HTTPS jquery doesn't work 9 64
Switching Visual Studio 2015 to normal debug display 3 28
get combo value in class 5 10
MailAddress in vb 4 17
For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
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…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

831 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