Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

161 lines
4.0 KiB

// 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;
}