BitBlt Explained
You can skim through this tutorial just learning how to use bitblt if you want. I myself however wondered for a period of time just how this fancy bitblt thing worked. Since I wondered that I learnt a bit of boolean stuff and so I took a look at the underlying way that the mask to get a partly transparent image works. I will endeavour to explain this as I go along. If you don't have a clue about logic gates, boolean algebra or binary then you could well get a bit lost. If you find this happens I would recommend looking on the howstuffworks website as it has an excellent clear description of logic gates and binary.First things first you need to know that bitblt is an API so it must be declared. Here is the declaration. The only bit that you should change is the private part depending on where you are using the function.
Public Declare Function BitBlt Lib "gdi32" _ (ByVal hDestDC As Long, ByVal X As Long, _ ByVal Y As Long, ByVal nWidth As Long, _ ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc _ As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
hDestDC - This is the hDC reference of the destination picture/canvas. To get and objects hDC just use its hDC property (form1.hDC). If an object doesn't have a hDC property then you can't use it. I think only pictureboxes and forms have it. For the techy people a hDC reference is the address in the computers memory where the objects drawing data is stored.
X - This is just the X coordinate of where the picture will be put in the destination.
Y - Same but the Y coordinate.
nWidth - The width of the picture to be copied (The picture will be cropped not scaled, if larger than the source then the function takes the bit of the screen the is next to it).
nHeight - Same but height.
hSrcDC - The hDC reference of the source picture.
xSrc - The X coordinate of the chosen rectangle in the source picture.
ySrc - Same but the y coordinate.
dwRop - Tells the function how to copy the stuff.
dwRop
Here are the options for dwRop:vbDstInvert - Inverts the destination rectangle.
vbMergeCopy - Merges the colors of the source rectangle with the objects current brush using Boolean AND.
vbMergePaint - Combines the inverted source bitmap with the destination bitmap by using Boolean OR.
vbNotSrcCopy - Copies the inverted source bitmap to the destination bitmap.
vbNotSrcErase - Inverts the result of combining the destination and source bitmaps by using OR
vbPatCopy - Copies the objects current brush onto the destination bitmap
vbPatInvert - Combines the destination bitmap with the objects current brush by using XOR
vbPatPaint - Combines the inverted source bitmap with the objects current brush by using Or. It then Combines the result of this operation with the destination bitmap by using Boolean OR.
vbSrcAnd - Combines the destination and source bitmaps by using Boolean AND
vbSrcCopy - Copies the source bitmap to the destination bitmap.
vbSrcErase - Inverts the destination bitmap and combines the result with the source bitmap using Boolean AND.
vbSrcInvert - Combines the destination and source bitmaps by using Boolean XOR.
vbSrcPaint - Combines the destination and source bitmaps by using Boolean OR.
Drawing a simple rectangular picture
This is a very basic use for bitblt. It just copies a rectangle from one place to another. You coudl use it in something like a tile engine for drawing the tiles.In the example you will need a picture box called sourcepic with a picture in it. If you make the picturebox invisible make sure you set autoredraw to true. I have put a nice picture of some grass below which provides a nice background for what we will do below.

The dwRop for this is vbSrcCopy which just replaces the destination bits with the ones from the source.
Private Declare Function BitBlt Lib "gdi32" _ (ByVal hDestDC As Long, ByVal X As Long, _ ByVal Y As Long, ByVal nWidth As Long, _ ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc _ As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long Private Sub Form_Load() Me.AutoRedraw = True BitBlt Me.hDC, 10, 10, 250, 250, SourcePic.hDC, 0, 0, vbSrcCopy End Sub
Remember that the units are all in pixels not twips.
Using a picture and mask
There are in fact two ways of doing this with each one using the function calls in the opposite order. I will only tell you about one in detail.First you will need to prepare your pictures (or use mine below). The main picture should have a black background (if all of your pictures have a white background then I would recommend using the second method to save the bother). For your mask you should have a white background with the object in centre being filled in with black.
Now you should load your two pictures into pictureboxes ready for running. If you set the pictureboxes visible to false then you must set autoredraw to true (It took me ages to debug but I did learn how to use the picture object in VB to do this very task). Here is a function I made that will draw a masked picture.
Private Sub DrawMasked(Dest As Object, Source As Object, SourceMask As Object, X As Long, Y As Long, Width As Long, Height As Long, Optional SourceX As Long, Optional SourceY As Long) BitBlt Dest.hDC, X, Y, Width, Height, SourceMask.hDC, SourceX, SourceY, vbSrcAnd BitBlt Dest.hDC, X, Y, Width, Height, Source.hDC, SourceX, SourceY, vbSrcPaint End Sub
So what the function does is call bitblt twice, first for the mask and then for the main picture. You will notice however that there is a different function call for each. The thing changed is of course the dwRop value that we feed it. This is the main bit which needs explaining.
The first function call tells bitblt to use the boolean AND operator to combine the bits. Heres the truth table for the AND operator:
A B Q 0 0 0 0 1 0 1 0 0 1 1 1
So by this stage we have our picture exactly the same but with a black area where the visible part our our picture will go.
Now, with the second function call we are telling bitblt to use the OR operator to combine the bits. Here is the truth table for OR:
A B Q 0 0 0 0 1 1 1 0 1 1 1 1
This is why we put a black background onto our main picture. The black will not interfere with the colours so all of the black area will be transparent.
Now we can see why we needed to apply the mask first. We have already worked out that black areas do not affect coloured areas. Also we know that our mask left a black area on the background exactly the same shape as our coloured picture. This means that our picture will stay exactly the same when it is applied.
Here is an example which will fit with the previous program. Create two more pictureboxes one called 'MaskSrc' and the other 'PicSrc'. Place this code straight after the first bitblt call.
DrawMasked Me, PicSrc, MaskSrc, 70, 30, 62, 114
Private Declare Function BitBlt Lib "gdi32" _ (ByVal hDestDC As Long, ByVal X As Long, _ ByVal Y As Long, ByVal nWidth As Long, _ ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc _ As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long Private Sub Form_Load() Me.AutoRedraw = True BitBlt Me.hDC, 10, 10, 250, 250, SourcePic.hDC, 0, 0, vbSrcCopy DrawMasked Me, PicSrc, MaskSrc, 70, 30, 62, 114 End Sub Private Sub DrawMasked(Dest As Object, Source As Object, SourceMask As Object, X As Long, Y As Long, Width As Long, Height As Long, Optional SourceX As Long, Optional SourceY As Long) BitBlt Dest.hDC, X, Y, Width, Height, SourceMask.hDC, SourceX, SourceY, vbSrcAnd BitBlt Dest.hDC, X, Y, Width, Height, Source.hDC, SourceX, SourceY, vbSrcPaint End Sub
Other Visual Basic tutorials
© Jonathan Waller 2005; QuantumState Visual Basic




