Index: dll/win32/comctl32/imagelist.c =================================================================== --- dll/win32/comctl32/imagelist.c (revision 67187) +++ dll/win32/comctl32/imagelist.c (working copy) @@ -33,7 +33,7 @@ * * TODO: * - Add support for ILD_PRESERVEALPHA, ILD_SCALE, ILD_DPISCALE - * - Add support for ILS_GLOW, ILS_SHADOW + * - Add support for ILS_SHADOW * - Thread-safe locking */ @@ -1393,6 +1393,76 @@ return hdc; } +HDC glow_image( HIMAGELIST himl, HDC dest_dc, int dest_x, int dest_y, + int src_x, int src_y, int cx, int cy, COLORREF rgbFg) +{ + HDC hdc = NULL; + HBITMAP bmp = 0; + BITMAPINFO *info; + + unsigned int *ptr; + void *bits; + int i; + int bR, bG, bB; + int brightValue = 50; + + /* create a dc and its device independent bitmap for doing the work, + shamelessly copied from the alpha-blending function above */ + if (!(hdc = CreateCompatibleDC( 0 ))) return FALSE; + if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) goto done; + info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + info->bmiHeader.biWidth = cx; + info->bmiHeader.biHeight = cy; + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = 32; + info->bmiHeader.biCompression = BI_RGB; + info->bmiHeader.biSizeImage = cx * cy * 4; + info->bmiHeader.biXPelsPerMeter = 0; + info->bmiHeader.biYPelsPerMeter = 0; + info->bmiHeader.biClrUsed = 0; + info->bmiHeader.biClrImportant = 0; + if (!(bmp = CreateDIBSection(himl->hdcImage, info, DIB_RGB_COLORS, &bits, 0, 0 ))) goto done; + + /* bind both surfaces */ + SelectObject(hdc, bmp); + + /* copy into our dc the section that covers just the icon we we're asked for */ + BitBlt(hdc, 0, 0, cx, cy, himl->hdcImage, src_x, src_y, SRCCOPY); + + /* loop every pixel of the bitmap */ + for (i = 0, ptr = bits; i < cx * cy; i++, ptr++) + { + COLORREF orig_color = *ptr; + + bR = GetRValue(orig_color) + brightValue; + bG = GetGValue(orig_color) + brightValue; + bB = GetBValue(orig_color) + brightValue; + + /* Make sure the color values stay within range */ + if (bR < 0) bR = 1; + else if (bR > 255) bR = 255; + + if (bG < 0) bG = 1; + else if (bG > 255) bG = 255; + + if (bB < 0) bB = 1; + else if (bB > 255) bB = 255; + + *ptr = RGBA(bR, bG, bB, GetAValue(orig_color)); + } + +done: + + if (bmp) + DeleteObject(bmp); + + if (info) + HeapFree(GetProcessHeap(), 0, info); + + /* return the handle to our glowing dc, that will substitute its original counterpart in the next calls */ + return hdc; +} + /************************************************************************* * ImageList_DrawIndirect [COMCTL32.@] * @@ -1484,6 +1554,17 @@ pt.y = 0; } + if (fState & ILS_GLOW) + { + hImageListDC = glow_image(himl, pimldp->hdcDst, pimldp->x, pimldp->y, + pt.x, pt.y, cx, cy, pimldp->rgbFg); + + /* shitty way of getting subroutines to blit at the right place (top left corner), + as our modified imagelist only contains a single image for performance reasons */ + pt.x = 0; + pt.y = 0; + } + has_alpha = (himl->has_alpha && himl->has_alpha[pimldp->i]); if (!bMask && (has_alpha || (fState & ILS_ALPHA))) { @@ -1608,7 +1689,6 @@ } } - if (fState & ILS_GLOW) FIXME("ILS_GLOW: unimplemented!\n"); if (fState & ILS_SHADOW) FIXME("ILS_SHADOW: unimplemented!\n"); if (fStyle & ILD_PRESERVEALPHA) FIXME("ILD_PRESERVEALPHA: unimplemented!\n"); Index: dll/win32/comctl32/toolbar.c =================================================================== --- dll/win32/comctl32/toolbar.c (revision 67187) +++ dll/win32/comctl32/toolbar.c (working copy) @@ -696,7 +696,7 @@ const NMTBCUSTOMDRAW *tbcd, DWORD dwItemCDFlag) { HIMAGELIST himl = NULL; - BOOL draw_masked = FALSE, draw_desaturated = FALSE; + BOOL draw_masked = FALSE, draw_desaturated = FALSE, draw_glow = FALSE; INT index; INT offset = 0; UINT draw_flags = ILD_TRANSPARENT; @@ -731,7 +731,15 @@ use default image list */ himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_HOT, &index); if (!himl) + { himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT, &index); + + ImageList_GetImageInfo(himl, index, &info); + GetObjectW(info.hbmImage, sizeof(bm), &bm); + + if (bm.bmBitsPixel == 32) + draw_glow = TRUE; + } } else himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT, &index); @@ -755,6 +763,25 @@ /* code path for drawing flat disabled icons without alpha channel */ TOOLBAR_DrawMasked (himl, index, tbcd->nmcd.hdc, left + offset, top + offset, draw_flags); } + else if (draw_glow) + { + /* code path for drawing hot, alpha-blended (32bpp) icons */ + IMAGELISTDRAWPARAMS imldp = {0}; + + imldp.cbSize = sizeof(imldp); + imldp.himl = himl; + imldp.i = index; + imldp.hdcDst = tbcd->nmcd.hdc, + imldp.x = offset + left; + imldp.y = offset + top; + imldp.rgbBk = CLR_NONE; + imldp.rgbFg = CLR_DEFAULT; + imldp.fStyle = ILD_TRANSPARENT; + imldp.fState = ILS_ALPHA | ILS_GLOW; + imldp.Frame = 192; + + ImageList_DrawIndirect (&imldp); + } else if (draw_desaturated) { /* code path for drawing disabled, alpha-blended (32bpp) icons */