diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c index c1edbdf1720..41c1017943a 100644 --- a/dlls/comctl32/imagelist.c +++ b/dlls/comctl32/imagelist.c @@ -771,7 +771,14 @@ ImageList_Create (INT cx, INT cy, UINT flags, if (FAILED(ImageListImpl_CreateInstance(NULL, &IID_IImageList, (void **)&himl))) return NULL; - cGrow = (cGrow < 4) ? 4 : (cGrow + 3) & ~3; + cGrow = (WORD)((max( cGrow, 1 ) + 3) & ~3); + + if (cGrow > 256) + { + /* Windows doesn't limit the size here, but X11 doesn't let use allocate such huge bitmaps */ + WARN( "grow %d too large, limiting to 256\n", cGrow ); + cGrow = 256; + } himl->cx = cx; himl->cy = cy; @@ -2352,7 +2359,7 @@ ImageList_Remove (HIMAGELIST himl, INT i) return TRUE; } - himl->cMaxImage = himl->cInitial + himl->cGrow - 1; + himl->cMaxImage = himl->cGrow; himl->cCurImage = 0; for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++) himl->nOvlIdx[nCount] = -1; @@ -2563,7 +2570,7 @@ ImageList_ReplaceIcon (HIMAGELIST himl, INT nIndex, HICON hIcon) return -1; if (nIndex == -1) { - if (himl->cCurImage + 1 > himl->cMaxImage) + if (himl->cCurImage + 1 >= himl->cMaxImage) IMAGELIST_InternalExpandBitmaps(himl, 1); nIndex = himl->cCurImage; @@ -2848,14 +2855,8 @@ ImageList_SetImageCount (HIMAGELIST himl, UINT iImageCount) if (!is_valid(himl)) return FALSE; - if (himl->cMaxImage > iImageCount) - { - himl->cCurImage = iImageCount; - /* TODO: shrink the bitmap when cMaxImage-cCurImage>cGrow ? */ - return TRUE; - } - nNewCount = iImageCount + himl->cGrow; + nNewCount = iImageCount + 1; nCopyCount = min(himl->cCurImage, iImageCount); hdcBitmap = CreateCompatibleDC (0); diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c index 588a5b38735..b920b9aaf5b 100644 --- a/dlls/comctl32/tests/imagelist.c +++ b/dlls/comctl32/tests/imagelist.c @@ -1089,6 +1089,59 @@ static void test_imagelist_storage(void) ret = ImageList_Destroy(himl); ok(ret, "ImageList_Destroy failed\n"); iml_clear_stream_data(); + + himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 99); + ok(himl != 0, "ImageList_Create failed\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK, + "init 2 grow 99"); + icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits); + ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n"); + ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 2, 3, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK, + "init 2 grow 99 2 icons"); + ok( ImageList_AddIcon(himl, icon) == 2,"failed to add icon\n"); + DestroyIcon( icon ); + check_iml_data(himl, BMP_CX, BMP_CX, 3, 104, 100, BMP_CX * 4, BMP_CX * 104/4, ILC_COLOR4|ILC_MASK, + "init 2 grow 99 3 icons"); + ok( ImageList_Remove(himl, -1) == TRUE,"failed to remove icon\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 100, 100, BMP_CX * 4, BMP_CX * 100/4, ILC_COLOR4|ILC_MASK, + "init 2 grow 99 empty"); + ok( ImageList_SetImageCount(himl, 22) == TRUE,"failed to set image count\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 22, 23, 100, BMP_CX * 4, BMP_CX * 24/4, ILC_COLOR4|ILC_MASK, + "init 2 grow 99 set count 22"); + ok( ImageList_SetImageCount(himl, 0) == TRUE,"failed to set image count\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK, + "init 2 grow 99 set count 0"); + ok( ImageList_SetImageCount(himl, 42) == TRUE,"failed to set image count\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 42, 43, 100, BMP_CX * 4, BMP_CX * 44/4, ILC_COLOR4|ILC_MASK, + "init 2 grow 99 set count 42"); + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + iml_clear_stream_data(); + + himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 65536+12); + ok(himl != 0, "ImageList_Create failed\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 12, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK, + "init 2 grow 65536+12"); + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + iml_clear_stream_data(); + + himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 65535); + ok(himl != 0, "ImageList_Create failed\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 0, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK, + "init 2 grow 65535"); + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + iml_clear_stream_data(); + + himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, -20); + ok(himl != 0, "ImageList_Create failed\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK, + "init 2 grow -20"); + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + iml_clear_stream_data(); } static void test_shell_imagelist(void)