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
117#define IMAGELIST_MAGIC 0x53414D58
119#define IMAGELIST_MAGIC_DESTROYED 0x44454144
200 return ((
width *
bpp + 31) >> 3) & ~3;
206 *
abs(
info->bmiHeader.biHeight );
240 int mask_stride = (
info->bmiHeader.biWidth + 31) / 32 * 4;
249 for (
i = 0;
i <
height && !has_alpha;
i++)
251 if ((has_alpha = ((
bits[
i *
stride +
j] & 0xff000000) != 0)))
break;
257 if (!mask_info || !((mask_bits[
i * mask_stride +
j / 8] << (
j % 8)) & 0x80))
271 mask_bits[
i * mask_stride +
j / 8] &= ~(0x80 >> (
j % 8));
273 mask_bits[
i * mask_stride +
j / 8] |= 0x80 >> (
j % 8);
299 if (bm.bmBitsPixel != 32)
return FALSE;
302 mask_width = (bm.bmWidth + 31) / 32 * 4;
306 info->bmiHeader.biWidth = bm.bmWidth;
308 info->bmiHeader.biPlanes = 1;
309 info->bmiHeader.biBitCount = 32;
311 info->bmiHeader.biSizeImage = bm.bmWidth *
height * 4;
312 info->bmiHeader.biXPelsPerMeter = 0;
313 info->bmiHeader.biYPelsPerMeter = 0;
314 info->bmiHeader.biClrUsed = 0;
315 info->bmiHeader.biClrImportant = 0;
377 TRACE(
"Create expanded bitmaps : himl=%p x=%d y=%d count=%d\n",
himl, sz.
cx, sz.
cy, nNewCount);
382 if (hbmNewBitmap == 0)
383 ERR(
"creating new image bitmap (x=%d y=%d)!\n", sz.
cx, sz.
cy);
400 if (hbmNewBitmap == 0)
401 ERR(
"creating new mask bitmap!\n");
451 INT nFirstIndex, nImageCount,
i;
455 TRACE(
"himl=%p hbmimage=%p hbmmask=%p\n",
himl, hbmImage, hbmMask);
462 TRACE(
"himl %p, cCurImage %d, cMaxImage %d, cGrow %d, cx %d, cy %d\n",
467 TRACE(
"%p has %d images (%d x %d) bpp %d\n", hbmImage, nImageCount,
bmp.bmWidth,
bmp.bmHeight,
494 for (
i=0;
i<nImageCount;
i++)
539#undef ImageList_AddIcon
604 if (
bmp.bmBitsPixel > 8)
639 INT dxHotspot,
INT dyHotspot)
644 TRACE(
"(himlTrack=%p iTrack=%d dx=%d dy=%d)\n", himlTrack, iTrack,
645 dxHotspot, dyHotspot);
661 WARN(
"Error creating drag image list!\n");
711 TRACE(
"himlDst=%p iDst=%d himlSrc=%p iSrc=%d\n", himlDst, iDst, himlSrc, iSrc);
715 if ((iDst < 0) || (iDst >= himlDst->
cCurImage))
717 if ((iSrc < 0) || (iSrc >= himlSrc->
cCurImage))
726 HBITMAP hbmTempImage, hbmTempMask;
745 himlDst->
hdcMask, ptDst.
x, ptDst.
y, himlDst->
cx, himlDst->
cy,
755 himlSrc->
hdcMask, ptSrc.
x, ptSrc.
y, himlSrc->
cx, himlSrc->
cy,
779 himlSrc->
hdcMask, ptSrc.
x, ptSrc.
y, himlSrc->
cx, himlSrc->
cy,
811 static const WORD aBitBlend25[] =
812 {0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
814 static const WORD aBitBlend50[] =
815 {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
826 cGrow = (
WORD)((
max( cGrow, 1 ) + 3) & ~3);
831 WARN(
"grow %d too large, limiting to 256\n", cGrow );
883 ERR(
"Error creating mask bitmap!\n");
960 TRACE(
"(hwnd=%p x=%d y=%d)\n", hwndLock,
x,
y);
1003 FIXME(
"DragLeave hWnd != DragEnter hWnd\n");
1037 imldp.
cbSize =
sizeof(imldp);
1083 INT origNewX, origNewY;
1084 INT origOldX, origOldY;
1085 INT origRegX, origRegY;
1086 INT sizeRegX, sizeRegY;
1094 origRegX =
min(origNewX, origOldX);
1095 origRegY =
min(origNewY, origOldY);
1109 BitBlt(hdcOffScreen, 0, 0, sizeRegX, sizeRegY, hdcDrag,
1112 BitBlt(hdcOffScreen, origOldX - origRegX, origOldY - origRegY,
1117 hdcOffScreen, origNewX - origRegX, origNewY - origRegY,
SRCCOPY);
1120 origNewY - origRegY);
1122 BitBlt(hdcDrag, origRegX, origRegY, sizeRegX, sizeRegY,
1162 TRACE(
"bShow=0x%X!\n", bShow);
1271 imldp.
cbSize =
sizeof(imldp);
1279 imldp.
rgbBk = rgbBk;
1280 imldp.
rgbFg = rgbFg;
1298 void *
bits, *mask_bits;
1305 info->bmiHeader.biWidth =
cx;
1306 info->bmiHeader.biHeight =
cy;
1307 info->bmiHeader.biPlanes = 1;
1308 info->bmiHeader.biBitCount = 32;
1310 info->bmiHeader.biSizeImage =
cx *
cy * 4;
1311 info->bmiHeader.biXPelsPerMeter = 0;
1312 info->bmiHeader.biYPelsPerMeter = 0;
1313 info->bmiHeader.biClrUsed = 0;
1314 info->bmiHeader.biClrImportant = 0;
1324 TRACE(
"BitBlt failed\n");
1340 *
ptr = ((*
ptr & 0xff000000) |
1341 ((((*
ptr & 0x00ff0000) * 3 + (
r << 16)) / 4) & 0x00ff0000) |
1342 ((((*
ptr & 0x0000ff00) * 3 + (
g << 8)) / 4) & 0x0000ff00) |
1343 ((((*
ptr & 0x000000ff) * 3 + (
b << 0)) / 4) & 0x000000ff));
1348 *
ptr = ((*
ptr & 0xff000000) |
1349 ((((*
ptr & 0x00ff0000) + (
r << 16)) / 2) & 0x00ff0000) |
1350 ((((*
ptr & 0x0000ff00) + (
g << 8)) / 2) & 0x0000ff00) |
1351 ((((*
ptr & 0x000000ff) + (
b << 0)) / 2) & 0x000000ff));
1361 *
ptr = ((*
ptr & 0xff000000) |
1362 (((*
ptr & 0x00ff0000) *
alpha / 255) & 0x00ff0000) |
1363 (((*
ptr & 0x0000ff00) *
alpha / 255) & 0x0000ff00) |
1364 (((*
ptr & 0x000000ff) *
alpha / 255)));
1371 info->bmiHeader.biBitCount = 1;
1373 info->bmiColors[0].rgbRed = 0;
1374 info->bmiColors[0].rgbGreen = 0;
1375 info->bmiColors[0].rgbBlue = 0;
1376 info->bmiColors[0].rgbReserved = 0;
1377 info->bmiColors[1].rgbRed = 0xff;
1378 info->bmiColors[1].rgbGreen = 0xff;
1379 info->bmiColors[1].rgbBlue = 0xff;
1380 info->bmiColors[1].rgbReserved = 0;
1406 else *
ptr |= 0xff000000;
1409 ret =
GdiAlphaBlend( dest_dc, dest_x, dest_y,
cx,
cy,
hdc, 0, 0,
cx,
cy,
func );
1422 HDC *hdcImageListDC,
HDC *hdcMaskListDC)
1437 info->bmiHeader.biWidth =
cx;
1438 info->bmiHeader.biHeight =
cy;
1439 info->bmiHeader.biPlanes = 1;
1440 info->bmiHeader.biBitCount = 32;
1442 info->bmiHeader.biSizeImage =
cx *
cy * 4;
1443 info->bmiHeader.biXPelsPerMeter = 0;
1444 info->bmiHeader.biYPelsPerMeter = 0;
1445 info->bmiHeader.biClrUsed = 0;
1446 info->bmiHeader.biClrImportant = 0;
1452 TRACE(
"SelectObject failed\n");
1459 TRACE(
"BitBlt failed!\n");
1470 float mixed_color = (
GetRValue(orig_color) * .30 +
1505 *hdcMaskListDC = hdcMask;
1506 *hdcImageListDC =
hdc;
1528 DWORD fState, dwRop;
1531 HDC hImageDC, hImageListDC, hMaskListDC;
1532 HBITMAP hImageBmp, hOldImageBmp, hBlendMaskBmp;
1533 BOOL bIsTransparent, bBlend, bResult =
FALSE, bMask;
1557 bIsTransparent =
TRUE;
1559 bIsTransparent =
TRUE;
1563 TRACE(
"himl(%p) hbmMask(%p) iImage(%d) x(%d) y(%d) cx(%d) cy(%d)\n",
1576 if (!hImageListDC || !hImageDC || !hImageBmp ||
1577 (bBlend && !hBlendMaskBmp) || (
himl->
hbmMask && !hMaskListDC))
1588 oldImageBk =
SetBkColor( hImageDC,
RGB( 0xff, 0xff, 0xff ) );
1597 if (saturate_image(
himl, pimldp->
hdcDst, pimldp->
x, pimldp->
y,
1599 &hdcSaturated, &hdcSaturatedMask))
1601 hImageListDC = hdcSaturated;
1602 hMaskListDC = hdcSaturatedMask;
1612 if (!bMask && (has_alpha || (fState &
ILS_ALPHA)))
1619 blend_col = pimldp->
rgbFg;
1625 func.BlendFlags = 0;
1639 colour = pimldp->
rgbBk;
1646 alpha_blend_image(
himl, hImageListDC, hMaskListDC, hImageDC, 0, 0,
pt.x,
pt.y,
cx,
cy,
func, fStyle, blend_col );
1648 alpha_blend_image(
himl, hImageDC, 0, 0,
pt.x,
pt.y,
cx,
cy,
func, fStyle, blend_col );
1664 if( bIsTransparent )
1679 if( !bIsTransparent )
1681 colour = pimldp->
rgbBk;
1704 HDC hBlendMaskDC = hImageListDC;
1708 hOldBitmap =
SelectObject(hBlendMaskDC, hBlendMaskBmp);
1716 BitBlt(hBlendMaskDC, 0, 0,
cx,
cy, hMaskListDC,
pt.x,
pt.y, 0x220326);
1724 BitBlt (hImageDC, 0, 0,
cx,
cy, hBlendMaskDC, 0, 0, 0xB8074A);
1776 if (hdcSaturatedMask)
1806 ERR(
"Invalid image list handle!\n");
1938 if(!is_valid2(
himl))
2217 WARN(
"Couldn't load image\n");
2237 cx =
dib.dsBm.bmHeight;
2240 nImageCount =
dib.dsBm.bmWidth /
cx;
2305 INT xOff1, yOff1, xOff2, yOff2;
2309 TRACE(
"(himl1=%p i1=%d himl2=%p i2=%d dx=%d dy=%d)\n", himl1, i1, himl2,
2316 cxDst =
max (himl1->
cx,
dx + himl2->
cx);
2321 cxDst =
max (himl2->
cx, himl1->
cx -
dx);
2326 cxDst =
max (himl1->
cx, himl2->
cx);
2332 cyDst =
max (himl1->
cy,
dy + himl2->
cy);
2337 cyDst =
max (himl2->
cy, himl1->
cy -
dy);
2342 cyDst =
max (himl1->
cy, himl2->
cy);
2359 if (i1 >= 0 && i1 < himl1->cCurImage)
2361 if (i2 >= 0 && i2 < himl2->cCurImage)
2374 if (i1 >= 0 && i1 < himl1->cCurImage)
2376 if (i2 >= 0 && i2 < himl2->cCurImage)
2390 int bitsperpixel, palspace;
2393 if (
FAILED(IStream_Read ( pstm, &bmfh,
sizeof(bmfh),
NULL)))
2396 if (bmfh.
bfType != ((
'M'<<8)|
'B'))
2405 TRACE(
"width %u, height %u, planes %u, bpp %u\n",
2410 if (bitsperpixel<=8)
2411 palspace = (1<<bitsperpixel)*
sizeof(
RGBQUAD);
2469 void *image_bits, *mask_bits =
NULL;
2474 TRACE(
"%p\n", pstm);
2478 if (ilHead.
usMagic != ((
'L' << 8) |
'I'))
2483 TRACE(
"cx %u, cy %u, flags 0x%04x, cCurImage %u, cMaxImage %u\n",
2490 if (!(image_bits =
read_bitmap(pstm, image_info)))
2492 WARN(
"failed to read bitmap from stream\n");
2499 WARN(
"failed to read mask bitmap from stream\n");
2503 else mask_info =
NULL;
2508 BYTE *mask_ptr = mask_bits;
2570 HBITMAP hbmNewImage, hbmNewMask;
2577 ERR(
"Invalid image list handle!\n");
2582 TRACE(
"index out of range! %d\n",
i);
2592 TRACE(
"remove all on empty ImageList!\n");
2623 TRACE(
"Remove single image! %d\n",
i);
2626 TRACE(
" - Number of images: %d / %d (Old/New)\n",
2641 TRACE(
"Pre image copy: Copy %d images\n",
i);
2653 if (i < himl->cCurImage - 1) {
2654 TRACE(
"Post image copy!\n");
2710 TRACE(
"%p %d %p %p\n",
himl,
i, hbmImage, hbmMask);
2713 ERR(
"Invalid image list handle!\n");
2718 ERR(
"Invalid image index!\n");
2790 ERR(
"invalid image list\n");
2929 INT dxHotspot,
INT dyHotspot)
2937 TRACE(
" dxH=%d dyH=%d nX=%d nY=%d\n",
2943 dxHotspot, dyHotspot);
2992 FIXME(
"(%p 0x%x 0x%x):empty stub!\n",
himl,
i, dwFilter);
3093 INT nNewCount, nCopyCount;
3100 nNewCount = iImageCount + 1;
3107 if (hbmNewBitmap != 0)
3120 ERR(
"Could not create new image bitmap!\n");
3127 if (hbmNewBitmap != 0)
3140 ERR(
"Could not create new mask bitmap!\n");
3186 if ((iImage!=-1) && ((iImage < 0) || (iImage >
himl->
cCurImage)))
3203 INT bitCount, sizeImage, offBits, totalSize;
3210 bitCount = bm.bmBitsPixel;
3215 totalSize += (1 << bitCount) *
sizeof(
RGBQUAD);
3216 offBits = totalSize;
3217 totalSize += sizeImage;
3219 data = heap_alloc_zero(totalSize);
3222 lpBits =
data + offBits;
3225 bmfh->
bfType = ((
'M' << 8) |
'B');
3250 TRACE(
"width %u, height %u, planes %u, bpp %u\n",
3293 ilHead.
usMagic = ((
'L' << 8) |
'I');
3302 for(
i = 0;
i < 4;
i++) {
3306 TRACE(
"cx %u, cy %u, flags 0x04%x, cCurImage %u, cMaxImage %u\n",
3339 TRACE(
"Creating DIBSection %d x %d, %d Bits per Pixel\n",
3379 TRACE(
"returning %p\n", hbmNewBitmap);
3380 return hbmNewBitmap;
3406 if(!is_valid2(
himl))
3466 IImageList2_AddRef(iface);
3475 TRACE(
"(%p) refcount=%u\n", iface,
ref);
3484 TRACE(
"(%p) refcount=%u\n", iface,
ref);
3501 This->usMagic = IMAGELIST_MAGIC_DESTROYED;
3503 This->IImageList2_iface.lpVtbl =
NULL;
3548 int iImage,
int iOverlay)
3588 old_himl = pimldp->
himl;
3589 pimldp->
himl = imgl;
3593 pimldp->
himl = old_himl;
3645 if (
FAILED(IUnknown_QueryInterface(unk_src, &IID_IImageList,
3654 IImageList_Release(
src);
3675 if (
FAILED(IUnknown_QueryInterface(punk2, &IID_IImageList,
3688 IImageList_Release(iml2);
3772 int dxHotspot,
int dyHotspot)
3801 IUnknown *punk,
int iDrag,
int dxHotspot,
int dyHotspot)
3810 if (
FAILED(IUnknown_QueryInterface(punk, &IID_IImageList,
3817 IImageList_Release(iml2);
3844 IImageList_Release(idrag);
3863 if ((iOverlay < 0) || (iOverlay >
This->cCurImage))
3868 if (
This->nOvlIdx[
i] == iOverlay)
3880 FIXME(
"(%p)->(%d %d): stub\n", iface,
cx,
cy);