Доброго времени суток,
Подскажите как решить следующую проблему:
В моём Namespace Extension мне надо показывать у иконок файлов различные оверлеи (напрмер, признак, что документ вычекнут).
Для этого я беру стандартную иконку файла (например ворда) и накладываю на неё свою иконку из ресурсов.
Используется модифицированный код из MS KB (
http://support.microsoft.com/kb/318876):
HICON CExtractIconImpl::CreateAlphaIcon(WORD size, HICON hIcon, HICON hIcon2)
{
HDC hMemDC;
DWORD dwWidth, dwHeight;
BITMAPV5HEADER bi;
HBITMAP hBitmap, hOldBitmap;
void *lpBits;
HICON hAlphaIcon = NULL;
dwWidth = size; // width of icon
dwHeight = size; // height of icon
ZeroMemory(&bi,sizeof(BITMAPV5HEADER));
bi.bV5Size = sizeof(BITMAPV5HEADER);
bi.bV5Width = dwWidth;
bi.bV5Height = dwHeight;
bi.bV5Planes = 1;
bi.bV5BitCount = 32;
bi.bV5Compression = BI_BITFIELDS;
// The following mask specification specifies a supported 32 BPP
// alpha format for Windows XP.
bi.bV5RedMask = 0x00FF0000;
bi.bV5GreenMask = 0x0000FF00;
bi.bV5BlueMask = 0x000000FF;
bi.bV5AlphaMask = 0xFF000000;
HDC hdc;
hdc = GetDC(NULL);
// Create the DIB section with an alpha channel.
hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS,
(void **)&lpBits, NULL, (DWORD)0);
hMemDC = CreateCompatibleDC(hdc);
int res = ReleaseDC(NULL,hdc);
// Draw icons on the DIB section.
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
res = SetBkMode(hMemDC,TRANSPARENT);
DWORD* p = (DWORD*)lpBits;
for (DWORD i = 0; i < dwHeight; ++i)
for (DWORD j = 0; j < dwHeight; ++j)
*p++ = 0x00FFFFFF;
BOOL fRes = DrawIconEx(hMemDC, 0, 0, hIcon, size, size, 0, NULL, DI_NORMAL);
fRes = DrawIconEx(hMemDC, 0, 0, hIcon2, size, size, 0, NULL, DI_NORMAL);
SelectObject(hMemDC, hOldBitmap);
fRes = DeleteDC(hMemDC);
// Create an empty mask bitmap.
HBITMAP hMonoBitmap = CreateBitmap(dwWidth,dwHeight,1,1,NULL);
ICONINFO ii;
ii.fIcon = TRUE;
ii.xHotspot = 0;
ii.yHotspot = 0;
ii.hbmMask = hMonoBitmap;
ii.hbmColor = hBitmap;
// Create the alpha icon with the alpha DIB section.
hAlphaIcon = CreateIconIndirect(&ii);
DeleteObject(hBitmap);
DeleteObject(hMonoBitmap);
return hAlphaIcon;
}
HICON'ы перед этим достаются из ресурсов так:
// иконка типа файла
res = PrivateExtractIcons(pszFile, nIconIndex, wSize, wSize,
&hIcon, &pIconId, 1, LR_CREATEDIBSECTION);
// иконка оверлея из моего модуля
HICON hOverlay = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(wOverlayResource),
IMAGE_ICON, wSize, wSize, LR_CREATEDIBSECTION);
Сначала я сделал у себя в ресурсах только 32bit иконки.
Потом выяснилось, что когда заходишь с удалённого компа моя оверлейная иконка забивает иконку типа,
т.е. вместо того чтобы показываться поверх иконки типа — показывается на белом фоне.
Я выяснил, что это происходило из-за того, что при таком подключении использовались 8bit иконки (для иконки типа), а у меня таких не было.
После добавления к моим ресурсам нужных 8bit форматов (и попутного гемора с маской) все начало работать нормально и с удалённого компа.
Но тут подкрался он самый

.
Если в качестве иконки типа используется иконка у которой нет 32bit формата (например первая иконка shell32.dll — там только 8 и 4 битные форматы) опять те же грабли — моя иконка на белом фоне.
Т.е. я так понимаю что когда делаешь DrawIconEx 8bit иконки с маской, а потом 32bit иконки с альфой — происходит какой-то косяк с прозрачностью.
(наоборот, кстати, работает — я вижу свои торчащие иконки из-под иконки типа файла)
Подскажите, может есть другой способ или глюк в коде какой?
Я даже руками согласен эти прозрачности окучивать, так не могу найти как получить из HBITMAP значения альфы

— что GetPixel, что GetDIBits возвращают 0x00 для альфы