Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleLet the user draw lines and move their end points by using grab handles
Keywordsline, end point, drag, drawing
CategoriesGraphics
 
This program uses two PictureBox variables declared WithEvents. The first, m_NewLinePictureBox, processes MouseMove and MouseUp events when the user is drawing a new line segment. The second, m_MoveEndpointPictureBox, processes MouseMove and MouseUp events when the user is moving an existing line's end point.

The MouseDown event handler uses the FindEndPoint subroutine to see if the mouse is over an existing end point. If it is, the routine sets m_MoveEndpointPictureBox to the drawing surface so its event handlers can move the end point. If the mouse is not over an end point, the routine sets NewLinePictureBox to the drawing surface so its event handlers can make a new line.

 
Private Type Segment
    X(1 To 2) As Single
    Y(1 To 2) As Single
End Type

Private m_NumSegments As Integer
Private m_Segments() As Segment
Private m_GrabbedSegment As Integer
Private m_GrabbedPoint As Integer

Private WithEvents m_NewLinePictureBox As PictureBox
Private WithEvents m_MoveEndpointPictureBox As PictureBox

Private m_X1 As Single
Private m_Y1 As Single
Private m_X2 As Single
Private m_Y2 As Single

Private Sub picCanvas_MouseDown(Button As Integer, Shift As _
    Integer, X As Single, Y As Single)
    ' See if this is an endpoint.
    FindEndPoint X, Y, m_GrabbedSegment, m_GrabbedPoint

    ' See if we found an endpoint.
    If m_GrabbedSegment > 0 Then
        ' We found an endpoint. Start moving it.
        Set m_MoveEndpointPictureBox = picCanvas
    Else
        ' We didn't find an endpoint. Start a new line.
        m_X1 = X
        m_Y1 = Y
        m_X2 = X
        m_Y2 = Y
        picCanvas.DrawMode = vbInvert
        Set m_NewLinePictureBox = picCanvas
    End If
End Sub

' Find the end point at this position if there is one.
Private Sub FindEndPoint(ByVal X As Single, ByVal Y As _
    Single, ByRef segment_num As Integer, ByRef point_num _
    As Integer)
Dim seg As Integer
Dim pt As Integer

    ' See if this is a point.
    segment_num = 0
    point_num = 0
    For seg = 1 To m_NumSegments
        ' Check both end points.
        With m_Segments(seg)
            For pt = 1 To 2
                If Abs(X - .X(pt)) <= GRAB_WID / 2 And _
                   Abs(Y - .Y(pt)) < GRAB_WID / 2 _
                Then
                    ' This is the point.
                    segment_num = seg
                    point_num = pt
                    Exit Sub
                End If
            Next pt
        End With
    Next seg
End Sub
 
The m_MoveEndpointPictureBox_MouseMove event handler updates the grabbed end point's coordinates and redraws the segments.

The MouseUp event handler sets the grabbed segment and point numbers to 0 to indicate that no end point drag is in progress. It then sets m_MoveEndpointPictureBox to Nothing so it doesn't process further mouse events.

 
' Move the selected endpoint.
Private Sub m_MoveEndpointPictureBox_MouseMove(Button As _
    Integer, Shift As Integer, X As Single, Y As Single)
    ' Save the new coordinates.
    m_Segments(m_GrabbedSegment).X(m_GrabbedPoint) = X
    m_Segments(m_GrabbedSegment).Y(m_GrabbedPoint) = Y

    ' Redraw the lines.
    DrawLines
End Sub

' Stop moving the selected point.
Private Sub m_MoveEndpointPictureBox_MouseUp(Button As _
    Integer, Shift As Integer, X As Single, Y As Single)
    m_GrabbedSegment = 0
    m_GrabbedPoint = 0

    ' Stop receiving mouse events.
    Set m_MoveEndpointPictureBox = Nothing
End Sub
 
The m_NewLinePictureBox_MouseMove event handler erases the new segment, updates the segment's end point, and redraws it.

The MouseUp event handler sets m_NewLinePictureBox_MouseMove to Nothing so it no longer receives mouse events, creates the new segment, and redraws the segments.

 
' Continue drawing the new line.
Private Sub m_NewLinePictureBox_MouseMove(Button As _
    Integer, Shift As Integer, X As Single, Y As Single)
    ' Erase the old line.
    picCanvas.Line (m_X1, m_Y1)-(m_X2, m_Y2)

    ' Update the position.
    m_X2 = X
    m_Y2 = Y

    ' Draw the new line.
    picCanvas.Line (m_X1, m_Y1)-(m_X2, m_Y2)
End Sub

' Finish drawing the new line.
Private Sub m_NewLinePictureBox_MouseUp(Button As Integer, _
    Shift As Integer, X As Single, Y As Single)
    ' Stop drawing the new line.
    Set m_NewLinePictureBox = Nothing

    ' Make the new line.
    m_NumSegments = m_NumSegments + 1
    ReDim Preserve m_Segments(1 To m_NumSegments)
    With m_Segments(m_NumSegments)
        .X(1) = m_X1
        .Y(1) = m_Y1
        .X(2) = m_X2
        .Y(2) = m_Y2
    End With

    ' Redraw the lines.
    DrawLines
End Sub
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated