Thursday, September 11, 2008

Draw a Transparent Bitmap into the destination DC in MFC

// Draw a transparent bitmap into the destination DC.

void CEMCHotCtrl::TransparentBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HBITMAP hBitmap, int nXSrc, int nYSrc, COLORREF cTransparentColor)

{

COLORREF cColor;

HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;

HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;

HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;

POINT ptSize;

hdcTemp = CreateCompatibleDC(hdcDest);

SelectObject(hdcTemp, hBitmap); // Select the bitmap

ptSize.x = nWidth;

ptSize.y = nHeight;

DPtoLP(hdcTemp, &ptSize, 1); // Convert from device

// Create some DCs to hold temporary data.

hdcBack = CreateCompatibleDC(hdcDest);

hdcObject = CreateCompatibleDC(hdcDest);

hdcMem = CreateCompatibleDC(hdcDest);

hdcSave = CreateCompatibleDC(hdcDest);

// 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(hdcDest, ptSize.x, ptSize.y);

bmSave = CreateCompatibleBitmap(hdcDest, ptSize.x, ptSize.y);

// Each DC must select a bitmap object to store pixel data.

bmBackOld = (HBITMAP)SelectObject(hdcBack, bmAndBack);

bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject);

bmMemOld = (HBITMAP)SelectObject(hdcMem, bmAndMem);

bmSaveOld = (HBITMAP)SelectObject(hdcSave, bmSave);

// Set proper mapping mode.

SetMapMode(hdcTemp, GetMapMode(hdcDest));

// 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, nXDest, nYDest, ptSize.x, ptSize.y, hdcDest, nXSrc, nYSrc, 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(hdcDest, nXDest, nYDest, ptSize.x, ptSize.y, hdcMem, nXSrc, nYSrc, 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);

}

No comments: