使用NxDcDrawTransparentDDB void NxDcMaskDDB(HDC hDC, RECT rcDraw, HBITMAP hDDB, HBITMAP hMask, DWORD dwROP) { // Get DDB info BITMAP bm; VERIFY(GetObject(hDDB, sizeof(BITMAP), &bm)); // create memory DC select bitmap to memory DC HDC hMemDC = CreateCompatibleDC(hDC); ASSERT(hMemDC); HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, hDDB); // If monochrome bitmap we set foreground/background color to black/white COLORREF oldForeColor; COLORREF oldBackColor; if (1 == bm.bmBitsPixel) { oldForeColor = SetTextColor(hDC, RGB( 0,0,0 )); oldBackColor = SetBkColor(hDC, RGB( 255,255,255 )); } // StretchBlt BOOL bOK = MaskBlt(hDC, rcDraw.left, rcDraw.top, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, hMask, 0, 0, dwROP); // Restore what we changed for monochrome bitmap if ( 1 == bm.bmBitsPixel ) { SetTextColor(hDC, oldForeColor); SetBkColor(hDC, oldBackColor); } // Restore memory DC's bitmap selection and destroy it SelectObject(hMemDC, hOldBmp); DeleteDC(hMemDC); }void NxDcDrawTransparentDDB(HDC hDC, RECT rcDraw, HBITMAP hDDB, COLORREF clrTransparent) { // Get DDB info CBitmap* pBmp = CBitmap::FromHandle(hDDB); // BITMAP bm; pBmp->GetBitmap(&bm); // Create a mask bitmap CBitmap mask; mask.CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL); // Load to DC to draw the mask CDC dcSrc, dcDst; dcSrc.CreateCompatibleDC(NULL); dcDst.CreateCompatibleDC(NULL); dcSrc.SelectObject(pBmp); dcDst.SelectObject(&mask); // Draw the color bitmap into the mono mask bitmap // To convert color to monochrome, BitBlt sets pixels that match // the background color to white and sets all other pixels to black. // Then we invert the mask bits (white for opaque, black for transparent). dcDst.SetBkColor(clrTransparent); dcDst.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcSrc, 0, 0, SRCCOPY); dcDst.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcSrc, 0, 0, DSTINVERT); // Destroy the DCs dcSrc.DeleteDC(); dcDst.DeleteDC(); // Draw the bitmap with the mask NxDcMaskDDB(hDC, rcDraw, hDDB, mask, MAKEROP4(SRCCOPY, SRCAND)); }
void NxDcMaskDDB(HDC hDC, RECT rcDraw, HBITMAP hDDB, HBITMAP hMask, DWORD dwROP)
{
// Get DDB info
BITMAP bm;
VERIFY(GetObject(hDDB, sizeof(BITMAP), &bm)); // create memory DC select bitmap to memory DC
HDC hMemDC = CreateCompatibleDC(hDC);
ASSERT(hMemDC);
HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, hDDB); // If monochrome bitmap we set foreground/background color to black/white
COLORREF oldForeColor;
COLORREF oldBackColor;
if (1 == bm.bmBitsPixel)
{
oldForeColor = SetTextColor(hDC, RGB( 0,0,0 ));
oldBackColor = SetBkColor(hDC, RGB( 255,255,255 ));
} // StretchBlt
BOOL bOK = MaskBlt(hDC, rcDraw.left, rcDraw.top,
bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, hMask, 0, 0, dwROP); // Restore what we changed for monochrome bitmap
if ( 1 == bm.bmBitsPixel )
{
SetTextColor(hDC, oldForeColor);
SetBkColor(hDC, oldBackColor);
} // Restore memory DC's bitmap selection and destroy it
SelectObject(hMemDC, hOldBmp);
DeleteDC(hMemDC);
}void NxDcDrawTransparentDDB(HDC hDC, RECT rcDraw, HBITMAP hDDB, COLORREF clrTransparent)
{
// Get DDB info
CBitmap* pBmp = CBitmap::FromHandle(hDDB);
//
BITMAP bm;
pBmp->GetBitmap(&bm); // Create a mask bitmap
CBitmap mask;
mask.CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL); // Load to DC to draw the mask
CDC dcSrc, dcDst;
dcSrc.CreateCompatibleDC(NULL);
dcDst.CreateCompatibleDC(NULL);
dcSrc.SelectObject(pBmp);
dcDst.SelectObject(&mask); // Draw the color bitmap into the mono mask bitmap
// To convert color to monochrome, BitBlt sets pixels that match
// the background color to white and sets all other pixels to black.
// Then we invert the mask bits (white for opaque, black for transparent).
dcDst.SetBkColor(clrTransparent);
dcDst.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcSrc, 0, 0, SRCCOPY);
dcDst.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcSrc, 0, 0, DSTINVERT); // Destroy the DCs
dcSrc.DeleteDC();
dcDst.DeleteDC(); // Draw the bitmap with the mask
NxDcMaskDDB(hDC, rcDraw, hDDB, mask, MAKEROP4(SRCCOPY, SRCAND));
}
使用BitBlt函数,
同意dongfa(一桶江湖) 的做法
具体实现的代码可能会不同,不过从道理上不外乎两种,这在我的blog中都有介绍,其中第二种的办法稍微简单一些。而第一种的形式更多一些,我给出的代码、算法和dongfa(一桶江湖) 就不一样。1,用3次ROP运算,dongfa(一桶江湖) 给出的代码就是这种实现。
2,MaskBlt,用特殊的ROP码。