I have a 24 bpp bitmap that contains several 16x16 subpictures. The resource ID of the bitmap is IDB_TRAYICONS. I'd like to extract one of them and show it as a tray icon. My problem is that the icon created by CreateIconIndirect doesn't have a transparency mask even if I create it directly and set the hbmMask member of the ICONINFO struct. What did I do wrong?
void showTrayIcon(HINSTANCE hInst, HWND hwnd, const wchar_t *title) {
NOTIFYICONDATA ni;
memset(&ni, 0, sizeof(ni));
ni.cbSize = sizeof(ni);
ni.hWnd = hwnd;
wcscpy_s(ni.szTip, sizeof(ni.szTip) / sizeof(*ni.szTip), title);
ni.uCallbackMessage = WM_USER+1;
ni.uFlags = NIF_MESSAGE + NIF_ICON + NIF_TIP;
ni.uID = 1;
HBITMAP icons = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_TRAYIC
ONS));
BITMAP iconsHeader;
GetObject(icons, sizeof(iconsHeader), &iconsHeader);
HDC hdcIcons = CreateCompatibleDC(GetDC(0
));
SelectObject(hdcIcons, icons);
// extract icon image (test: 16x16 icon at top left)
HBITMAP iconImage = CreateBitmap(16, 16, 1, iconsHeader.bmBitsPixel, NULL);
HDC hdcIconImage = CreateCompatibleDC(hdcIcon
s);
SelectObject(hdcIconImage,
iconImage);
BitBlt(hdcIconImage, 0, 0, 16, 16, hdcIcons, 0, 0, SRCCOPY);
// create icon mask (test: checkerboard pattern)
HBITMAP iconMask = CreateBitmap(16, 16, 1, 1, NULL);
HDC hdcIconMask = CreateCompatibleDC(hdcIcon
s);
SelectObject(hdcIconMask, iconMask);
for (int i=0; i<16; i++)
for (int j=0; j<16; j++)
SetPixel(hdcIconMask, i, j, (i+j)%2 ? 0xFFFFFF : 0);
// create icon
ICONINFO ii;
ii.fIcon = true;
ii.hbmColor = iconImage;
ii.hbmMask = iconMask;
ii.xHotspot = 0;
ii.yHotspot = 0;
ni.hIcon = CreateIconIndirect(&ii);
Shell_NotifyIcon(NIM_ADD, &ni);
DeleteDC(hdcIcons);
DeleteDC(hdcIconImage);
DeleteDC(hdcIconMask);
DeleteObject(icons);
DeleteObject(iconImage);
DeleteObject(iconMask);
DestroyIcon(ni.hIcon);
}
Start Free Trial