2 * Unit test suite for imagelist control.
4 * Copyright 2004 Michael Stefaniuc
5 * Copyright 2002 Mike McCormack for CodeWeavers
6 * Copyright 2007 Dmitry Timoshkov
7 * Copyright 2009 Owen Rudge for CodeWeavers
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
36 #include "commctrl.h" /* must be included after objbase.h to get ImageList_Write */
38 #include "commoncontrols.h"
41 #include "wine/test.h"
47 #define WAIT Sleep (1000)
48 #define REDRAW(hwnd) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW)
54 #define IMAGELIST_MAGIC (('L' << 8) | 'I')
57 /* Header used by ImageList_Read() and ImageList_Write() */
58 typedef struct _ILHEAD
73 static HIMAGELIST (WINAPI *pImageList_Create)(int, int, UINT, int, int);
74 static int (WINAPI *pImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
75 static BOOL (WINAPI *pImageList_DrawIndirect)(IMAGELISTDRAWPARAMS*);
76 static BOOL (WINAPI *pImageList_SetImageCount)(HIMAGELIST,UINT);
77 static HRESULT (WINAPI *pImageList_CoCreateInstance)(REFCLSID,const IUnknown *,
79 static HRESULT (WINAPI *pHIMAGELIST_QueryInterface)(HIMAGELIST,REFIID,void **);
81 static HINSTANCE hinst;
83 /* These macros build cursor/bitmap data in 4x4 pixel blocks */
84 #define B(x,y) ((x?0xf0:0)|(y?0xf:0))
85 #define ROW1(a,b,c,d,e,f,g,h) B(a,b),B(c,d),B(e,f),B(g,h)
86 #define ROW32(a,b,c,d,e,f,g,h) ROW1(a,b,c,d,e,f,g,h), ROW1(a,b,c,d,e,f,g,h), \
87 ROW1(a,b,c,d,e,f,g,h), ROW1(a,b,c,d,e,f,g,h)
88 #define ROW2(a,b,c,d,e,f,g,h,i,j,k,l) ROW1(a,b,c,d,e,f,g,h),B(i,j),B(k,l)
89 #define ROW48(a,b,c,d,e,f,g,h,i,j,k,l) ROW2(a,b,c,d,e,f,g,h,i,j,k,l), \
90 ROW2(a,b,c,d,e,f,g,h,i,j,k,l), ROW2(a,b,c,d,e,f,g,h,i,j,k,l), \
91 ROW2(a,b,c,d,e,f,g,h,i,j,k,l)
93 static const BYTE empty_bits[48*48/8];
95 static const BYTE icon_bits[32*32/8] =
97 ROW32(0,0,0,0,0,0,0,0),
98 ROW32(0,0,1,1,1,1,0,0),
99 ROW32(0,1,1,1,1,1,1,0),
100 ROW32(0,1,1,0,0,1,1,0),
101 ROW32(0,1,1,0,0,1,1,0),
102 ROW32(0,1,1,1,1,1,1,0),
103 ROW32(0,0,1,1,1,1,0,0),
104 ROW32(0,0,0,0,0,0,0,0)
107 static const BYTE bitmap_bits[48*48/8] =
109 ROW48(0,0,0,0,0,0,0,0,0,0,0,0),
110 ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
111 ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
112 ROW48(0,1,0,0,0,0,0,0,1,0,1,0),
113 ROW48(0,1,0,0,0,0,0,1,0,0,1,0),
114 ROW48(0,1,0,0,0,0,1,0,0,0,1,0),
115 ROW48(0,1,0,0,0,1,0,0,0,0,1,0),
116 ROW48(0,1,0,0,1,0,0,0,0,0,1,0),
117 ROW48(0,1,0,1,0,0,0,0,0,0,1,0),
118 ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
119 ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
120 ROW48(0,0,0,0,0,0,0,0,0,0,0,0)
123 static HIMAGELIST createImageList(int cx, int cy)
125 /* Create an ImageList and put an image into it */
126 HIMAGELIST himl = ImageList_Create(cx, cy, ILC_COLOR, 1, 1);
127 HBITMAP hbm = CreateBitmap(48, 48, 1, 1, bitmap_bits);
128 ImageList_Add(himl, hbm, NULL);
133 static HWND create_a_window(void)
135 char className[] = "bmwnd";
136 char winName[] = "Test Bitmap";
138 static int registered = 0;
144 cls.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
145 cls.lpfnWndProc = DefWindowProcA;
149 cls.hIcon = LoadIconA (0, IDI_APPLICATION);
150 cls.hCursor = LoadCursorA (0, IDC_ARROW);
151 cls.hbrBackground = GetStockObject (WHITE_BRUSH);
152 cls.lpszMenuName = 0;
153 cls.lpszClassName = className;
155 RegisterClassA (&cls);
160 hWnd = CreateWindowA (className, winName,
161 WS_OVERLAPPEDWINDOW ,
162 CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
166 ShowWindow (hWnd, SW_SHOW);
174 static HDC show_image(HWND hwnd, HIMAGELIST himl, int idx, int size,
175 LPCSTR loc, BOOL clear)
179 if (!himl) return NULL;
181 SetWindowText(hwnd, loc);
183 ImageList_Draw(himl, idx, hdc, 0, 0, ILD_TRANSPARENT);
190 BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
191 ReleaseDC(hwnd, hdc);
198 /* Useful for checking differences */
200 static void dump_bits(const BYTE *p, const BYTE *q, int size)
206 for (i = 0; i < size * 2; i++)
209 for (j = 0; j < size; j++)
210 printf("%c%c", p[j] & 0xf0 ? 'X' : ' ', p[j] & 0xf ? 'X' : ' ');
212 for (j = 0; j < size; j++)
213 printf("%c%c", q[j] & 0xf0 ? 'X' : ' ', q[j] & 0xf ? 'X' : ' ');
222 static void check_bits(HWND hwnd, HIMAGELIST himl, int idx, int size,
223 const BYTE *checkbits, LPCSTR loc)
226 BYTE bits[100*100/8];
233 memset(bits, 0, sizeof(bits));
234 hdc = show_image(hwnd, himl, idx, size, loc, FALSE);
236 c = GetPixel(hdc, 0, 0);
238 for (y = 0; y < size; y ++)
240 for (x = 0; x < size; x++)
243 if (GetPixel(hdc, x, y) != c) bits[i] |= (0x80 >> (x & 0x7));
247 BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
248 ReleaseDC(hwnd, hdc);
250 ok (memcmp(bits, checkbits, (size * size)/8) == 0,
251 "%s: bits different\n", loc);
252 if (memcmp(bits, checkbits, (size * size)/8))
253 dump_bits(bits, checkbits, size);
257 static void test_hotspot(void)
268 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
269 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
276 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
277 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
278 HWND hwnd = create_a_window();
281 for (i = 0; i < HOTSPOTS_MAX; i++) {
282 for (j = 0; j < HOTSPOTS_MAX; j++) {
283 int dx1 = hotspots[i].dx;
284 int dy1 = hotspots[i].dy;
285 int dx2 = hotspots[j].dx;
286 int dy2 = hotspots[j].dy;
287 int correctx, correcty, newx, newy;
292 ret = ImageList_BeginDrag(himl1, 0, dx1, dy1);
293 ok(ret != 0, "BeginDrag failed for { %d, %d }\n", dx1, dy1);
294 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
295 show_image(hwnd, himl1, 0, max(SIZEX1, SIZEY1), loc, TRUE);
297 /* check merging the dragged image with a second image */
298 ret = ImageList_SetDragCursorImage(himl2, 0, dx2, dy2);
299 ok(ret != 0, "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
301 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
302 show_image(hwnd, himl2, 0, max(SIZEX2, SIZEY2), loc, TRUE);
304 /* check new hotspot, it should be the same like the old one */
305 himlNew = ImageList_GetDragImage(NULL, &ppt);
306 ok(ppt.x == dx1 && ppt.y == dy1,
307 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
308 dx1, dy1, ppt.x, ppt.y);
309 /* check size of new dragged image */
310 ImageList_GetIconSize(himlNew, &newx, &newy);
311 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
312 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
313 ok(newx == correctx && newy == correcty,
314 "Expected drag image size [%d,%d] got [%d,%d]\n",
315 correctx, correcty, newx, newy);
316 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
317 show_image(hwnd, himlNew, 0, max(correctx, correcty), loc, TRUE);
326 ImageList_Destroy(himl2);
327 ImageList_Destroy(himl1);
331 static void test_add_remove(void)
339 /* create an imagelist to play with */
340 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
341 ok(himl!=0,"failed to create imagelist\n");
343 /* load the icons to add to the image list */
344 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
345 ok(hicon1 != 0, "no hicon1\n");
346 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
347 ok(hicon2 != 0, "no hicon2\n");
348 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
349 ok(hicon3 != 0, "no hicon3\n");
351 /* remove when nothing exists */
352 ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
353 /* removing everything from an empty imagelist should succeed */
354 ok(ImageList_RemoveAll(himl),"removed nonexistent icon\n");
357 ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
358 ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
359 ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
361 /* remove an index out of range */
362 ok(!ImageList_Remove(himl,4711),"removed nonexistent icon\n");
365 ok(ImageList_Remove(himl,0),"can't remove 0\n");
366 ok(ImageList_Remove(himl,0),"can't remove 0\n");
367 ok(ImageList_Remove(himl,0),"can't remove 0\n");
369 /* remove one extra */
370 ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
373 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
375 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
376 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
377 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
380 static void test_imagecount(void)
384 if (!pImageList_SetImageCount)
386 win_skip("ImageList_SetImageCount not available\n");
390 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
391 ok(himl!=0,"failed to create imagelist\n");
393 ok(pImageList_SetImageCount(himl, 3), "couldn't increase image count\n");
394 ok(ImageList_GetImageCount(himl) == 3, "invalid image count after increase\n");
395 ok(pImageList_SetImageCount(himl, 1), "couldn't decrease image count\n");
396 ok(ImageList_GetImageCount(himl) == 1, "invalid image count after decrease to 1\n");
397 ok(pImageList_SetImageCount(himl, 0), "couldn't decrease image count\n");
398 ok(ImageList_GetImageCount(himl) == 0, "invalid image count after decrease to 0\n");
400 ok(ImageList_Destroy(himl), "destroy imagelist failed\n");
403 static void test_DrawIndirect(void)
411 IMAGELISTDRAWPARAMS imldp;
415 if (!pImageList_DrawIndirect)
417 win_skip("ImageList_DrawIndirect not available, skipping test\n");
421 hwndfortest = create_a_window();
422 hdc = GetDC(hwndfortest);
423 ok(hdc!=NULL, "couldn't get DC\n");
425 /* create an imagelist to play with */
426 himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
427 ok(himl!=0,"failed to create imagelist\n");
429 /* load the icons to add to the image list */
430 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
431 ok(hbm1 != 0, "no bitmap 1\n");
432 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
433 ok(hbm2 != 0, "no bitmap 2\n");
434 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
435 ok(hbm3 != 0, "no bitmap 3\n");
438 ok(0==ImageList_Add(himl, hbm1, 0),"failed to add bitmap 1\n");
439 ok(1==ImageList_Add(himl, hbm2, 0),"failed to add bitmap 2\n");
441 if (pImageList_SetImageCount)
443 ok(pImageList_SetImageCount(himl,3),"Setimage count failed\n");
444 /*ok(2==ImageList_Add(himl, hbm3, NULL),"failed to add bitmap 3\n"); */
445 ok(ImageList_Replace(himl, 2, hbm3, 0),"failed to replace bitmap 3\n");
448 memset(&imldp, 0, sizeof (imldp));
449 ok(!pImageList_DrawIndirect(&imldp), "zero data succeeded!\n");
450 imldp.cbSize = IMAGELISTDRAWPARAMS_V3_SIZE;
451 ok(!pImageList_DrawIndirect(&imldp), "zero hdc succeeded!\n");
453 ok(!pImageList_DrawIndirect(&imldp),"zero himl succeeded!\n");
459 imldp.fStyle = SRCCOPY;
460 imldp.rgbBk = CLR_DEFAULT;
461 imldp.rgbFg = CLR_DEFAULT;
464 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
466 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
468 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
470 ok(!pImageList_DrawIndirect(&imldp),"should fail\n");
473 ok(ImageList_Remove(himl, 0), "removing 1st bitmap\n");
474 ok(ImageList_Remove(himl, 0), "removing 2nd bitmap\n");
475 ok(ImageList_Remove(himl, 0), "removing 3rd bitmap\n");
478 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
480 /* bitmaps should not be deleted by the imagelist */
481 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
482 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
483 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
485 ReleaseDC(hwndfortest, hdc);
486 DestroyWindow(hwndfortest);
489 static void test_merge(void)
491 HIMAGELIST himl1, himl2, hmerge;
493 HWND hwnd = create_a_window();
495 himl1 = ImageList_Create(32,32,0,0,3);
496 ok(himl1 != NULL,"failed to create himl1\n");
498 himl2 = ImageList_Create(32,32,0,0,3);
499 ok(himl2 != NULL,"failed to create himl2\n");
501 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
502 ok(hicon1 != NULL, "failed to create hicon1\n");
504 if (!himl1 || !himl2 || !hicon1)
507 ok(0==ImageList_AddIcon(himl2, hicon1),"add icon1 to himl2 failed\n");
508 check_bits(hwnd, himl2, 0, 32, icon_bits, "add icon1 to himl2");
510 /* If himl1 has no images, merge still succeeds */
511 hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
512 ok(hmerge != NULL, "merge himl1,-1 failed\n");
513 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,-1");
514 if (hmerge) ImageList_Destroy(hmerge);
516 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
517 ok(hmerge != NULL,"merge himl1,0 failed\n");
518 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,0");
519 if (hmerge) ImageList_Destroy(hmerge);
521 /* Same happens if himl2 is empty */
522 ImageList_Destroy(himl2);
523 himl2 = ImageList_Create(32,32,0,0,3);
524 ok(himl2 != NULL,"failed to recreate himl2\n");
528 hmerge = ImageList_Merge(himl1, -1, himl2, -1, 0, 0);
529 ok(hmerge != NULL, "merge himl2,-1 failed\n");
530 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,-1");
531 if (hmerge) ImageList_Destroy(hmerge);
533 hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
534 ok(hmerge != NULL, "merge himl2,0 failed\n");
535 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,0");
536 if (hmerge) ImageList_Destroy(hmerge);
538 /* Now try merging an image with itself */
539 ok(0==ImageList_AddIcon(himl2, hicon1),"re-add icon1 to himl2 failed\n");
541 hmerge = ImageList_Merge(himl2, 0, himl2, 0, 0, 0);
542 ok(hmerge != NULL, "merge himl2 with itself failed\n");
543 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2 with itself");
544 if (hmerge) ImageList_Destroy(hmerge);
546 /* Try merging 2 different image lists */
547 ok(0==ImageList_AddIcon(himl1, hicon1),"add icon1 to himl1 failed\n");
549 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
550 ok(hmerge != NULL, "merge himl1 with himl2 failed\n");
551 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2");
552 if (hmerge) ImageList_Destroy(hmerge);
554 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 8, 16);
555 ok(hmerge != NULL, "merge himl1 with himl2 8,16 failed\n");
556 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2, 8,16");
557 if (hmerge) ImageList_Destroy(hmerge);
559 ImageList_Destroy(himl1);
560 ImageList_Destroy(himl2);
565 /*********************** imagelist storage test ***************************/
572 char *iml_data; /* written imagelist data */
576 static HRESULT STDMETHODCALLTYPE Test_Stream_QueryInterface(
585 static ULONG STDMETHODCALLTYPE Test_Stream_AddRef(
592 static ULONG STDMETHODCALLTYPE Test_Stream_Release(
599 static HRESULT STDMETHODCALLTYPE Test_Stream_Read(
609 static BOOL allocate_storage(struct my_IStream *my_is, ULONG add)
611 my_is->iml_data_size += add;
613 if (!my_is->iml_data)
614 my_is->iml_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, my_is->iml_data_size);
616 my_is->iml_data = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, my_is->iml_data, my_is->iml_data_size);
618 return my_is->iml_data ? TRUE : FALSE;
621 static HRESULT STDMETHODCALLTYPE Test_Stream_Write(
627 struct my_IStream *my_is = (struct my_IStream *)This;
628 ULONG current_iml_data_size = my_is->iml_data_size;
630 if (!allocate_storage(my_is, cb)) return E_FAIL;
632 memcpy(my_is->iml_data + current_iml_data_size, pv, cb);
633 if (pcbWritten) *pcbWritten = cb;
638 static HRESULT STDMETHODCALLTYPE Test_Stream_Seek(
640 LARGE_INTEGER dlibMove,
642 ULARGE_INTEGER* plibNewPosition)
648 static HRESULT STDMETHODCALLTYPE Test_Stream_SetSize(
650 ULARGE_INTEGER libNewSize)
656 static HRESULT STDMETHODCALLTYPE Test_Stream_CopyTo(
660 ULARGE_INTEGER* pcbRead,
661 ULARGE_INTEGER* pcbWritten)
667 static HRESULT STDMETHODCALLTYPE Test_Stream_Commit(
669 DWORD grfCommitFlags)
675 static HRESULT STDMETHODCALLTYPE Test_Stream_Revert(
682 static HRESULT STDMETHODCALLTYPE Test_Stream_LockRegion(
684 ULARGE_INTEGER libOffset,
692 static HRESULT STDMETHODCALLTYPE Test_Stream_UnlockRegion(
694 ULARGE_INTEGER libOffset,
702 static HRESULT STDMETHODCALLTYPE Test_Stream_Stat(
711 static HRESULT STDMETHODCALLTYPE Test_Stream_Clone(
719 static const IStreamVtbl Test_Stream_Vtbl =
721 Test_Stream_QueryInterface,
731 Test_Stream_LockRegion,
732 Test_Stream_UnlockRegion,
737 static struct my_IStream Test_Stream = { { &Test_Stream_Vtbl }, 0, 0 };
739 static INT DIB_GetWidthBytes( int width, int bpp )
741 return ((width * bpp + 31) / 8) & ~3;
744 static void check_bitmap_data(const char *bm_data, ULONG bm_data_size,
745 INT width, INT height, INT bpp,
748 const BITMAPFILEHEADER *bmfh = (const BITMAPFILEHEADER *)bm_data;
749 const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)(bm_data + sizeof(*bmfh));
750 ULONG hdr_size, image_size;
752 hdr_size = sizeof(*bmfh) + sizeof(*bmih);
753 if (bmih->biBitCount <= 8) hdr_size += (1 << bpp) * sizeof(RGBQUAD);
755 ok(bmfh->bfType == (('M' << 8) | 'B'), "wrong bfType 0x%02x\n", bmfh->bfType);
756 ok(bmfh->bfSize == hdr_size, "wrong bfSize 0x%02x\n", bmfh->bfSize);
757 ok(bmfh->bfReserved1 == 0, "wrong bfReserved1 0x%02x\n", bmfh->bfReserved1);
758 ok(bmfh->bfReserved2 == 0, "wrong bfReserved2 0x%02x\n", bmfh->bfReserved2);
759 ok(bmfh->bfOffBits == hdr_size, "wrong bfOffBits 0x%02x\n", bmfh->bfOffBits);
761 ok(bmih->biSize == sizeof(*bmih), "wrong biSize %d\n", bmih->biSize);
762 ok(bmih->biWidth == width, "wrong biWidth %d (expected %d)\n", bmih->biWidth, width);
763 ok(bmih->biHeight == height, "wrong biHeight %d (expected %d)\n", bmih->biHeight, height);
764 ok(bmih->biPlanes == 1, "wrong biPlanes %d\n", bmih->biPlanes);
765 ok(bmih->biBitCount == bpp, "wrong biBitCount %d\n", bmih->biBitCount);
767 image_size = DIB_GetWidthBytes(bmih->biWidth, bmih->biBitCount) * bmih->biHeight;
768 ok(bmih->biSizeImage == image_size, "wrong biSizeImage %u\n", bmih->biSizeImage);
773 sprintf(fname, "bmp_%s.bmp", comment);
774 f = fopen(fname, "wb");
775 fwrite(bm_data, 1, bm_data_size, f);
781 static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max, INT grow)
783 const ILHEAD *ilh = (const ILHEAD *)ilh_data;
785 ok(ilh->usMagic == IMAGELIST_MAGIC, "wrong usMagic %4x (expected %02x)\n", ilh->usMagic, IMAGELIST_MAGIC);
786 ok(ilh->usVersion == 0x101, "wrong usVersion %x (expected 0x101)\n", ilh->usVersion);
787 ok(ilh->cCurImage == cur, "wrong cCurImage %d (expected %d)\n", ilh->cCurImage, cur);
788 ok(ilh->cMaxImage == max, "wrong cMaxImage %d (expected %d)\n", ilh->cMaxImage, max);
789 ok(ilh->cGrow == grow, "wrong cGrow %d (expected %d)\n", ilh->cGrow, grow);
790 ok(ilh->cx == cx, "wrong cx %d (expected %d)\n", ilh->cx, cx);
791 ok(ilh->cy == cy, "wrong cy %d (expected %d)\n", ilh->cy, cy);
792 ok(ilh->bkcolor == CLR_NONE, "wrong bkcolor %x\n", ilh->bkcolor);
793 ok(ilh->flags == ILC_COLOR24, "wrong flags %04x\n", ilh->flags);
794 ok(ilh->ovls[0] == -1 ||
795 ilh->ovls[0] == 0, /* win95 */
796 "wrong ovls[0] %04x\n", ilh->ovls[0]);
797 ok(ilh->ovls[1] == -1 ||
798 ilh->ovls[1] == 0, /* win95 */
799 "wrong ovls[1] %04x\n", ilh->ovls[1]);
800 ok(ilh->ovls[2] == -1 ||
801 ilh->ovls[2] == 0, /* win95 */
802 "wrong ovls[2] %04x\n", ilh->ovls[2]);
803 ok(ilh->ovls[3] == -1 ||
804 ilh->ovls[3] == 0, /* win95 */
805 "wrong ovls[3] %04x\n", ilh->ovls[3]);
808 static HBITMAP create_bitmap(INT cx, INT cy, COLORREF color, const char *comment)
811 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
812 BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
813 HBITMAP hbmp, hbmp_old;
815 RECT rc = { 0, 0, cx, cy };
817 hdc = CreateCompatibleDC(0);
819 memset(bmi, 0, sizeof(*bmi));
820 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
821 bmi->bmiHeader.biHeight = cx;
822 bmi->bmiHeader.biWidth = cy;
823 bmi->bmiHeader.biBitCount = 24;
824 bmi->bmiHeader.biPlanes = 1;
825 bmi->bmiHeader.biCompression = BI_RGB;
826 hbmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
828 hbmp_old = SelectObject(hdc, hbmp);
830 hbrush = CreateSolidBrush(color);
831 FillRect(hdc, &rc, hbrush);
832 DeleteObject(hbrush);
834 DrawText(hdc, comment, -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
836 SelectObject(hdc, hbmp_old);
842 #define iml_clear_stream_data() \
843 HeapFree(GetProcessHeap(), 0, Test_Stream.iml_data); \
844 Test_Stream.iml_data = NULL; \
845 Test_Stream.iml_data_size = 0;
847 static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max, INT grow,
848 INT width, INT height, INT bpp, const char *comment)
852 trace("%s\n", comment);
854 ret = ImageList_GetImageCount(himl);
855 ok(ret == cur, "expected image count %d got %d\n", cur, ret);
857 ret = ImageList_GetIconSize(himl, &cxx, &cyy);
858 ok(ret, "ImageList_GetIconSize failed\n");
859 ok(cxx == cx, "wrong cx %d (expected %d)\n", cxx, cx);
860 ok(cyy == cy, "wrong cy %d (expected %d)\n", cyy, cy);
862 iml_clear_stream_data();
863 ret = ImageList_Write(himl, &Test_Stream.is);
864 ok(ret, "ImageList_Write failed\n");
866 ok(Test_Stream.iml_data != 0, "ImageList_Write didn't write any data\n");
867 ok(Test_Stream.iml_data_size > sizeof(ILHEAD), "ImageList_Write wrote not enough data\n");
869 check_ilhead_data(Test_Stream.iml_data, cx, cy, cur, max, grow);
870 check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD),
871 Test_Stream.iml_data_size - sizeof(ILHEAD),
872 width, height, bpp, comment);
875 static void image_list_init(HIMAGELIST himl)
881 static const struct test_data
884 INT cx, cy, cur, max, grow, width, height, bpp;
888 { 255, BMP_CX, BMP_CX, 1, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "total 1" },
889 { 170, BMP_CX, BMP_CX, 2, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 2" },
890 { 85, BMP_CX, BMP_CX, 3, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 3" },
891 { 0, BMP_CX, BMP_CX, 4, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 4" },
892 { 0, BMP_CX, BMP_CX, 5, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 5" },
893 { 85, BMP_CX, BMP_CX, 6, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 6" },
894 { 170, BMP_CX, BMP_CX, 7, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 7" },
895 { 255, BMP_CX, BMP_CX, 8, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 8" },
896 { 255, BMP_CX, BMP_CX, 9, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 9" },
897 { 170, BMP_CX, BMP_CX, 10, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 10" },
898 { 85, BMP_CX, BMP_CX, 11, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 11" },
899 { 0, BMP_CX, BMP_CX, 12, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 12" },
900 { 0, BMP_CX, BMP_CX, 13, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 13" },
901 { 85, BMP_CX, BMP_CX, 14, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 14" },
902 { 170, BMP_CX, BMP_CX, 15, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 15" },
903 { 255, BMP_CX, BMP_CX, 16, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 16" },
904 { 255, BMP_CX, BMP_CX, 17, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 17" },
905 { 170, BMP_CX, BMP_CX, 18, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 18" },
906 { 85, BMP_CX, BMP_CX, 19, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 19" },
907 { 0, BMP_CX, BMP_CX, 20, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 20" },
908 { 0, BMP_CX, BMP_CX, 21, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 21" },
909 { 85, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 22" },
910 { 170, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 23" },
911 { 255, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 24" }
914 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "total 0");
916 #define add_bitmap(grey) \
917 sprintf(comment, "%d", n++); \
918 hbm = create_bitmap(BMP_CX, BMP_CX, RGB((grey),(grey),(grey)), comment); \
919 ImageList_Add(himl, hbm, NULL); \
922 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
924 add_bitmap(td[i].grey);
925 check_iml_data(himl, td[i].cx, td[i].cy, td[i].cur, td[i].max, td[i].grow,
926 td[i].width, td[i].height, td[i].bpp, td[i].comment);
931 static void test_imagelist_storage(void)
937 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 1, 1);
938 ok(himl != 0, "ImageList_Create failed\n");
940 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "empty");
942 image_list_init(himl);
943 check_iml_data(himl, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "orig");
945 ret = ImageList_Remove(himl, 4);
946 ok(ret, "ImageList_Remove failed\n");
947 check_iml_data(himl, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "1");
949 ret = ImageList_Remove(himl, 5);
950 ok(ret, "ImageList_Remove failed\n");
951 check_iml_data(himl, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "2");
953 ret = ImageList_Remove(himl, 6);
954 ok(ret, "ImageList_Remove failed\n");
955 check_iml_data(himl, BMP_CX, BMP_CX, 21, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "3");
957 ret = ImageList_Remove(himl, 7);
958 ok(ret, "ImageList_Remove failed\n");
959 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "4");
961 ret = ImageList_Remove(himl, -2);
962 ok(!ret, "ImageList_Remove(-2) should fail\n");
963 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "5");
965 ret = ImageList_Remove(himl, 20);
966 ok(!ret, "ImageList_Remove(20) should fail\n");
967 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "6");
969 ret = ImageList_Remove(himl, -1);
970 ok(ret, "ImageList_Remove(-1) failed\n");
971 check_iml_data(himl, BMP_CX, BMP_CX, 0, 4, 4, BMP_CX * 4, BMP_CX * 1, 24, "7");
973 ret = ImageList_Destroy(himl);
974 ok(ret, "ImageList_Destroy failed\n");
976 iml_clear_stream_data();
978 /* test ImageList_Create storage allocation */
980 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 0, 32);
981 ok(himl != 0, "ImageList_Create failed\n");
982 check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 32, BMP_CX * 4, BMP_CX * 1, 24, "init 0 grow 32");
983 hbm = create_bitmap(BMP_CX * 9, BMP_CX, 0, "9");
984 ret = ImageList_Add(himl, hbm, NULL);
985 ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
986 check_iml_data(himl, BMP_CX, BMP_CX, 1, 34, 32, BMP_CX * 4, BMP_CX * 9, 24, "add 1 x 9");
988 ret = ImageList_Destroy(himl);
989 ok(ret, "ImageList_Destroy failed\n");
990 iml_clear_stream_data();
992 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 4);
993 ok(himl != 0, "ImageList_Create failed\n");
994 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, 24, "init 4 grow 4");
995 hbm = create_bitmap(BMP_CX, BMP_CX * 9, 0, "9");
996 ret = ImageList_Add(himl, hbm, NULL);
997 ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
998 check_iml_data(himl, BMP_CX, BMP_CX, 9, 15, 4, BMP_CX * 4, BMP_CX * 4, 24, "add 9 x 1");
999 ret = ImageList_Add(himl, hbm, NULL);
1000 ok(ret == 9, "ImageList_Add returned %d, expected 9\n", ret);
1001 check_iml_data(himl, BMP_CX, BMP_CX, 18, 25, 4, BMP_CX * 4, BMP_CX * 7, 24, "add 9 x 1");
1003 ret = ImageList_Destroy(himl);
1004 ok(ret, "ImageList_Destroy failed\n");
1005 iml_clear_stream_data();
1007 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 207, 209);
1008 ok(himl != 0, "ImageList_Create failed\n");
1009 check_iml_data(himl, BMP_CX, BMP_CX, 0, 208, 212, BMP_CX * 4, BMP_CX * 52, 24, "init 207 grow 209");
1010 ret = ImageList_Destroy(himl);
1011 ok(ret, "ImageList_Destroy failed\n");
1012 iml_clear_stream_data();
1014 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 209, 207);
1015 ok(himl != 0, "ImageList_Create failed\n");
1016 check_iml_data(himl, BMP_CX, BMP_CX, 0, 210, 208, BMP_CX * 4, BMP_CX * 53, 24, "init 209 grow 207");
1017 ret = ImageList_Destroy(himl);
1018 ok(ret, "ImageList_Destroy failed\n");
1019 iml_clear_stream_data();
1021 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 14, 4);
1022 ok(himl != 0, "ImageList_Create failed\n");
1023 check_iml_data(himl, BMP_CX, BMP_CX, 0, 15, 4, BMP_CX * 4, BMP_CX * 4, 24, "init 14 grow 4");
1024 ret = ImageList_Destroy(himl);
1025 ok(ret, "ImageList_Destroy failed\n");
1026 iml_clear_stream_data();
1028 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 5, 9);
1029 ok(himl != 0, "ImageList_Create failed\n");
1030 check_iml_data(himl, BMP_CX, BMP_CX, 0, 6, 12, BMP_CX * 4, BMP_CX * 2, 24, "init 5 grow 9");
1031 ret = ImageList_Destroy(himl);
1032 ok(ret, "ImageList_Destroy failed\n");
1033 iml_clear_stream_data();
1035 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 9, 5);
1036 ok(himl != 0, "ImageList_Create failed\n");
1037 check_iml_data(himl, BMP_CX, BMP_CX, 0, 10, 8, BMP_CX * 4, BMP_CX * 3, 24, "init 9 grow 5");
1038 ret = ImageList_Destroy(himl);
1039 ok(ret, "ImageList_Destroy failed\n");
1040 iml_clear_stream_data();
1042 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 2, 4);
1043 ok(himl != 0, "ImageList_Create failed\n");
1044 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX * 1, 24, "init 2 grow 4");
1045 ret = ImageList_Destroy(himl);
1046 ok(ret, "ImageList_Destroy failed\n");
1047 iml_clear_stream_data();
1049 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 2);
1050 ok(himl != 0, "ImageList_Create failed\n");
1051 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, 24, "init 4 grow 2");
1052 ret = ImageList_Destroy(himl);
1053 ok(ret, "ImageList_Destroy failed\n");
1054 iml_clear_stream_data();
1057 static void test_shell_imagelist(void)
1059 BOOL (WINAPI *pSHGetImageList)(INT, REFIID, void**);
1060 IImageList *iml = NULL;
1067 /* Try to load function from shell32 */
1068 hShell32 = LoadLibrary("shell32.dll");
1069 pSHGetImageList = (void*)GetProcAddress(hShell32, (LPCSTR) 727);
1071 if (!pSHGetImageList)
1073 win_skip("SHGetImageList not available, skipping test\n");
1077 /* Get system image list */
1078 hr = (pSHGetImageList)(SHIL_SYSSMALL, &IID_IImageList, (void**)&iml);
1080 ok(SUCCEEDED(hr), "SHGetImageList failed, hr=%x\n", hr);
1085 IImageList_GetImageCount(iml, &out);
1086 ok(out > 0, "IImageList_GetImageCount returned out <= 0\n");
1088 /* Fetch the small icon size */
1089 cx = GetSystemMetrics(SM_CXSMICON);
1090 cy = GetSystemMetrics(SM_CYSMICON);
1092 /* Check icon size matches */
1093 IImageList_GetImageRect(iml, 0, &rect);
1094 ok(((rect.right == cx) && (rect.bottom == cy)),
1095 "IImageList_GetImageRect returned r:%d,b:%d\n",
1096 rect.right, rect.bottom);
1098 IImageList_Release(iml);
1099 FreeLibrary(hShell32);
1102 static HBITMAP create_test_bitmap(HDC hdc, int bpp, UINT32 pixel1, UINT32 pixel2)
1105 UINT32 *buffer = NULL;
1106 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, bpp, BI_RGB,
1109 hBitmap = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, NULL, 0);
1110 ok(hBitmap != NULL && buffer != NULL, "CreateDIBSection failed.\n");
1112 if(!hBitmap || !buffer)
1114 DeleteObject(hBitmap);
1124 static BOOL colour_match(UINT32 x, UINT32 y)
1126 const INT32 tolerance = 8;
1128 const INT32 dr = abs((INT32)(x & 0x000000FF) - (INT32)(y & 0x000000FF));
1129 const INT32 dg = abs((INT32)((x & 0x0000FF00) >> 8) - (INT32)((y & 0x0000FF00) >> 8));
1130 const INT32 db = abs((INT32)((x & 0x00FF0000) >> 16) - (INT32)((y & 0x00FF0000) >> 16));
1132 return (dr <= tolerance && dg <= tolerance && db <= tolerance);
1135 static void check_ImageList_DrawIndirect(IMAGELISTDRAWPARAMS *ildp, UINT32 *bits,
1136 UINT32 expected, int line)
1138 bits[0] = 0x00FFFFFF;
1139 pImageList_DrawIndirect(ildp);
1140 ok(colour_match(bits[0], expected),
1141 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1142 bits[0] & 0x00FFFFFF, expected, line);
1146 static void check_ImageList_DrawIndirect_fStyle(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1147 UINT fStyle, UINT32 expected, int line)
1149 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1150 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, ILS_NORMAL, 0, 0x00000000};
1151 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1154 static void check_ImageList_DrawIndirect_ILD_ROP(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1155 DWORD dwRop, UINT32 expected, int line)
1157 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1158 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_IMAGE | ILD_ROP, dwRop, ILS_NORMAL, 0, 0x00000000};
1159 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1162 static void check_ImageList_DrawIndirect_fState(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i, UINT fStyle,
1163 UINT fState, DWORD Frame, UINT32 expected, int line)
1165 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1166 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1167 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1170 static void check_ImageList_DrawIndirect_broken(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1171 UINT fStyle, UINT fState, DWORD Frame, UINT32 expected,
1172 UINT32 broken_expected, int line)
1174 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1175 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1176 bits[0] = 0x00FFFFFF;
1177 pImageList_DrawIndirect(&ildp);
1178 ok(colour_match(bits[0], expected) ||
1179 broken(colour_match(bits[0], broken_expected)),
1180 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1181 bits[0] & 0x00FFFFFF, expected, line);
1184 static void test_ImageList_DrawIndirect(void)
1186 HIMAGELIST himl = NULL;
1189 HBITMAP hbmOld = NULL, hbmDst = NULL;
1190 HBITMAP hbmMask = NULL, hbmInverseMask = NULL;
1191 HBITMAP hbmImage = NULL, hbmAlphaImage = NULL, hbmTransparentImage = NULL;
1192 int iImage = -1, iAlphaImage = -1, iTransparentImage = -1;
1194 UINT32 maskBits = 0x00000000, inverseMaskBits = 0xFFFFFFFF;
1195 int bpp, broken_value;
1197 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB,
1200 hdcDst = CreateCompatibleDC(0);
1201 ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
1204 bpp = GetDeviceCaps(hdcDst, BITSPIXEL);
1206 hbmMask = CreateBitmap(2, 1, 1, 1, &maskBits);
1207 ok(hbmMask != 0, "CreateBitmap failed\n");
1208 if(!hbmMask) goto cleanup;
1210 hbmInverseMask = CreateBitmap(2, 1, 1, 1, &inverseMaskBits);
1211 ok(hbmInverseMask != 0, "CreateBitmap failed\n");
1212 if(!hbmInverseMask) goto cleanup;
1214 himl = pImageList_Create(2, 1, ILC_COLOR32, 0, 1);
1215 ok(himl != 0, "ImageList_Create failed\n");
1216 if(!himl) goto cleanup;
1218 /* Add a no-alpha image */
1219 hbmImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x00ABCDEF);
1220 if(!hbmImage) goto cleanup;
1222 iImage = pImageList_Add(himl, hbmImage, hbmMask);
1223 ok(iImage != -1, "ImageList_Add failed\n");
1224 if(iImage == -1) goto cleanup;
1226 /* Add an alpha image */
1227 hbmAlphaImage = create_test_bitmap(hdcDst, 32, 0x89ABCDEF, 0x89ABCDEF);
1228 if(!hbmAlphaImage) goto cleanup;
1230 iAlphaImage = pImageList_Add(himl, hbmAlphaImage, hbmMask);
1231 ok(iAlphaImage != -1, "ImageList_Add failed\n");
1232 if(iAlphaImage == -1) goto cleanup;
1234 /* Add a transparent alpha image */
1235 hbmTransparentImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x89ABCDEF);
1236 if(!hbmTransparentImage) goto cleanup;
1238 iTransparentImage = pImageList_Add(himl, hbmTransparentImage, hbmMask);
1239 ok(iTransparentImage != -1, "ImageList_Add failed\n");
1240 if(iTransparentImage == -1) goto cleanup;
1243 bitmapInfo.bmiHeader.biBitCount = 32;
1244 hbmDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1245 ok (hbmDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1246 if (!hbmDst || !bits)
1248 hbmOld = SelectObject(hdcDst, hbmDst);
1250 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_NORMAL, 0x00ABCDEF, __LINE__);
1251 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_TRANSPARENT, 0x00ABCDEF, __LINE__);
1252 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x00D4D9DD, __LINE__);
1253 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1254 else broken_value = 0x00B4BDC4;
1255 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1256 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_MASK, 0x00ABCDEF, __LINE__);
1257 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_IMAGE, 0x00ABCDEF, __LINE__);
1258 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_PRESERVEALPHA, 0x00ABCDEF, __LINE__);
1260 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, 0x00D3E5F7, __LINE__);
1261 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_TRANSPARENT, 0x00D3E5F7, __LINE__);
1263 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1264 else broken_value = 0x009DA8B1;
1265 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1266 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1267 else broken_value = 0x008C99A3;
1268 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1269 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0x00D3E5F7, __LINE__);
1270 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0x00D3E5F7, __LINE__);
1271 todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__);
1273 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__);
1275 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCCOPY, 0x00ABCDEF, __LINE__);
1276 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCINVERT, 0x00543210, __LINE__);
1278 /* ILD_ROP is ignored when the image has an alpha channel */
1279 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCCOPY, 0x00D3E5F7, __LINE__);
1280 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCINVERT, 0x00D3E5F7, __LINE__);
1282 todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00CCCCCC, __LINE__);
1283 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00AFAFAF, 0x00F0F0F0, __LINE__);
1285 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_GLOW, 0, 0x00ABCDEF, __LINE__);
1286 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SHADOW, 0, 0x00ABCDEF, __LINE__);
1288 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00D5E6F7, __LINE__);
1289 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00E9F2FB, 0x00AEB7C0, __LINE__);
1290 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_NORMAL, 127, 0x00E9F2FB, 0x00D3E5F7, __LINE__);
1295 SelectObject(hdcDst, hbmOld);
1297 DeleteObject(hbmDst);
1303 DeleteObject(hbmMask);
1305 DeleteObject(hbmInverseMask);
1308 DeleteObject(hbmImage);
1310 DeleteObject(hbmAlphaImage);
1311 if(hbmTransparentImage)
1312 DeleteObject(hbmTransparentImage);
1316 ret = ImageList_Destroy(himl);
1317 ok(ret, "ImageList_Destroy failed\n");
1321 static void test_iimagelist(void)
1323 IImageList *imgl, *imgl2;
1328 if (!pHIMAGELIST_QueryInterface)
1330 win_skip("XP imagelist functions not available\n");
1334 /* test reference counting on destruction */
1335 imgl = (IImageList*)createImageList(32, 32);
1336 ret = IUnknown_AddRef(imgl);
1337 ok(ret == 2, "Expected 2, got %d\n", ret);
1338 ret = ImageList_Destroy((HIMAGELIST)imgl);
1339 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1340 ret = ImageList_Destroy((HIMAGELIST)imgl);
1341 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1342 ret = ImageList_Destroy((HIMAGELIST)imgl);
1343 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1345 imgl = (IImageList*)createImageList(32, 32);
1346 ret = IUnknown_AddRef(imgl);
1347 ok(ret == 2, "Expected 2, got %d\n", ret);
1348 ret = ImageList_Destroy((HIMAGELIST)imgl);
1349 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1350 ret = IImageList_Release(imgl);
1351 ok(ret == 0, "Expected 0, got %d\n", ret);
1352 ret = ImageList_Destroy((HIMAGELIST)imgl);
1353 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1355 /* ref counting, HIMAGELIST_QueryInterface adds a reference */
1356 imgl = (IImageList*)createImageList(32, 32);
1357 hr = pHIMAGELIST_QueryInterface((HIMAGELIST)imgl, &IID_IImageList, (void**)&imgl2);
1358 ok(hr == S_OK, "got 0x%08x\n", hr);
1359 ok(imgl2 == imgl, "got different pointer\n");
1360 ret = IImageList_Release(imgl);
1361 ok(ret == 1, "got %u\n", ret);
1362 IImageList_Release(imgl);
1364 if (!pImageList_CoCreateInstance)
1366 win_skip("Vista imagelist functions not available\n");
1370 hr = pImageList_CoCreateInstance(&CLSID_ImageList, NULL, &IID_IImageList, (void **) &imgl);
1371 ok(SUCCEEDED(hr), "ImageList_CoCreateInstance failed, hr=%x\n", hr);
1374 IImageList_Release(imgl);
1376 himl = createImageList(32, 32);
1381 hr = (pHIMAGELIST_QueryInterface)(himl, &IID_IImageList, (void **) &imgl);
1382 ok(SUCCEEDED(hr), "HIMAGELIST_QueryInterface failed, hr=%x\n", hr);
1385 IImageList_Release(imgl);
1387 ImageList_Destroy(himl);
1390 static void test_hotspot_v6(void)
1401 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
1402 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
1409 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
1410 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
1411 IImageList *imgl1, *imgl2;
1414 /* cast to IImageList */
1415 imgl1 = (IImageList *) himl1;
1416 imgl2 = (IImageList *) himl2;
1418 for (i = 0; i < HOTSPOTS_MAX; i++) {
1419 for (j = 0; j < HOTSPOTS_MAX; j++) {
1420 int dx1 = hotspots[i].dx;
1421 int dy1 = hotspots[i].dy;
1422 int dx2 = hotspots[j].dx;
1423 int dy2 = hotspots[j].dy;
1424 int correctx, correcty, newx, newy;
1426 IImageList *imglNew;
1429 hr = IImageList_BeginDrag(imgl1, 0, dx1, dy1);
1430 ok(SUCCEEDED(hr), "BeginDrag failed for { %d, %d }\n", dx1, dy1);
1431 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
1433 /* check merging the dragged image with a second image */
1434 hr = IImageList_SetDragCursorImage(imgl2, (IUnknown *) imgl2, 0, dx2, dy2);
1435 ok(SUCCEEDED(hr), "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
1436 dx1, dy1, dx2, dy2);
1437 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
1439 /* check new hotspot, it should be the same like the old one */
1440 hr = IImageList_GetDragImage(imgl2, NULL, &ppt, &IID_IImageList, (PVOID *) &imglNew);
1441 ok(SUCCEEDED(hr), "GetDragImage failed\n");
1442 ok(ppt.x == dx1 && ppt.y == dy1,
1443 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
1444 dx1, dy1, ppt.x, ppt.y);
1445 /* check size of new dragged image */
1446 IImageList_GetIconSize(imglNew, &newx, &newy);
1447 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
1448 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
1449 ok(newx == correctx && newy == correcty,
1450 "Expected drag image size [%d,%d] got [%d,%d]\n",
1451 correctx, correcty, newx, newy);
1452 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
1453 IImageList_EndDrag(imgl2);
1461 IImageList_Release(imgl2);
1462 IImageList_Release(imgl1);
1465 static void test_IImageList_Add_Remove(void)
1477 /* create an imagelist to play with */
1478 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1479 ok(himl != 0,"failed to create imagelist\n");
1481 imgl = (IImageList *) himl;
1483 /* load the icons to add to the image list */
1484 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1485 ok(hicon1 != 0, "no hicon1\n");
1486 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1487 ok(hicon2 != 0, "no hicon2\n");
1488 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1489 ok(hicon3 != 0, "no hicon3\n");
1491 /* remove when nothing exists */
1492 hr = IImageList_Remove(imgl, 0);
1493 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1495 /* removing everything from an empty imagelist should succeed */
1496 hr = IImageList_Remove(imgl, -1);
1497 ok(hr == S_OK, "removed nonexistent icon\n");
1501 ok( IImageList_ReplaceIcon(imgl, -1, hicon1, &ret) == S_OK && (ret == 0),"failed to add icon1\n");
1503 ok( IImageList_ReplaceIcon(imgl, -1, hicon2, &ret) == S_OK && (ret == 1),"failed to add icon2\n");
1505 ok( IImageList_ReplaceIcon(imgl, -1, hicon3, &ret) == S_OK && (ret == 2),"failed to add icon3\n");
1507 /* remove an index out of range */
1508 ok( IImageList_Remove(imgl, 4711) == E_INVALIDARG, "got 0x%08x\n", hr);
1511 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1512 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1513 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1515 /* remove one extra */
1516 ok( IImageList_Remove(imgl, 0) == E_INVALIDARG, "got 0x%08x\n", hr);
1518 IImageList_Release(imgl);
1519 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
1520 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
1521 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
1524 static void test_IImageList_Get_SetImageCount(void)
1531 /* create an imagelist to play with */
1532 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1533 ok(himl != 0,"failed to create imagelist\n");
1535 imgl = (IImageList *) himl;
1537 /* check SetImageCount/GetImageCount */
1538 hr = IImageList_SetImageCount(imgl, 3);
1539 ok(hr == S_OK, "got 0x%08x\n", hr);
1541 hr = IImageList_GetImageCount(imgl, &ret);
1542 ok(hr == S_OK && ret == 3, "invalid image count after increase\n");
1543 hr = IImageList_SetImageCount(imgl, 1);
1544 ok(hr == S_OK, "got 0x%08x\n", hr);
1546 hr = IImageList_GetImageCount(imgl, &ret);
1547 ok(hr == S_OK && ret == 1, "invalid image count after decrease to 1\n");
1548 hr = IImageList_SetImageCount(imgl, 0);
1549 ok(hr == S_OK, "got 0x%08x\n", hr);
1551 hr = IImageList_GetImageCount(imgl, &ret);
1552 ok(hr == S_OK && ret == 0, "invalid image count after decrease to 0\n");
1554 IImageList_Release(imgl);
1557 static void test_IImageList_Draw(void)
1566 IMAGELISTDRAWPARAMS imldp;
1572 hwndfortest = create_a_window();
1573 hdc = GetDC(hwndfortest);
1574 ok(hdc!=NULL, "couldn't get DC\n");
1576 /* create an imagelist to play with */
1577 himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
1578 ok(himl!=0,"failed to create imagelist\n");
1580 imgl = (IImageList *) himl;
1582 /* load the icons to add to the image list */
1583 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1584 ok(hbm1 != 0, "no bitmap 1\n");
1585 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1586 ok(hbm2 != 0, "no bitmap 2\n");
1587 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1588 ok(hbm3 != 0, "no bitmap 3\n");
1592 ok( IImageList_Add(imgl, hbm1, 0, &ret) == S_OK && (ret == 0), "failed to add bitmap 1\n");
1594 ok( IImageList_Add(imgl, hbm2, 0, &ret) == S_OK && (ret == 1), "failed to add bitmap 2\n");
1596 ok( IImageList_SetImageCount(imgl, 3) == S_OK, "Setimage count failed\n");
1597 ok( IImageList_Replace(imgl, 2, hbm3, 0) == S_OK, "failed to replace bitmap 3\n");
1601 /* crashes on native */
1602 IImageList_Draw(imgl, NULL);
1605 memset(&imldp, 0, sizeof (imldp));
1606 hr = IImageList_Draw(imgl, &imldp);
1607 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
1609 imldp.cbSize = IMAGELISTDRAWPARAMS_V3_SIZE;
1613 REDRAW(hwndfortest);
1616 imldp.fStyle = SRCCOPY;
1617 imldp.rgbBk = CLR_DEFAULT;
1618 imldp.rgbFg = CLR_DEFAULT;
1621 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1623 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1625 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1627 ok( IImageList_Draw(imgl, &imldp) == E_INVALIDARG, "should fail\n");
1630 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 1st bitmap\n");
1631 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 2nd bitmap\n");
1632 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 3rd bitmap\n");
1635 IImageList_Release(imgl);
1637 /* bitmaps should not be deleted by the imagelist */
1638 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
1639 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
1640 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
1642 ReleaseDC(hwndfortest, hdc);
1643 DestroyWindow(hwndfortest);
1646 static void test_IImageList_Merge(void)
1648 HIMAGELIST himl1, himl2;
1649 IImageList *imgl1, *imgl2, *merge;
1651 HWND hwnd = create_a_window();
1655 himl1 = ImageList_Create(32,32,0,0,3);
1656 ok(himl1 != NULL,"failed to create himl1\n");
1658 himl2 = ImageList_Create(32,32,0,0,3);
1659 ok(himl2 != NULL,"failed to create himl2\n");
1661 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1662 ok(hicon1 != NULL, "failed to create hicon1\n");
1664 if (!himl1 || !himl2 || !hicon1)
1667 /* cast to IImageList */
1668 imgl1 = (IImageList *) himl1;
1669 imgl2 = (IImageList *) himl2;
1672 ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (ret == 0),"add icon1 to himl2 failed\n");
1676 /* null cases that crash on native */
1677 IImageList_Merge(imgl1, -1, NULL, 0, 0, 0, &IID_IImageList, (void**)&merge);
1678 IImageList_Merge(imgl1, -1, (IUnknown*) imgl2, 0, 0, 0, &IID_IImageList, NULL);
1681 /* If himl1 has no images, merge still succeeds */
1682 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1683 ok(hr == S_OK, "merge himl1,-1 failed\n");
1684 if (hr == S_OK) IImageList_Release(merge);
1686 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1687 ok(hr == S_OK, "merge himl1,0 failed\n");
1688 if (hr == S_OK) IImageList_Release(merge);
1690 /* Same happens if himl2 is empty */
1691 IImageList_Release(imgl2);
1692 himl2 = ImageList_Create(32,32,0,0,3);
1693 ok(himl2 != NULL,"failed to recreate himl2\n");
1695 imgl2 = (IImageList *) himl2;
1697 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, -1, 0, 0, &IID_IImageList, (void **) &merge);
1698 ok(hr == S_OK, "merge himl2,-1 failed\n");
1699 if (hr == S_OK) IImageList_Release(merge);
1701 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1702 ok(hr == S_OK, "merge himl2,0 failed\n");
1703 if (hr == S_OK) IImageList_Release(merge);
1705 /* Now try merging an image with itself */
1707 ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (ret == 0),"re-add icon1 to himl2 failed\n");
1709 hr = IImageList_Merge(imgl2, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1710 ok(hr == S_OK, "merge himl2 with itself failed\n");
1711 if (hr == S_OK) IImageList_Release(merge);
1713 /* Try merging 2 different image lists */
1715 ok( IImageList_ReplaceIcon(imgl1, -1, hicon1, &ret) == S_OK && (ret == 0),"add icon1 to himl1 failed\n");
1717 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1718 ok(hr == S_OK, "merge himl1 with himl2 failed\n");
1719 if (hr == S_OK) IImageList_Release(merge);
1721 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 8, 16, &IID_IImageList, (void **) &merge);
1722 ok(hr == S_OK, "merge himl1 with himl2 8,16 failed\n");
1723 if (hr == S_OK) IImageList_Release(merge);
1725 IImageList_Release(imgl1);
1726 IImageList_Release(imgl2);
1728 DestroyIcon(hicon1);
1729 DestroyWindow(hwnd);
1732 static void test_iconsize(void)
1738 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1739 /* null pointers, not zero imagelist dimensions */
1740 ret = ImageList_GetIconSize(himl, NULL, NULL);
1741 ok(!ret, "got %d\n", ret);
1743 /* doesn't touch return pointers */
1745 ret = ImageList_GetIconSize(himl, &cx, NULL);
1746 ok(!ret, "got %d\n", ret);
1747 ok(cx == 0x1abe11ed, "got %d\n", cx);
1750 ret = ImageList_GetIconSize(himl, NULL, &cy);
1751 ok(!ret, "got %d\n", ret);
1752 ok(cy == 0x1abe11ed, "got %d\n", cy);
1754 ImageList_Destroy(himl);
1757 static void test_create(void)
1761 /* list with zero or negative image dimensions */
1762 himl = ImageList_Create(0, 0, ILC_COLOR16, 0, 3);
1763 ok(himl == NULL, "got %p\n", himl);
1765 himl = ImageList_Create(0, 16, ILC_COLOR16, 0, 3);
1766 ok(himl == NULL, "got %p\n", himl);
1768 himl = ImageList_Create(16, 0, ILC_COLOR16, 0, 3);
1769 ok(himl == NULL, "got %p\n", himl);
1771 himl = ImageList_Create(16, -1, ILC_COLOR16, 0, 3);
1772 ok(himl == NULL, "got %p\n", himl);
1774 himl = ImageList_Create(-1, 16, ILC_COLOR16, 0, 3);
1775 ok(himl == NULL, "got %p\n", himl);
1778 static void test_IImageList_Clone(void)
1780 IImageList *imgl, *imgl2;
1785 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1786 imgl = (IImageList*)himl;
1790 /* crashes on native */
1791 IImageList_Clone(imgl, &IID_IImageList, NULL);
1794 hr = IImageList_Clone(imgl, &IID_IImageList, (void**)&imgl2);
1795 ok(hr == S_OK, "got 0x%08x\n", hr);
1796 ref = IImageList_Release(imgl2);
1797 ok(ref == 0, "got %u\n", ref);
1799 IImageList_Release(imgl);
1802 static void test_IImageList_GetBkColor(void)
1809 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1810 imgl = (IImageList*)himl;
1814 /* crashes on native */
1815 IImageList_GetBkColor(imgl, NULL);
1818 hr = IImageList_GetBkColor(imgl, &color);
1819 ok(hr == S_OK, "got 0x%08x\n", hr);
1821 IImageList_Release(imgl);
1824 static void test_IImageList_SetBkColor(void)
1831 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1832 imgl = (IImageList*)himl;
1836 /* crashes on native */
1837 IImageList_SetBkColor(imgl, RGB(0, 0, 0), NULL);
1840 hr = IImageList_SetBkColor(imgl, CLR_NONE, &color);
1841 ok(hr == S_OK, "got 0x%08x\n", hr);
1843 hr = IImageList_SetBkColor(imgl, CLR_NONE, &color);
1844 ok(hr == S_OK, "got 0x%08x\n", hr);
1847 hr = IImageList_GetBkColor(imgl, &color);
1848 ok(hr == S_OK, "got 0x%08x\n", hr);
1849 ok(color == CLR_NONE, "got %x\n", color);
1851 IImageList_Release(imgl);
1854 static void test_IImageList_GetImageCount(void)
1861 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1862 imgl = (IImageList*)himl;
1866 /* crashes on native */
1867 IImageList_GetImageCount(imgl, NULL);
1871 hr = IImageList_GetImageCount(imgl, &count);
1872 ok(hr == S_OK, "got 0x%08x\n", hr);
1873 ok(count == 0, "got %d\n", count);
1875 IImageList_Release(imgl);
1878 static void test_IImageList_GetIconSize(void)
1885 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1886 imgl = (IImageList*)himl;
1888 hr = IImageList_GetIconSize(imgl, NULL, NULL);
1889 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1891 hr = IImageList_GetIconSize(imgl, &cx, NULL);
1892 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1894 hr = IImageList_GetIconSize(imgl, NULL, &cy);
1895 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1897 IImageList_Release(imgl);
1900 START_TEST(imagelist)
1902 ULONG_PTR ctx_cookie;
1905 HMODULE hComCtl32 = GetModuleHandle("comctl32.dll");
1906 pImageList_Create = NULL; /* These are not needed for non-v6.0 tests*/
1907 pImageList_Add = NULL;
1908 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
1909 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
1911 hinst = GetModuleHandleA(NULL);
1913 InitCommonControls();
1919 test_DrawIndirect();
1921 test_imagelist_storage();
1924 FreeLibrary(hComCtl32);
1926 /* Now perform v6 tests */
1928 if (!load_v6_module(&ctx_cookie, &hCtx))
1931 /* Reload comctl32 */
1932 hComCtl32 = LoadLibraryA("comctl32.dll");
1933 pImageList_Create = (void*)GetProcAddress(hComCtl32, "ImageList_Create");
1934 pImageList_Add = (void*)GetProcAddress(hComCtl32, "ImageList_Add");
1935 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
1936 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
1937 pImageList_CoCreateInstance = (void*)GetProcAddress(hComCtl32, "ImageList_CoCreateInstance");
1938 pHIMAGELIST_QueryInterface = (void*)GetProcAddress(hComCtl32, "HIMAGELIST_QueryInterface");
1940 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1943 test_ImageList_DrawIndirect();
1944 test_shell_imagelist();
1948 test_IImageList_Add_Remove();
1949 test_IImageList_Get_SetImageCount();
1950 test_IImageList_Draw();
1951 test_IImageList_Merge();
1952 test_IImageList_Clone();
1953 test_IImageList_GetBkColor();
1954 test_IImageList_SetBkColor();
1955 test_IImageList_GetImageCount();
1956 test_IImageList_GetIconSize();
1960 unload_v6_module(ctx_cookie, hCtx);