|
|
Title | Let the user select an irregular area and copy it to the clipboard |
Description | This 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. |
Keywords | select, area, polygon, irregular area, clipboard |
Categories | Graphics, 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
|
|
|
|
|
|