45#include "commoncontrols.h"
52#define MAX_OVERLAYIMAGE 15
62#define ImageList_Add Internal_Add
63#define ImageList_ReplaceIcon Internal_ReplaceIcon
64#define ImageList_SetOverlayImage Internal_SetOverlayImage
65#define ImageList_Replace Internal_Replace
66#define ImageList_AddMasked Internal_AddMasked
67#define ImageList_Remove Internal_Remove
68#define ImageList_GetIcon Internal_GetIcon
69#define ImageList_GetImageInfo Internal_GetImageInfo
70#define ImageList_Copy Internal_Copy
71#define ImageList_Merge Internal_Merge
72#define ImageList_Duplicate Internal_Duplicate
73#define ImageList_GetIconSize Internal_GetIconSize
74#define ImageList_SetIconSize Internal_SetIconSize
75#define ImageList_GetImageCount Internal_GetImageCount
76#define ImageList_SetImageCount Internal_SetImageCount
77#define ImageList_SetBkColor Internal_SetBkColor
78#define ImageList_GetBkColor Internal_GetBkColor
79#define ImageList_BeginDrag Internal_BeginDrag
80#define ImageList_DrawIndirect Internal_DrawIndirect
120#define IMAGELIST_MAGIC 0x53414D58
122#define IMAGELIST_MAGIC_DESTROYED 0x44454144
123#define IMAGELIST_VERSION 0x101
125#define WinVerMajor() LOBYTE(GetVersion())
128#define ILC_PUBLICFLAGS ( 0xFFFFFFFF )
129#define ILC_COLORMASK 0xFE
210 return ((
width *
bpp + 31) >> 3) & ~3;
216 *
abs(
info->bmiHeader.biHeight );
250 int mask_stride = (
info->bmiHeader.biWidth + 31) / 32 * 4;
259 for (
i = 0;
i <
height && !has_alpha;
i++)
261 if ((has_alpha = ((
bits[
i *
stride +
j] & 0xff000000) != 0)))
break;
267 if (!mask_info || !((mask_bits[
i * mask_stride +
j / 8] << (
j % 8)) & 0x80))
281 mask_bits[
i * mask_stride +
j / 8] &= ~(0x80 >> (
j % 8));
283 mask_bits[
i * mask_stride +
j / 8] |= 0x80 >> (
j % 8);
309 if (bm.bmBitsPixel != 32)
return FALSE;
312 mask_width = (bm.bmWidth + 31) / 32 * 4;
316 info->bmiHeader.biWidth = bm.bmWidth;
318 info->bmiHeader.biPlanes = 1;
319 info->bmiHeader.biBitCount = 32;
321 info->bmiHeader.biSizeImage = bm.bmWidth *
height * 4;
322 info->bmiHeader.biXPelsPerMeter = 0;
323 info->bmiHeader.biYPelsPerMeter = 0;
324 info->bmiHeader.biClrUsed = 0;
325 info->bmiHeader.biClrImportant = 0;
387 TRACE(
"Create expanded bitmaps : himl=%p x=%d y=%d count=%d\n",
himl, sz.
cx, sz.
cy, nNewCount);
392 if (hbmNewBitmap == 0)
393 ERR(
"creating new image bitmap (x=%d y=%d)!\n", sz.
cx, sz.
cy);
410 if (hbmNewBitmap == 0)
411 ERR(
"creating new mask bitmap!\n");
461 INT nFirstIndex, nImageCount,
i;
465 TRACE(
"himl=%p hbmimage=%p hbmmask=%p\n",
himl, hbmImage, hbmMask);
472 TRACE(
"himl %p, cCurImage %d, cMaxImage %d, cGrow %d, cx %d, cy %d\n",
477 TRACE(
"%p has %d images (%d x %d) bpp %d\n", hbmImage, nImageCount,
bmp.bmWidth,
bmp.bmHeight,
504 for (
i=0;
i<nImageCount;
i++)
549#undef ImageList_AddIcon
614 if (
bmp.bmBitsPixel > 8)
649 INT dxHotspot,
INT dyHotspot)
654 TRACE(
"(himlTrack=%p iTrack=%d dx=%d dy=%d)\n", himlTrack, iTrack,
655 dxHotspot, dyHotspot);
671 WARN(
"Error creating drag image list!\n");
721 TRACE(
"himlDst=%p iDst=%d himlSrc=%p iSrc=%d\n", himlDst, iDst, himlSrc, iSrc);
725 if ((iDst < 0) || (iDst >= himlDst->
cCurImage))
727 if ((iSrc < 0) || (iSrc >= himlSrc->
cCurImage))
736 HBITMAP hbmTempImage, hbmTempMask;
755 himlDst->
hdcMask, ptDst.
x, ptDst.
y, himlDst->
cx, himlDst->
cy,
765 himlSrc->
hdcMask, ptSrc.
x, ptSrc.
y, himlSrc->
cx, himlSrc->
cy,
789 himlSrc->
hdcMask, ptSrc.
x, ptSrc.
y, himlSrc->
cx, himlSrc->
cy,
821 static const WORD aBitBlend25[] =
822 {0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
824 static const WORD aBitBlend50[] =
825 {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
836 cGrow = (
WORD)((
max( cGrow, 1 ) + 3) & ~3);
841 WARN(
"grow %d too large, limiting to 256\n", cGrow );
896 ERR(
"Error creating mask bitmap!\n");
978 TRACE(
"(hwnd=%p x=%d y=%d)\n", hwndLock,
x,
y);
1021 FIXME(
"DragLeave hWnd != DragEnter hWnd\n");
1055 imldp.
cbSize =
sizeof(imldp);
1101 INT origNewX, origNewY;
1102 INT origOldX, origOldY;
1103 INT origRegX, origRegY;
1104 INT sizeRegX, sizeRegY;
1112 origRegX =
min(origNewX, origOldX);
1113 origRegY =
min(origNewY, origOldY);
1127 BitBlt(hdcOffScreen, 0, 0, sizeRegX, sizeRegY, hdcDrag,
1130 BitBlt(hdcOffScreen, origOldX - origRegX, origOldY - origRegY,
1135 hdcOffScreen, origNewX - origRegX, origNewY - origRegY,
SRCCOPY);
1138 origNewY - origRegY);
1140 BitBlt(hdcDrag, origRegX, origRegY, sizeRegX, sizeRegY,
1180 TRACE(
"bShow=0x%X!\n", bShow);
1289 imldp.
cbSize =
sizeof(imldp);
1297 imldp.
rgbBk = rgbBk;
1298 imldp.
rgbFg = rgbFg;
1316 void *
bits, *mask_bits;
1323 info->bmiHeader.biWidth =
cx;
1324 info->bmiHeader.biHeight =
cy;
1325 info->bmiHeader.biPlanes = 1;
1326 info->bmiHeader.biBitCount = 32;
1328 info->bmiHeader.biSizeImage =
cx *
cy * 4;
1329 info->bmiHeader.biXPelsPerMeter = 0;
1330 info->bmiHeader.biYPelsPerMeter = 0;
1331 info->bmiHeader.biClrUsed = 0;
1332 info->bmiHeader.biClrImportant = 0;
1342 TRACE(
"BitBlt failed\n");
1358 *
ptr = ((*
ptr & 0xff000000) |
1359 ((((*
ptr & 0x00ff0000) * 3 + (
r << 16)) / 4) & 0x00ff0000) |
1360 ((((*
ptr & 0x0000ff00) * 3 + (
g << 8)) / 4) & 0x0000ff00) |
1361 ((((*
ptr & 0x000000ff) * 3 + (
b << 0)) / 4) & 0x000000ff));
1366 *
ptr = ((*
ptr & 0xff000000) |
1367 ((((*
ptr & 0x00ff0000) + (
r << 16)) / 2) & 0x00ff0000) |
1368 ((((*
ptr & 0x0000ff00) + (
g << 8)) / 2) & 0x0000ff00) |
1369 ((((*
ptr & 0x000000ff) + (
b << 0)) / 2) & 0x000000ff));
1379 *
ptr = ((*
ptr & 0xff000000) |
1380 (((*
ptr & 0x00ff0000) *
alpha / 255) & 0x00ff0000) |
1381 (((*
ptr & 0x0000ff00) *
alpha / 255) & 0x0000ff00) |
1382 (((*
ptr & 0x000000ff) *
alpha / 255)));
1389 info->bmiHeader.biBitCount = 1;
1391 info->bmiColors[0].rgbRed = 0;
1392 info->bmiColors[0].rgbGreen = 0;
1393 info->bmiColors[0].rgbBlue = 0;
1394 info->bmiColors[0].rgbReserved = 0;
1395 info->bmiColors[1].rgbRed = 0xff;
1396 info->bmiColors[1].rgbGreen = 0xff;
1397 info->bmiColors[1].rgbBlue = 0xff;
1398 info->bmiColors[1].rgbReserved = 0;
1424 else *
ptr |= 0xff000000;
1427 ret =
GdiAlphaBlend( dest_dc, dest_x, dest_y,
cx,
cy,
hdc, 0, 0,
cx,
cy,
func );
1440 HDC *hdcImageListDC,
HDC *hdcMaskListDC)
1455 info->bmiHeader.biWidth =
cx;
1456 info->bmiHeader.biHeight =
cy;
1457 info->bmiHeader.biPlanes = 1;
1458 info->bmiHeader.biBitCount = 32;
1460 info->bmiHeader.biSizeImage =
cx *
cy * 4;
1461 info->bmiHeader.biXPelsPerMeter = 0;
1462 info->bmiHeader.biYPelsPerMeter = 0;
1463 info->bmiHeader.biClrUsed = 0;
1464 info->bmiHeader.biClrImportant = 0;
1470 TRACE(
"SelectObject failed\n");
1477 TRACE(
"BitBlt failed!\n");
1488 float mixed_color = (
GetRValue(orig_color) * .30 +
1523 *hdcMaskListDC = hdcMask;
1524 *hdcImageListDC =
hdc;
1546 DWORD fState, dwRop;
1549 HDC hImageDC, hImageListDC, hMaskListDC;
1550 HBITMAP hImageBmp, hOldImageBmp, hBlendMaskBmp;
1551 BOOL bIsTransparent, bBlend, bResult =
FALSE, bMask;
1575 bIsTransparent =
TRUE;
1577 bIsTransparent =
TRUE;
1581 TRACE(
"himl(%p) hbmMask(%p) iImage(%d) x(%d) y(%d) cx(%d) cy(%d)\n",
1594 if (!hImageListDC || !hImageDC || !hImageBmp ||
1595 (bBlend && !hBlendMaskBmp) || (
himl->
hbmMask && !hMaskListDC))
1606 oldImageBk =
SetBkColor( hImageDC,
RGB( 0xff, 0xff, 0xff ) );
1615 if (saturate_image(
himl, pimldp->
hdcDst, pimldp->
x, pimldp->
y,
1617 &hdcSaturated, &hdcSaturatedMask))
1619 hImageListDC = hdcSaturated;
1620 hMaskListDC = hdcSaturatedMask;
1630 if (!bMask && (has_alpha || (fState &
ILS_ALPHA)))
1637 blend_col = pimldp->
rgbFg;
1643 func.BlendFlags = 0;
1657 colour = pimldp->
rgbBk;
1664 alpha_blend_image(
himl, hImageListDC, hMaskListDC, hImageDC, 0, 0,
pt.x,
pt.y,
cx,
cy,
func, fStyle, blend_col );
1666 alpha_blend_image(
himl, hImageDC, 0, 0,
pt.x,
pt.y,
cx,
cy,
func, fStyle, blend_col );
1682 if( bIsTransparent )
1697 if( !bIsTransparent )
1699 colour = pimldp->
rgbBk;
1722 HDC hBlendMaskDC = hImageListDC;
1726 hOldBitmap =
SelectObject(hBlendMaskDC, hBlendMaskBmp);
1734 BitBlt(hBlendMaskDC, 0, 0,
cx,
cy, hMaskListDC,
pt.x,
pt.y, 0x220326);
1742 BitBlt (hImageDC, 0, 0,
cx,
cy, hBlendMaskDC, 0, 0, 0xB8074A);
1794 if (hdcSaturatedMask)
1824 ERR(
"Invalid image list handle!\n");
1956 if(!is_valid2(
himl))
2235 WARN(
"Couldn't load image\n");
2255 cx =
dib.dsBm.bmHeight;
2258 nImageCount =
dib.dsBm.bmWidth /
cx;
2323 INT xOff1, yOff1, xOff2, yOff2;
2327 TRACE(
"(himl1=%p i1=%d himl2=%p i2=%d dx=%d dy=%d)\n", himl1, i1, himl2,
2334 cxDst =
max (himl1->
cx,
dx + himl2->
cx);
2339 cxDst =
max (himl2->
cx, himl1->
cx -
dx);
2344 cxDst =
max (himl1->
cx, himl2->
cx);
2350 cyDst =
max (himl1->
cy,
dy + himl2->
cy);
2355 cyDst =
max (himl2->
cy, himl1->
cy -
dy);
2360 cyDst =
max (himl1->
cy, himl2->
cy);
2377 if (i1 >= 0 && i1 < himl1->cCurImage)
2379 if (i2 >= 0 && i2 < himl2->cCurImage)
2392 if (i1 >= 0 && i1 < himl1->cCurImage)
2394 if (i2 >= 0 && i2 < himl2->cCurImage)
2408 int bitsperpixel, palspace;
2411 if (
FAILED(IStream_Read ( pstm, &bmfh,
sizeof(bmfh),
NULL)))
2414 if (bmfh.
bfType != ((
'M'<<8)|
'B'))
2423 TRACE(
"width %u, height %u, planes %u, bpp %u\n",
2428 if (bitsperpixel<=8)
2429 palspace = (1<<bitsperpixel)*
sizeof(
RGBQUAD);
2487 void *image_bits, *mask_bits =
NULL;
2492 TRACE(
"%p\n", pstm);
2496 if (ilHead.
usMagic != ((
'L' << 8) |
'I'))
2499 if (ilHead.
usVersion != IMAGELIST_VERSION &&
2507 TRACE(
"cx %u, cy %u, flags 0x%04x, cCurImage %u, cMaxImage %u\n",
2519 if (!(image_bits =
read_bitmap(pstm, image_info)))
2521 WARN(
"failed to read bitmap from stream\n");
2528 WARN(
"failed to read mask bitmap from stream\n");
2532 else mask_info =
NULL;
2537 BYTE *mask_ptr = mask_bits;
2541 int mask_step = ilHead.
usVersion != IMAGELIST_VERSION ? 4 : 8;
2563 mask_ptr +=
stride / mask_step;
2617 HBITMAP hbmNewImage, hbmNewMask;
2624 ERR(
"Invalid image list handle!\n");
2629 TRACE(
"index out of range! %d\n",
i);
2639 TRACE(
"remove all on empty ImageList!\n");
2670 TRACE(
"Remove single image! %d\n",
i);
2673 TRACE(
" - Number of images: %d / %d (Old/New)\n",
2688 TRACE(
"Pre image copy: Copy %d images\n",
i);
2700 if (i < himl->cCurImage - 1) {
2701 TRACE(
"Post image copy!\n");
2757 TRACE(
"%p %d %p %p\n",
himl,
i, hbmImage, hbmMask);
2760 ERR(
"Invalid image list handle!\n");
2765 ERR(
"Invalid image index!\n");
2837 ERR(
"invalid image list\n");
2976 INT dxHotspot,
INT dyHotspot)
2984 TRACE(
" dxH=%d dyH=%d nX=%d nY=%d\n",
2990 dxHotspot, dyHotspot);
3039 FIXME(
"(%p 0x%x 0x%x):empty stub!\n",
himl,
i, dwFilter);
3081 if (
flags & ~ILC_PUBLICFLAGS)
3091 return ChangeColorDepth(
himl);
3174 INT nNewCount, nCopyCount;
3181 nNewCount = iImageCount + 1;
3188 if (hbmNewBitmap != 0)
3201 ERR(
"Could not create new image bitmap!\n");
3208 if (hbmNewBitmap != 0)
3221 ERR(
"Could not create new mask bitmap!\n");
3267 if ((iImage!=-1) && ((iImage < 0) || (iImage >
himl->
cCurImage)))
3284 INT bitCount, sizeImage, offBits, totalSize;
3291 bitCount = bm.bmBitsPixel;
3296 totalSize += (1 << bitCount) *
sizeof(
RGBQUAD);
3297 offBits = totalSize;
3298 totalSize += sizeImage;
3300 data = heap_alloc_zero(totalSize);
3303 lpBits =
data + offBits;
3306 bmfh->
bfType = ((
'M' << 8) |
'B');
3331 TRACE(
"width %u, height %u, planes %u, bpp %u\n",
3374 ilHead.
usMagic = ((
'L' << 8) |
'I');
3383 for(
i = 0;
i < 4;
i++) {
3387 TRACE(
"cx %u, cy %u, flags 0x04%x, cCurImage %u, cMaxImage %u\n",
3420 TRACE(
"Creating DIBSection %d x %d, %d Bits per Pixel\n",
3460 TRACE(
"returning %p\n", hbmNewBitmap);
3461 return hbmNewBitmap;
3487 if(!is_valid2(
himl))
3547 IImageList2_AddRef(iface);
3556 TRACE(
"(%p) refcount=%u\n", iface,
ref);
3565 TRACE(
"(%p) refcount=%u\n", iface,
ref);
3582 This->usMagic = IMAGELIST_MAGIC_DESTROYED;
3584 This->IImageList2_iface.lpVtbl =
NULL;
3629 int iImage,
int iOverlay)
3669 old_himl = pimldp->
himl;
3670 pimldp->
himl = imgl;
3674 pimldp->
himl = old_himl;
3726 if (
FAILED(IUnknown_QueryInterface(unk_src, &IID_IImageList,
3735 IImageList_Release(
src);
3756 if (
FAILED(IUnknown_QueryInterface(punk2, &IID_IImageList,
3769 IImageList_Release(iml2);
3853 int dxHotspot,
int dyHotspot)
3882 IUnknown *punk,
int iDrag,
int dxHotspot,
int dyHotspot)
3891 if (
FAILED(IUnknown_QueryInterface(punk, &IID_IImageList,
3898 IImageList_Release(iml2);