此代码适用于32位系统颜色(Windows 7), 但它不适用于16位颜色 - 菜单位图不透明!!!:
...
HBITMAP rv = rgb(hsrc, 16);
...
HBITMAP rgb(HBITMAP hsrc, WORD wBitsPixel) {
HBITMAP hold = NULL;
HDC hdcsrc = NULL, hdc = NULL;
BITMAP bmp = {0};
HBITMAP dib = NULL;
UCHAR *dst = NULL, *src = NULL, *tmp = NULL;
UCHAR alpha;
int bpl;
ULONG x, y;
DWORD bmp_size = 0;
HANDLE hdib = NULL;
char *lpbitmap = NULL;
int rv = 0;
hdc = GetDC(m_hMainDlg);
hdcsrc = CreateCompatibleDC(hdc);
hold = (HBITMAP)SelectObject(hdcsrc, hsrc);
rv = GetObject(hsrc, sizeof(BITMAP), &bmp);
BITMAPINFOHEADER bi = {0};
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmp.bmWidth;;
bi.biHeight = bmp.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitsPixel;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
bmp_size = ((bmp.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmp.bmHeight;
hdib = GlobalAlloc(GHND, bmp_size);
lpbitmap = (char *)GlobalLock(hdib);
/* Get bits of source bitmap. */
GetDIBits(hdcsrc, hsrc, 0, bmp.bmHeight, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS);
/* For destination bitmap */
BITMAPINFO bmi = {0};
bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
bmi.bmiHeader.biWidth = bmp.bmWidth;
bmi.bmiHeader.biHeight = bmp.bmHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = wBitsPixel;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
dib = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **)&dst, NULL, 0);
bpl = 4 * bmp.bmWidth; /* bytes per line */
src = (UCHAR *)lpbitmap;
for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
tmp = src;
for (x = 0; x < bmp.bmWidth; x++) {
alpha = tmp[3];
dst[0] = tmp[0] * alpha / 255;
dst[1] = tmp[1] * alpha / 255;
dst[2] = tmp[2] * alpha / 255;
dst[3] = alpha;
dst += 4;
tmp += 4;
}
}
// free resources
ReleaseDC(m_hMainDlg, hdc);
SelectObject(hdcsrc, hold);
DeleteDC(hdcsrc);
GlobalUnlock(hdib);
GlobalFree(hdib);
return dib;
}