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