Dave's Brain

Browse - programming tips - win32 transparent icons on toolbar

Date: 2008sep11
Platform: win32
Language: C/C++

Q.  How do I get transparent icons in a toolbar?

A.  There are probably other ways to do it but this works for me.
Make the toolbar bitmap with a color to represent transparency
(in this case RGB(192,192,192)).  When you load the bitmap resource
convert that color to the system background color.  Then use
the bitmap in your toolbar.  Here's some code:

static const int iToolbarIconWidth = 32;	// Change to your size
static const int iToolbarIconHeight = 32;	// Change to your size

static const int iToolbarBitmapWidth = iToolbarIconWidth * 13;	// There are
13 icons.  Change to your number.
static const int iToolbarBitmapHeight = 100; 

static const int iGrey = 192;		// Bitmap was created with this has the bg color

static InitBitmapInfo(BITMAPINFO &bi, const int bytes_per_pixel, const int width, const int height)
{
	ZeroMemory(&bi, sizeof(bi));
	bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bi.bmiHeader.biWidth = width;
	bi.bmiHeader.biHeight = height;
	bi.bmiHeader.biPlanes = 1;
	bi.bmiHeader.biBitCount = bytes_per_pixel * 8;
	int	cClrBits = bytes_per_pixel * 8;
	if (cClrBits < 24) 	bi.bmiHeader.biClrUsed = (1<<cClrBits);
	bi.bmiHeader.biCompression = BI_RGB;
	bi.bmiHeader.biSizeImage = ((bi.bmiHeader.biWidth * cClrBits + 31) & ~31) / 8 * bi.bmiHeader.biHeight;
	bi.bmiHeader.biClrImportant = 0;
}

static BOOL GetBmpBits(HBITMAP hBmp, const int bytes_per_pixel, const int width, const int height, LPVOID pBits, const size_t size) 
{
	HDC				hdc = ::GetDC(NULL);
	BITMAPINFO		bi;
	BOOL			bResult;

	if (bytes_per_pixel > 4)
	{
		Debug("GetBmpBits: bytes_per_pixel is too big.  Its bytes not bits, right?");
		::ReleaseDC(NULL, hdc);
		return FALSE;
	}
	
	InitBitmapInfo(bi, bytes_per_pixel, width, height);

	if (size < bi.bmiHeader.biSizeImage)
	{
		// Supplied buffer is too small
		::ReleaseDC(NULL, hdc);
		return FALSE;
	}

	bResult = GetDIBits(
		hdc,           // handle to DC
		hBmp,      // handle to bitmap
		0,   // first scan line to set
		height,   // number of scan lines to copy.  Negative means top-down (ie normal)
		pBits,    // array for bitmap bits
		&bi, // bitmap data buffer
		DIB_RGB_COLORS        // RGB or palette index
	);

	::ReleaseDC(NULL, hdc); 
	return bResult;
}

static BOOL SetBmpBits(HBITMAP hBmp, const int iBytesPerPixel, const int width, const int height, LPVOID pBits, const size_t size) 
{
	HDC				hdc = ::GetDC(NULL);
	BITMAPINFO		bi;
	BOOL			bResult;
	
	InitBitmapInfo(bi, iBytesPerPixel, width, height);

	if (size < bi.bmiHeader.biSizeImage)
	{
		// Supplied buffer is too small
		::ReleaseDC(NULL, hdc);
		return FALSE;
	}

	bResult = SetDIBits(
		hdc,           // handle to DC
		hBmp,      // handle to bitmap
		0,   // first scan line to set
		height,   // number of scan lines to copy
		pBits,    // array for bitmap bits
		&bi, // bitmap data buffer
		DIB_RGB_COLORS        // RGB or palette index
	);

	::ReleaseDC(NULL, hdc); 
	return bResult;
}

static void MakeToolbarBitmapTransparent(CBitmap &b)
{
	COLORREF		bg = ::GetSysColor(COLOR_3DFACE);
	RGBTRIPLE		bmp_bits[iToolbarBitmapHeight][iToolbarBitmapWidth]; // Must match the bitmap or we'll crash
	int				x, y;
	RGBTRIPLE		*pRow;
	RGBTRIPLE		*pPixel;
	RGBTRIPLE		Bg;

	Bg.rgbtRed = GetRValue(bg);
	Bg.rgbtGreen = GetGValue(bg);
	Bg.rgbtBlue = GetBValue(bg);

	GetBmpBits(b, 3, iToolbarBitmapWidth, iToolbarBitmapHeight, bmp_bits, sizeof(bmp_bits));

	// Bitmap is bottom-up.  We only need to touch the top iToolbarIconHeight lines.
	for (y = iToolbarBitmapHeight - iToolbarIconHeight; y < iToolbarBitmapHeight; y++)
	{
		pRow = (RGBTRIPLE *) &bmp_bits[y];
		for (x = 0; x < iToolbarBitmapWidth; x++)	
		{
			pPixel = &pRow[x];
			if (pPixel->rgbtRed == iGrey && pPixel->rgbtGreen == iGrey && pPixel->rgbtBlue == iGrey)
			{
				*pPixel = Bg;
			}
		}
	}

	SetBmpBits(b, 3, iToolbarBitmapWidth, iToolbarBitmapHeight, bmp_bits, sizeof(bmp_bits));
}
What this info useful to you? You can donate to say thanks

Add a comment

Sign in to add a comment
Copyright © 2008-2012, dave - Code samples on Dave's Brain is licensed under the Creative Commons Attribution 2.5 License. However other material, including English text has all rights reserved.
Advertisements: