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 select an irregular area and copy it to the clipboard
DescriptionThis example shows how to let the user select an irregular area and copy it to the clipboard in Visual Basic 6. It uses the MouseDown, MouseMove, and MouseUp events to draw the area. After selection, it uses a Timer to redraw the area so it is visible.
Keywordsselect, area, polygon, irregular area, clipboard
CategoriesGraphics, Tips and Tricks, Multimedia
 
The program uses the MouseDown, MouseMove, and MouseUp to let the user select the area. It draws the selection using the Polyline API function, setting DrawStyle = vbDot to draw dashed lines.

After the area is selected, the program enables a timer that redraws the selected area with DrawStyle = vbSolid and DrawMode = vbInvert every 1/4 second. That inverts the dotted lines and makes them flash. (This is sometimes called "crawling ants.")

 
' Start drawing.
Private Sub Form_MouseDown(Button As Integer, Shift As _
    Integer, X As Single, Y As Single)
    m_Drawing = True

    ' Remove the previous selction boundary.
    RemoveBoundary

    ' Save the initial point.
    m_NumPoints = 1
    ReDim m_Points(1 To m_NumPoints)
    With m_Points(m_NumPoints)
        .X = X
        .Y = Y
    End With

    ' Draw the polygon.
    Polyline hdc, m_Points(1), m_NumPoints
    Refresh
End Sub

' Continue drawing.
Private Sub Form_MouseMove(Button As Integer, Shift As _
    Integer, X As Single, Y As Single)
    ' Do nothing if we're not drawing.
    If Not m_Drawing Then Exit Sub

    ' Do nothing if the point hasn't changed.
    With m_Points(m_NumPoints)
        If (.X = X) And (.Y = Y) Then Exit Sub
    End With

    ' Erase the old curve.
    Polyline hdc, m_Points(1), m_NumPoints

    ' Save the new point.
    m_NumPoints = m_NumPoints + 1
    ReDim Preserve m_Points(1 To m_NumPoints)
    With m_Points(m_NumPoints)
        .X = X
        .Y = Y
        If .X < 0 Then .X = 0
        If .X >= ScaleWidth Then .X = ScaleWidth - 1
        If .Y < 0 Then .Y = 0
        If .Y >= ScaleHeight Then .Y = ScaleHeight - 1
    End With

    ' Draw the new curve.
    Polyline hdc, m_Points(1), m_NumPoints
    Refresh
End Sub

' Stop drawing.
Private Sub Form_MouseUp(Button As Integer, Shift As _
    Integer, X As Single, Y As Single)
    ' Do nothing if we're not drawing.
    If Not m_Drawing Then Exit Sub
    m_Drawing = False

    ' Erase the old curve.
    Polyline hdc, m_Points(1), m_NumPoints

    ' Close the curve.
    m_NumPoints = m_NumPoints + 1
    ReDim Preserve m_Points(1 To m_NumPoints)
    m_Points(m_NumPoints).X = m_Points(1).X
    m_Points(m_NumPoints).Y = m_Points(1).Y

    ' Draw the closed curve, dotted.
    Polyline hdc, m_Points(1), m_NumPoints
    Refresh

    ' Start the redraw timer.
    tmrDrawSelection.Enabled = True
    m_Inverted = False
End Sub

' Remove the selection boundary.
Private Sub RemoveBoundary()
    ' Erase the previously selected area.
    tmrDrawSelection.Enabled = False
    DrawMode = vbInvert
    If m_NumPoints > 0 Then
        If m_Inverted Then
            ' The previous polygon is inverted.
            ' Draw with DrawStyle = vbSolid to
            ' put it back to normal.
            DrawStyle = vbSolid
            Polyline hdc, m_Points(1), m_NumPoints
            m_Inverted = False
        End If

        ' Now invert with DrawStyle = vbDot to
        ' erase the polygon.
        DrawStyle = vbDot
        Polyline hdc, m_Points(1), m_NumPoints
    Else
        DrawStyle = vbDot
    End If
End Sub

Private Sub tmrDrawSelection_Timer()
    ' Invert the selected area boundary.
    DrawMode = vbInvert
    DrawStyle = vbSolid
    Polyline hdc, m_Points(1), m_NumPoints
    Refresh
    DrawMode = vbCopyPen

    ' Remember whether the polygon is inverted or not.
    m_Inverted = Not m_Inverted
End Sub
 
When the user clicks Ctrl-C or Ctrl-X, the program calls subroutine CopySelectedRegion.
 
Private Sub Form_KeyPress(KeyAscii As Integer)
    Select Case KeyAscii
        Case 3  ' Ctrl-C
            CopySelectedRegion
        Case 24 ' Ctrl-X
            CopySelectedRegion True
    End Select
End Sub
 
CopySelectedRegion fills a hidden mask PictureBox with black and fills the polygon's area with white.

Next the routine copies the form's full picture into the picHidden PictureBox. It copies the mask over this with the opcode vbSrcAnd to erase the parts of the image that are blank in the mask. That turns those areas black so the program copies the mask onto picHidden again with opcode vbMergePaint to turn then white.

Now picHidden contains just the selected area surrounded by white. The program copies this image to the clipboard.

If the user pressed Ctrl-X, the program copies the mask onto the form with the vbSrcPaint opcode to erase the selected area.

 
' Copy the selected region to picHidden.
Private Sub CopySelectedRegion(Optional ByVal do_cut As _
    Boolean = False)
    ' Remove the previous selction boundary.
    RemoveBoundary

    ' Erase the selected area in the mask.
    picMask.BackColor = vbBlack
    picMask.Cls
    picMask.ForeColor = vbWhite
    picMask.FillColor = vbWhite
    picMask.FillStyle = vbFSSolid
    Polygon picMask.hdc, m_Points(1), m_NumPoints
    picMask.Picture = picMask.Image

    ' Copy the full image onto picHidden.
    picHidden.PaintPicture Me.Picture, 0, 0

    ' Knock out the parts outside of the polygon.
    picHidden.PaintPicture picMask.Picture, 0, 0, _
        Opcode:=vbSrcAnd

    ' Invert the black outlying area.
    picHidden.PaintPicture picMask.Picture, 0, 0, _
        Opcode:=vbMergePaint
    picHidden.Picture = picHidden.Image

    ' Copy the result to the clipboard.
    Clipboard.Clear
    Clipboard.SetData picHidden.Picture

    ' If we should cut the area out of the original, do so.
    If do_cut Then
        Me.PaintPicture picMask.Picture, 0, 0, _
            Opcode:=vbSrcPaint
    End If

    ' Redraw the closed curve, dotted.
    Polyline hdc, m_Points(1), m_NumPoints
    Refresh

    ' Restart the redraw timer.
    m_Inverted = False
    tmrDrawSelection.Enabled = True
End Sub
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated