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 move a polygon's points with grab handles, snapping the points to a grid in VB .NET
Keywordspolygon, grab handles, snap to, grid, draw, drag
CategoriesGraphics, VB.NET
 
Use mouse event handlers to let the user drag points. When this program's PictureBox resizes, the program builds a bitmap named m_BackgroundBitmap that fits the PictureBox and that contains the positioning grid. When the user drags a point, the program uses this bitmap to erase the polygon and redraw the grid. It then draws the grid with its newly moved point.

The key to snapping points to the positioning grid is the SnapToGrid routine. It snaps a point to the nearest grid point. The program uses this routine to snap the point being dragged to the grid in the MouseMove event handler.

 
Private Const GRID_SPACING As Integer = 10

' The grab handle we are dragging. This is 
' -1 when we are not dragging any handle.
Private m_DraggingHandle As Integer = -1

' The data points.
Private m_Points() As Point

Private Const HANDLE_WIDTH As Integer = 6
Private Const HANDLE_HALF_WIDTH As Integer = HANDLE_WIDTH \ _
    2

' A bitmap containing the grid.
Private m_BackgroundBitmap As Bitmap

' Create some initial point data.
Private Sub Form1_Load(ByVal sender As Object, ByVal e As _
    System.EventArgs) Handles MyBase.Load
    ' Make room.
    ReDim m_Points(4)

    ' Set initial points.
    m_Points(0).X = 67 : m_Points(0).Y = 189
    m_Points(1).X = 62 : m_Points(1).Y = 111
    m_Points(2).X = 123 : m_Points(2).Y = 100
    m_Points(3).X = 190 : m_Points(3).Y = 183
    m_Points(4).X = 130 : m_Points(4).Y = 214

    For i As Integer = 0 To 4
        SnapToGrid(m_Points(i).X, m_Points(i).Y)
    Next i
End Sub

' Draw the polygon.
Private Sub DrawPolygon(ByVal gr As Graphics)
    ' Draw the grid.
    gr.DrawImage(m_BackgroundBitmap, 0, 0)

    ' Draw the polygon.
    gr.DrawPolygon(Pens.Black, m_Points)

    ' Draw grab handles as white squares with
    ' black edges.
    Dim rectangles() As Rectangle
    ReDim rectangles(m_Points.GetUpperBound(0))
    For i As Integer = 0 To m_Points.GetUpperBound(0)
        With rectangles(i)
            .X = m_Points(i).X - HANDLE_HALF_WIDTH
            .Y = m_Points(i).Y - HANDLE_HALF_WIDTH
            .Width = HANDLE_WIDTH
            .Height = HANDLE_WIDTH
        End With
    Next i
    gr.FillRectangles(Brushes.White, rectangles)
    gr.DrawRectangles(Pens.Black, rectangles)
End Sub

Private Sub picCanvas_Paint(ByVal sender As Object, ByVal e _
    As System.Windows.Forms.PaintEventArgs) Handles _
    picCanvas.Paint
    DrawPolygon(e.Graphics)
End Sub

' See if we are over a grab handle.
Private Sub picCanvas_MouseDown(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.MouseEventArgs) Handles _
    picCanvas.MouseDown
    Dim dx As Single
    Dim dy As Single

    For i As Integer = 0 To m_Points.GetUpperBound(0)
        If Abs(m_Points(i).X - e.X) < HANDLE_HALF_WIDTH And _
            _
           Abs(m_Points(i).Y - e.Y) < HANDLE_HALF_WIDTH _
        Then
            ' We are over this grab handle.
            ' Start dragging.
            m_DraggingHandle = i
            picCanvas.Cursor = Cursors.Cross
            Exit For
        End If
    Next i
End Sub

' Move the drag handle.
Private Sub picCanvas_MouseMove(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.MouseEventArgs) Handles _
    picCanvas.MouseMove
    ' Do nothing if we are not dragging.
    If m_DraggingHandle = -1 Then Exit Sub

    ' Move the handle.
    m_Points(m_DraggingHandle).X = e.X
    m_Points(m_DraggingHandle).Y = e.Y
    SnapToGrid( _
        m_Points(m_DraggingHandle).X, _
        m_Points(m_DraggingHandle).Y)

    ' Redraw.
    DrawPolygon(picCanvas.CreateGraphics())
End Sub

' Stop dragging.
Private Sub picCanvas_MouseUp(ByVal sender As Object, ByVal _
    e As System.Windows.Forms.MouseEventArgs) Handles _
    picCanvas.MouseUp
    picCanvas.Cursor = Cursors.Default
    m_DraggingHandle = -1
End Sub

' Snap the point to the grid.
Private Sub SnapToGrid(ByRef X As Integer, ByRef Y As _
    Integer)
    X = GRID_SPACING * CInt(X / GRID_SPACING)
    Y = GRID_SPACING * CInt(Y / GRID_SPACING)
End Sub

' Draw the positioning grid.
Private Sub DrawGrid(ByVal bm As Bitmap)
    For Y As Integer = 0 To picCanvas.ClientSize.Height - 1 _
        Step GRID_SPACING
        For X As Integer = 0 To picCanvas.ClientSize.Width _
            - 1 Step GRID_SPACING
            bm.SetPixel(X, Y, Color.Black)
        Next X
    Next Y
End Sub

' Make the background grid bitmap.
Private Sub picCanvas_Resize(ByVal sender As Object, ByVal _
    e As System.EventArgs) Handles picCanvas.Resize
    m_BackgroundBitmap = New _
        Bitmap(picCanvas.ClientSize.Width, _
        picCanvas.ClientSize.Height)

    ' Clear it.
    Dim gr As Graphics = _
        Graphics.FromImage(m_BackgroundBitmap)
    gr.Clear(picCanvas.BackColor)

    ' Draw the grid.
    For Y As Integer = 0 To m_BackgroundBitmap.Height - 1 _
        Step GRID_SPACING
        For X As Integer = 0 To m_BackgroundBitmap.Width - _
            1 Step GRID_SPACING
            m_BackgroundBitmap.SetPixel(X, Y, Color.Black)
        Next X
    Next Y
End Sub
 
For more information on graphics programming in Visual Basic 6, see my book Visual Basic Graphics Programming.
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated