Title | Let the user drag a picture with the mouse or move it with the arrow keys |
Description | |
Keywords | drag picture, BitBlt |
Categories | Graphics |
|
|
In the KeyDown event handler, set m_Dx or m_Dy values to indicate the direction of movement and enable a timer. When the timer fires, move the object. In the KeyUp event handler, clear m_Dx and m_Dy appropriately.
|
|
This program lets the user either drag an image or use the arrow keys to move an image.
The program's picMask PictureBox contains a mask of the image to be dragged. Pixels that should be drawn are black and pixels that should let the background show through are white.
In the MouseDown event handler, the program subtracts the overlay picture's current position from the mouse's coordinates to see where on the overlay picture the user clicked. If the corresponding mask pixel is white, the user is pressing where the background should show through so the event is ignored.
If the corresponding mask pixel is black, the user is pressing the mouse on part of the image and the program begins a drag.
|
|
' See if this point corresponds to
' a black point on the mask.
Private Sub picCanvas_MouseDown(Button As Integer, Shift As _
Integer, x As Single, y As Single)
If picXMask.Point(x - CurX, y - CurY) <> vbBlack Then _
Exit Sub
' Start dragging.
Dragging = True
OffsetX = CurX - x
OffsetY = CurY - y
End Sub
|
|
In the MouseMove event handler, the program determines where the picture should be placed and calls DrawPicture to draw it.
|
|
' Continue dragging.
Private Sub picCanvas_MouseMove(Button As Integer, Shift As _
Integer, x As Single, y As Single)
If Not Dragging Then Exit Sub
CurX = x + OffsetX
CurY = y + OffsetY
If CurX < 0 Then CurX = 0
If CurX > Xmax Then CurX = Xmax
If CurY < 0 Then CurY = 0
If CurY > Ymax Then CurY = Ymax
DrawPicture
End Sub
|
|
Subroutine DrawPic restores the background picture by using BitBlt to copy the part of the background that is currently covered by the overlay onto picCanvas. It then uses BitBlt to copy the overlay mask onto picCanvas using the opcode MERGEPAINT. This knocks out the mask's outline on the background so a white image of the overlay appears.
Next the code copies the overlay image onto the background using the SRCAND opcode. This combines the pixel values of the overlay image with the background image. The overlay image is white where it should not show and the background image is white where the overlay should show. The result is the overlay is dropped into its correct position.
|
|
' Draw the picture at (CurX, CurY).
Private Sub DrawPicture()
' Fix the part of the image that was covered.
BitBlt picCanvas.hDC, _
OldX, OldY, PicWid, PicHgt, _
picHidden.hDC, OldX, OldY, SRCCOPY
OldX = CurX
OldY = CurY
' Paint on the new image.
BitBlt picCanvas.hDC, _
CurX, CurY, PicWid, PicHgt, _
picXMask.hDC, 0, 0, MERGEPAINT
BitBlt picCanvas.hDC, _
CurX, CurY, PicWid, PicHgt, _
picX.hDC, 0, 0, SRCAND
' Update the display.
picCanvas.Refresh
End Sub
|
|
The MouseUp event handler simply ends the drag.
|
|
' Stop dragging.
Private Sub picCanvas_MouseUp(Button As Integer, Shift As _
Integer, x As Single, y As Single)
Dragging = False
End Sub
|
|
The form's KeyDown event handler sets a variable to indicate the direction it should move the overlay image and then enables the tmrKeyMover Timer.
The KeyUp event handler modifies the direction of motion variables appropriately and disables the timer if there should be no further motion.
|
|
Private Sub Form_KeyDown(KeyCode As Integer, Shift As _
Integer)
Select Case KeyCode
Case vbKeyLeft
m_Dx = -5
Case vbKeyRight
m_Dx = 5
Case vbKeyUp
m_Dy = -5
Case vbKeyDown
m_Dy = 5
End Select
tmrKeyMover.Enabled = (m_Dx <> 0) Or (m_Dy <> 0)
End Sub
Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
Select Case KeyCode
Case vbKeyLeft, vbKeyRight
m_Dx = 0
Case vbKeyUp, vbKeyDown
m_Dy = 0
End Select
tmrKeyMover.Enabled = (m_Dx <> 0) Or (m_Dy <> 0)
End Sub
|
|
The tmrKeyMover Timer updates the position of the overlay picture and calls DrawPicture to draw it at the proper location.
|
|
Private Sub tmrKeyMover_Timer()
CurX = CurX + m_Dx
CurY = CurY + m_Dy
If CurX < 0 Then CurX = 0
If CurX > Xmax Then CurX = Xmax
If CurY < 0 Then CurY = 0
If CurY > Ymax Then CurY = Ymax
DrawPicture
End Sub
|
|
My book Visual Basic Graphics Programming has more information on this kind of graphic manipulation.
See also:
|
|
|
|