|
|
// transbmp.cpp : implementation of the CTransBmp class
//
// support for transparent CBitmap objects. Used in the CUserList class.
// Based on a class from MSDN 7/95
#include "stdafx.h"
#include "transbmp.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__; #endif
// Colors
#define rgbWhite RGB(255,255,255)
// Raster op codes
#define DSa 0x008800C6L
#define DSx 0x00660046L
/////////////////////////////////////////////////////////////////////////////
// CTransBmp construction/destruction
CTransBmp::CTransBmp() { m_iWidth = 0; m_iHeight = 0; m_hbmMask = NULL; }
CTransBmp::~CTransBmp() { if (m_hbmMask != NULL) delete m_hbmMask; }
void CTransBmp::GetMetrics() { // Get the width and height
BITMAP bm; GetObject(sizeof(bm), &bm); m_iWidth = bm.bmWidth; m_iHeight = bm.bmHeight; }
int CTransBmp::GetWidth() { if ((m_iWidth == 0) || (m_iHeight == 0)){ GetMetrics(); } return m_iWidth; }
int CTransBmp::GetHeight() { if ((m_iWidth == 0) || (m_iHeight == 0)){ GetMetrics(); } return m_iHeight; }
void CTransBmp::CreateMask(CDC* pDC) { m_hbmMask = new CBitmap; // Nuke any existing mask
if (m_hbmMask) m_hbmMask->DeleteObject();
// Create memory DCs to work with
CDC* hdcMask = new CDC; CDC* hdcImage = new CDC;
hdcMask->CreateCompatibleDC(pDC); hdcImage->CreateCompatibleDC(pDC);
// Create a monochrome bitmap for the mask
m_hbmMask->CreateBitmap(GetWidth(), GetHeight(), 1, 1, NULL); // Select the mono bitmap into its DC
CBitmap* hbmOldMask = hdcMask->SelectObject(m_hbmMask); // Select the image bitmap into its DC
CBitmap* hbmOldImage = hdcImage->SelectObject(CBitmap::FromHandle((HBITMAP)m_hObject));
// Set the transparency color to be the top-left pixel
hdcImage->SetBkColor(hdcImage->GetPixel(0, 0)); // Make the mask
hdcMask->BitBlt(0, 0, GetWidth(), GetHeight(), hdcImage, 0, 0, SRCCOPY); // clean up
hdcMask->SelectObject(hbmOldMask); hdcImage->SelectObject(hbmOldImage); delete hdcMask; delete hdcImage; }
// draw the transparent bitmap using the created mask
void CTransBmp::DrawTrans(CDC* pDC, int x, int y) { if (m_hbmMask == NULL) CreateMask(pDC);
int dx = GetWidth(); int dy = GetHeight();
// Create a memory DC to do the drawing to
CDC* hdcOffScr = new CDC; hdcOffScr->CreateCompatibleDC(pDC);
// Create a bitmap for the off-screen DC that is really
// color compatible with the destination DC.
CBitmap hbmOffScr; hbmOffScr.CreateBitmap(dx, dy, pDC->GetDeviceCaps(PLANES), pDC->GetDeviceCaps(BITSPIXEL), NULL); // Select the buffer bitmap into the off-screen DC
HBITMAP hbmOldOffScr = (HBITMAP)hdcOffScr->SelectObject(hbmOffScr);
// Copy the image of the destination rectangle to the
// off-screen buffer DC so we can play with it
hdcOffScr->BitBlt(0, 0, dx, dy, pDC, x, y, SRCCOPY);
// Create a memory DC for the source image
CDC* hdcImage = new CDC; hdcImage->CreateCompatibleDC(pDC);
CBitmap* hbmOldImage = hdcImage->SelectObject(CBitmap::FromHandle((HBITMAP)m_hObject));
// Create a memory DC for the mask
CDC* hdcMask = new CDC; hdcMask->CreateCompatibleDC(pDC);
CBitmap* hbmOldMask = hdcMask->SelectObject(m_hbmMask);
// XOR the image with the destination
hdcOffScr->SetBkColor(rgbWhite); hdcOffScr->BitBlt(0, 0, dx, dy ,hdcImage, 0, 0, DSx); // AND the destination with the mask
hdcOffScr->BitBlt(0, 0, dx, dy, hdcMask, 0,0, DSa); // XOR the destination with the image again
hdcOffScr->BitBlt(0, 0, dx, dy, hdcImage, 0, 0, DSx);
// Copy the resultant image back to the screen DC
pDC->BitBlt(x, y, dx, dy, hdcOffScr, 0, 0, SRCCOPY);
// Tidy up
hdcOffScr->SelectObject(hbmOldOffScr); hdcImage->SelectObject(hbmOldImage); hdcMask->SelectObject(hbmOldMask);
delete hdcOffScr; delete hdcImage; delete hdcMask; }
|