|
|
Title | Overlay a picture on another and use BitBlt to allow the user to drag it |
Description | |
Keywords | drag picture, BitBlt |
Categories | Graphics |
|
|
This program lets the user either drag an image or drag a rectangle showing where the image will be placed. Dragging only the rectangle can be much faster for large images.
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. In that case, the program determines whether it should drag only an outline and saves the result in the Boolean UseOutline.
|
|
' See if the mouse is over a point corresponding
' to a black part of the mask.
Private Sub picCanvas_MouseDown(Button As Integer, Shift As _
Integer, X As Single, Y As Single)
OffsetX = PicX - X
OffsetY = PicY - Y
If picMask.Point(-OffsetX, -OffsetY) <> vbBlack Then _
Exit Sub
' Start dragging.
UseOutline = (chkUseOutline.Value = vbChecked)
If UseOutline Then DrawOutline
Dragging = True
End Sub
|
|
In the MouseMove event handler, the program checks whether it is drawing an outline. If it is, the code calls subroutine DrawOutline to erase the previous outline.
The event handler then determines where the picture should be placed and calls DrawOutline or DrawPic to draw the outline or picture as appropriate.
|
|
' Drag.
Private Sub picCanvas_MouseMove(Button As Integer, Shift As _
Integer, X As Single, Y As Single)
If Not Dragging Then Exit Sub
If UseOutline Then DrawOutline
PicX = X + OffsetX
If PicX < 0 Then
PicX = 0
ElseIf PicX > CanvasWid - PicWid Then
PicX = CanvasWid - PicWid
End If
PicY = Y + OffsetY
If PicY < 0 Then
PicY = 0
ElseIf PicY > CanvasHgt - PicHgt Then
PicY = CanvasHgt - PicHgt
End If
If UseOutline Then
DrawOutline
Else
DrawPic
End If
End Sub
|
|
Subroutine DrawOutline simply draws a rectangle where the picture should be. The picCanvas control has drawing mode set to invert so the rectangle is erasable.
Subroutine DrawPic restores the background picture by copying it from the hidden PictureBox picBackground onto the visible PictureBox 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 an outline of the picture.
Private Sub DrawOutline()
picCanvas.Line _
(PicX, PicY)-Step(PicWid, PicHgt), , B
End Sub
' Draw the picture.
Private Sub DrawPic()
picCanvas.Picture = picBackground.Picture
BitBlt picCanvas.hDC, _
PicX, PicY, PicWid, PicHgt, _
picMask.hDC, _
0, 0, MERGEPAINT
BitBlt picCanvas.hDC, _
PicX, PicY, PicWid, PicHgt, _
picImage.hDC, _
0, 0, SRCAND
picCanvas.Picture = picCanvas.Image
End Sub
|
|
If the user is dragging only an outline, the MouseUp event handler calls subroutine DrawPic to draw the overlay image at the desired location. This covers the previous outline.
If the user is not dragging only an outline, the picture is already in its new position.
|
|
' Stop dragging.
Private Sub picCanvas_MouseUp(Button As Integer, Shift As _
Integer, X As Single, Y As Single)
If UseOutline Then DrawPic
Dragging = False
End Sub
|
|
My book Visual Basic Graphics Programming has more information on this kind of graphic manipulation.
See also:
|
|
|
|
|
|