The following nine steps describe a process used to draw transparent bitmaps:
1.
|
Create a DC to hold the image bitmap.
|
2.
|
Select the image bitmap into the DC.
|
3.
|
Create a memory DC to hold the final image. This is the destination DC.
|
4.
|
Copy the portion of the screen that will be covered by the image into the destination DC.
|
5.
|
Create an "AND mask" that contains the mask of the colors to draw (the nontransparent portions of the image). To do this, perform the following three steps:
a.
|
Set the background color of the image DC to the color that will be transparent in the image.
|
b.
|
Create a monochrome DC.
|
c.
|
BitBlt the image into the monochrome DC.
|
This will create an AND mask of the bitmap by setting pixels that match the background color to white (1), and setting all other pixels to black (0).
|
6.
|
Use BitBlt with the SRCAND raster operation code to copy the AND mask onto the destination DC.
|
7.
|
Use BitBlt with the SRCAND raster operation code to copy the inverse of the AND mask onto the image DC.
|
8.
|
Use BitBlt with the SRCPAINT raster operation code to copy the image DC onto the destination DC.
|
9.
|
Use BitBlt to copy the contents of the destination DC to the appropriate portion of the screen.
|
The following code is a function that demonstrates the preceding steps:
?
void
?DrawTransparentBitmap(HDC?hdc,?HBITMAP?hBitmap,?
short
?xStart,
???????????????????????????
short
?yStart,?COLORREF?cTransparentColor)
???{
???BITMAP?????bm;
???COLORREF???cColor;
???HBITMAP????bmAndBack,?bmAndObject,?bmAndMem,?bmSave;
???HBITMAP????bmBackOld,?bmObjectOld,?bmMemOld,?bmSaveOld;
???HDC????????hdcMem,?hdcBack,?hdcObject,?hdcTemp,?hdcSave;
???POINT??????ptSize;
???hdcTemp?
=
?CreateCompatibleDC(hdc);
???SelectObject(hdcTemp,?hBitmap);???
//
?Select?the?bitmap
???GetObject(hBitmap,?sizeof(BITMAP),?(LPSTR)
&
bm);
???ptSize.x?
=
?bm.bmWidth;????????????
//
?Get?width?of?bitmap
???ptSize.y?
=
?bm.bmHeight;???????????
//
?Get?height?of?bitmap
???DPtoLP(hdcTemp,?
&
ptSize,?
1
);??????
//
?Convert?from?device
?????????????????????????????????????
//
?to?logical?points
???
//
?Create?some?DCs?to?hold?temporary?data.
???hdcBack???
=
?CreateCompatibleDC(hdc);
???hdcObject?
=
?CreateCompatibleDC(hdc);
???hdcMem????
=
?CreateCompatibleDC(hdc);
???hdcSave???
=
?CreateCompatibleDC(hdc);
???
//
?Create?a?bitmap?for?each?DC.?DCs?are?required?for?a?number?of
???
//
?GDI?functions.
???
//
?Monochrome?DC
???bmAndBack???
=
?CreateBitmap(ptSize.x,?ptSize.y,?
1
,?
1
,?NULL);
???
//
?Monochrome?DC
???bmAndObject?
=
?CreateBitmap(ptSize.x,?ptSize.y,?
1
,?
1
,?NULL);
???bmAndMem????
=
?CreateCompatibleBitmap(hdc,?ptSize.x,?ptSize.y);
???bmSave??????
=
?CreateCompatibleBitmap(hdc,?ptSize.x,?ptSize.y);
???
//
?Each?DC?must?select?a?bitmap?object?to?store?pixel?data.
???bmBackOld???
=
?SelectObject(hdcBack,?bmAndBack);
???bmObjectOld?
=
?SelectObject(hdcObject,?bmAndObject);
???bmMemOld????
=
?SelectObject(hdcMem,?bmAndMem);
???bmSaveOld???
=
?SelectObject(hdcSave,?bmSave);
???
//
?Set?proper?mapping?mode.
???SetMapMode(hdcTemp,?GetMapMode(hdc));
???
//
?Save?the?bitmap?sent?here,?because?it?will?be?overwritten.
???BitBlt(hdcSave,?
0
,?
0
,?ptSize.x,?ptSize.y,?hdcTemp,?
0
,?
0
,?SRCCOPY);
???
//
?Set?the?background?color?of?the?source?DC?to?the?color.
???
//
?contained?in?the?parts?of?the?bitmap?that?should?be?transparent
???cColor?
=
?SetBkColor(hdcTemp,?cTransparentColor);
???
//
?Create?the?object?mask?for?the?bitmap?by?performing?a?BitBlt
???
//
?from?the?source?bitmap?to?a?monochrome?bitmap.
???BitBlt(hdcObject,?
0
,?
0
,?ptSize.x,?ptSize.y,?hdcTemp,?
0
,?
0
,
??????????SRCCOPY);
???
//
?Set?the?background?color?of?the?source?DC?back?to?the?original
???
//
?color.
???SetBkColor(hdcTemp,?cColor);
???
//
?Create?the?inverse?of?the?object?mask.
???BitBlt(hdcBack,?
0
,?
0
,?ptSize.x,?ptSize.y,?hdcObject,?
0
,?
0
,
??????????NOTSRCCOPY);
???
//
?Copy?the?background?of?the?main?DC?to?the?destination.
???BitBlt(hdcMem,?
0
,?
0
,?ptSize.x,?ptSize.y,?hdc,?xStart,?yStart,
??????????SRCCOPY);
???
//
?Mask?out?the?places?where?the?bitmap?will?be?placed.
???BitBlt(hdcMem,?
0
,?
0
,?ptSize.x,?ptSize.y,?hdcObject,?
0
,?
0
,?SRCAND);
???
//
?Mask?out?the?transparent?colored?pixels?on?the?bitmap.
???BitBlt(hdcTemp,?
0
,?
0
,?ptSize.x,?ptSize.y,?hdcBack,?
0
,?
0
,?SRCAND);
???
//
?XOR?the?bitmap?with?the?background?on?the?destination?DC.
???BitBlt(hdcMem,?
0
,?
0
,?ptSize.x,?ptSize.y,?hdcTemp,?
0
,?
0
,?SRCPAINT);
???
//
?Copy?the?destination?to?the?screen.
???BitBlt(hdc,?xStart,?yStart,?ptSize.x,?ptSize.y,?hdcMem,?
0
,?
0
,
??????????SRCCOPY);
???
//
?Place?the?original?bitmap?back?into?the?bitmap?sent?here.
???BitBlt(hdcTemp,?
0
,?
0
,?ptSize.x,?ptSize.y,?hdcSave,?
0
,?
0
,?SRCCOPY);
???
//
?Delete?the?memory?bitmaps.
???DeleteObject(SelectObject(hdcBack,?bmBackOld));
???DeleteObject(SelectObject(hdcObject,?bmObjectOld));
???DeleteObject(SelectObject(hdcMem,?bmMemOld));
???DeleteObject(SelectObject(hdcSave,?bmSaveOld));
???
//
?Delete?the?memory?DCs.
???DeleteDC(hdcMem);
???DeleteDC(hdcBack);
???DeleteDC(hdcObject);
???DeleteDC(hdcSave);
???DeleteDC(hdcTemp);
???}
????????????????