Introduction
This article shows how the GDI function AlphaBlend is used to display and overlay 32 bit bitmaps with an alpha channel. It is mainly a hint, which would have saved me hours of research.
Background
The code and the idea of this article comes from a setup bootstrapper project. I want to be able to compose background images for wizard pages from 32 bit bitmaps with alpha transparency. That should save space as described in MSE-iT Setup Bootstrapper - Background Bitmap Resources.
Code Snippet
BITMAP bm;
GetObject(background, sizeof(BITMAP), &bm);
AlphaBlend(hdcMemWork, 0,0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0,
bm.bmWidth, bm.bmHeight, blendFkt)
SelectObject(hdcMem, hbmOld);
if(bmInfo.bmiHeader.biBitCount == 32 )
{
for (int y=0; y<bmInfo.bmiHeader.biHeight; ++y)
{
BYTE *pPixel= (BYTE *) lpDIBBits + bmInfo.bmiHeader.biWidth * 4 * y;
for (int x=0; x<bmInfo.bmiHeader.biWidth ; ++x)
{
pPixel[0]= pPixel[0]*pPixel[3]/255;
pPixel[1]= pPixel[1]*pPixel[3]/255;
pPixel[2]= pPixel[2]*pPixel[3]/255;
pPixel+= 4;
}
}
}
Points of interest
I played around a long time until AlphaBlend began working. At least the trick was to pre multiply the color values of the bitmap with the alpha value. Then, everything worked fine. Be careful with the width and height you provide to AlphaBlend(). If this exceeds the bounds of the bitmap, nothing is displayed. I prefer getting the width and height directly out of the bitmap data as shown.
Alpha blending effect
This is the empty background image of the bootstrapper wizard:

This is the left side image to blend over the background (transparency is black):

After adding additional images for localization, this is the resulting page:

Source code and working sample
You can check out the source code and the working sample in the original bootstrapper project: MSE-iT Setup Bootstrapper Project on CodePlex.