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 )
745 case 1: words = (width + 31) / 32; break;
746 case 4: words = (width + 7) / 8; break;
747 case 8: words = (width + 3) / 4; break;
749 case 16: words = (width + 1) / 2; break;
750 case 24: words = (width * 3 + 3)/4; break;
751 case 32: words = width; break;
755 trace("Unknown depth %d, please report.\n", bpp );
762 static void check_bitmap_data(const char *bm_data, ULONG bm_data_size,
763 INT width, INT height, INT bpp,
766 const BITMAPFILEHEADER *bmfh = (const BITMAPFILEHEADER *)bm_data;
767 const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)(bm_data + sizeof(*bmfh));
768 ULONG hdr_size, image_size;
770 hdr_size = sizeof(*bmfh) + sizeof(*bmih);
771 if (bmih->biBitCount <= 8) hdr_size += (1 << bpp) * sizeof(RGBQUAD);
773 ok(bmfh->bfType == (('M' << 8) | 'B'), "wrong bfType 0x%02x\n", bmfh->bfType);
774 ok(bmfh->bfSize == hdr_size, "wrong bfSize 0x%02x\n", bmfh->bfSize);
775 ok(bmfh->bfReserved1 == 0, "wrong bfReserved1 0x%02x\n", bmfh->bfReserved1);
776 ok(bmfh->bfReserved2 == 0, "wrong bfReserved2 0x%02x\n", bmfh->bfReserved2);
777 ok(bmfh->bfOffBits == hdr_size, "wrong bfOffBits 0x%02x\n", bmfh->bfOffBits);
779 ok(bmih->biSize == sizeof(*bmih), "wrong biSize %d\n", bmih->biSize);
780 ok(bmih->biWidth == width, "wrong biWidth %d (expected %d)\n", bmih->biWidth, width);
781 ok(bmih->biHeight == height, "wrong biHeight %d (expected %d)\n", bmih->biHeight, height);
782 ok(bmih->biPlanes == 1, "wrong biPlanes %d\n", bmih->biPlanes);
783 ok(bmih->biBitCount == bpp, "wrong biBitCount %d\n", bmih->biBitCount);
785 image_size = DIB_GetWidthBytes(bmih->biWidth, bmih->biBitCount) * bmih->biHeight;
786 ok(bmih->biSizeImage == image_size, "wrong biSizeImage %u\n", bmih->biSizeImage);
791 sprintf(fname, "bmp_%s.bmp", comment);
792 f = fopen(fname, "wb");
793 fwrite(bm_data, 1, bm_data_size, f);
799 static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max, INT grow)
801 const ILHEAD *ilh = (const ILHEAD *)ilh_data;
803 ok(ilh->usMagic == IMAGELIST_MAGIC, "wrong usMagic %4x (expected %02x)\n", ilh->usMagic, IMAGELIST_MAGIC);
804 ok(ilh->usVersion == 0x101, "wrong usVersion %x (expected 0x101)\n", ilh->usVersion);
805 ok(ilh->cCurImage == cur, "wrong cCurImage %d (expected %d)\n", ilh->cCurImage, cur);
806 ok(ilh->cMaxImage == max, "wrong cMaxImage %d (expected %d)\n", ilh->cMaxImage, max);
807 ok(ilh->cGrow == grow, "wrong cGrow %d (expected %d)\n", ilh->cGrow, grow);
808 ok(ilh->cx == cx, "wrong cx %d (expected %d)\n", ilh->cx, cx);
809 ok(ilh->cy == cy, "wrong cy %d (expected %d)\n", ilh->cy, cy);
810 ok(ilh->bkcolor == CLR_NONE, "wrong bkcolor %x\n", ilh->bkcolor);
811 ok(ilh->flags == ILC_COLOR24, "wrong flags %04x\n", ilh->flags);
812 ok(ilh->ovls[0] == -1 ||
813 ilh->ovls[0] == 0, /* win95 */
814 "wrong ovls[0] %04x\n", ilh->ovls[0]);
815 ok(ilh->ovls[1] == -1 ||
816 ilh->ovls[1] == 0, /* win95 */
817 "wrong ovls[1] %04x\n", ilh->ovls[1]);
818 ok(ilh->ovls[2] == -1 ||
819 ilh->ovls[2] == 0, /* win95 */
820 "wrong ovls[2] %04x\n", ilh->ovls[2]);
821 ok(ilh->ovls[3] == -1 ||
822 ilh->ovls[3] == 0, /* win95 */
823 "wrong ovls[3] %04x\n", ilh->ovls[3]);
826 static HBITMAP create_bitmap(INT cx, INT cy, COLORREF color, const char *comment)
829 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
830 BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
831 HBITMAP hbmp, hbmp_old;
833 RECT rc = { 0, 0, cx, cy };
835 hdc = CreateCompatibleDC(0);
837 memset(bmi, 0, sizeof(*bmi));
838 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
839 bmi->bmiHeader.biHeight = cx;
840 bmi->bmiHeader.biWidth = cy;
841 bmi->bmiHeader.biBitCount = 24;
842 bmi->bmiHeader.biPlanes = 1;
843 bmi->bmiHeader.biCompression = BI_RGB;
844 hbmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
846 hbmp_old = SelectObject(hdc, hbmp);
848 hbrush = CreateSolidBrush(color);
849 FillRect(hdc, &rc, hbrush);
850 DeleteObject(hbrush);
852 DrawText(hdc, comment, -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
854 SelectObject(hdc, hbmp_old);
860 #define iml_clear_stream_data() \
861 HeapFree(GetProcessHeap(), 0, Test_Stream.iml_data); \
862 Test_Stream.iml_data = NULL; \
863 Test_Stream.iml_data_size = 0;
865 static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max, INT grow,
866 INT width, INT height, INT bpp, const char *comment)
870 trace("%s\n", comment);
872 ret = ImageList_GetImageCount(himl);
873 ok(ret == cur, "expected image count %d got %d\n", cur, ret);
875 ret = ImageList_GetIconSize(himl, &cxx, &cyy);
876 ok(ret, "ImageList_GetIconSize failed\n");
877 ok(cxx == cx, "wrong cx %d (expected %d)\n", cxx, cx);
878 ok(cyy == cy, "wrong cy %d (expected %d)\n", cyy, cy);
880 iml_clear_stream_data();
881 ret = ImageList_Write(himl, &Test_Stream.is);
882 ok(ret, "ImageList_Write failed\n");
884 ok(Test_Stream.iml_data != 0, "ImageList_Write didn't write any data\n");
885 ok(Test_Stream.iml_data_size > sizeof(ILHEAD), "ImageList_Write wrote not enough data\n");
887 check_ilhead_data(Test_Stream.iml_data, cx, cy, cur, max, grow);
888 check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD),
889 Test_Stream.iml_data_size - sizeof(ILHEAD),
890 width, height, bpp, comment);
893 static void image_list_init(HIMAGELIST himl)
898 static const struct test_data
901 INT cx, cy, cur, max, grow, width, height, bpp;
905 { 255, BMP_CX, BMP_CX, 1, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "total 1" },
906 { 170, BMP_CX, BMP_CX, 2, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 2" },
907 { 85, BMP_CX, BMP_CX, 3, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 3" },
908 { 0, BMP_CX, BMP_CX, 4, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 4" },
909 { 0, BMP_CX, BMP_CX, 5, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 5" },
910 { 85, BMP_CX, BMP_CX, 6, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 6" },
911 { 170, BMP_CX, BMP_CX, 7, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 7" },
912 { 255, BMP_CX, BMP_CX, 8, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 8" },
913 { 255, BMP_CX, BMP_CX, 9, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 9" },
914 { 170, BMP_CX, BMP_CX, 10, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 10" },
915 { 85, BMP_CX, BMP_CX, 11, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 11" },
916 { 0, BMP_CX, BMP_CX, 12, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 12" },
917 { 0, BMP_CX, BMP_CX, 13, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 13" },
918 { 85, BMP_CX, BMP_CX, 14, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 14" },
919 { 170, BMP_CX, BMP_CX, 15, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 15" },
920 { 255, BMP_CX, BMP_CX, 16, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 16" },
921 { 255, BMP_CX, BMP_CX, 17, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 17" },
922 { 170, BMP_CX, BMP_CX, 18, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 18" },
923 { 85, BMP_CX, BMP_CX, 19, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 19" },
924 { 0, BMP_CX, BMP_CX, 20, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 20" },
925 { 0, BMP_CX, BMP_CX, 21, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 21" },
926 { 85, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 22" },
927 { 170, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 23" },
928 { 255, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 24" }
931 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "total 0");
933 #define add_bitmap(grey) \
934 sprintf(comment, "%d", n++); \
935 hbm = create_bitmap(BMP_CX, BMP_CX, RGB((grey),(grey),(grey)), comment); \
936 ImageList_Add(himl, hbm, NULL); \
939 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
941 add_bitmap(td[i].grey);
942 check_iml_data(himl, td[i].cx, td[i].cy, td[i].cur, td[i].max, td[i].grow,
943 td[i].width, td[i].height, td[i].bpp, td[i].comment);
948 static void test_imagelist_storage(void)
954 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 1, 1);
955 ok(himl != 0, "ImageList_Create failed\n");
957 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "empty");
959 image_list_init(himl);
960 check_iml_data(himl, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "orig");
962 ret = ImageList_Remove(himl, 4);
963 ok(ret, "ImageList_Remove failed\n");
964 check_iml_data(himl, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "1");
966 ret = ImageList_Remove(himl, 5);
967 ok(ret, "ImageList_Remove failed\n");
968 check_iml_data(himl, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "2");
970 ret = ImageList_Remove(himl, 6);
971 ok(ret, "ImageList_Remove failed\n");
972 check_iml_data(himl, BMP_CX, BMP_CX, 21, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "3");
974 ret = ImageList_Remove(himl, 7);
975 ok(ret, "ImageList_Remove failed\n");
976 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "4");
978 ret = ImageList_Remove(himl, -2);
979 ok(!ret, "ImageList_Remove(-2) should fail\n");
980 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "5");
982 ret = ImageList_Remove(himl, 20);
983 ok(!ret, "ImageList_Remove(20) should fail\n");
984 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "6");
986 ret = ImageList_Remove(himl, -1);
987 ok(ret, "ImageList_Remove(-1) failed\n");
988 check_iml_data(himl, BMP_CX, BMP_CX, 0, 4, 4, BMP_CX * 4, BMP_CX * 1, 24, "7");
990 ret = ImageList_Destroy(himl);
991 ok(ret, "ImageList_Destroy failed\n");
993 iml_clear_stream_data();
995 /* test ImageList_Create storage allocation */
997 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 0, 32);
998 ok(himl != 0, "ImageList_Create failed\n");
999 check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 32, BMP_CX * 4, BMP_CX * 1, 24, "init 0 grow 32");
1000 hbm = create_bitmap(BMP_CX * 9, BMP_CX, 0, "9");
1001 ret = ImageList_Add(himl, hbm, NULL);
1002 ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
1003 check_iml_data(himl, BMP_CX, BMP_CX, 1, 34, 32, BMP_CX * 4, BMP_CX * 9, 24, "add 1 x 9");
1005 ret = ImageList_Destroy(himl);
1006 ok(ret, "ImageList_Destroy failed\n");
1007 iml_clear_stream_data();
1009 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 4);
1010 ok(himl != 0, "ImageList_Create failed\n");
1011 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, 24, "init 4 grow 4");
1012 hbm = create_bitmap(BMP_CX, BMP_CX * 9, 0, "9");
1013 ret = ImageList_Add(himl, hbm, NULL);
1014 ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
1015 check_iml_data(himl, BMP_CX, BMP_CX, 9, 15, 4, BMP_CX * 4, BMP_CX * 4, 24, "add 9 x 1");
1016 ret = ImageList_Add(himl, hbm, NULL);
1017 ok(ret == 9, "ImageList_Add returned %d, expected 9\n", ret);
1018 check_iml_data(himl, BMP_CX, BMP_CX, 18, 25, 4, BMP_CX * 4, BMP_CX * 7, 24, "add 9 x 1");
1020 ret = ImageList_Destroy(himl);
1021 ok(ret, "ImageList_Destroy failed\n");
1022 iml_clear_stream_data();
1024 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 207, 209);
1025 ok(himl != 0, "ImageList_Create failed\n");
1026 check_iml_data(himl, BMP_CX, BMP_CX, 0, 208, 212, BMP_CX * 4, BMP_CX * 52, 24, "init 207 grow 209");
1027 ret = ImageList_Destroy(himl);
1028 ok(ret, "ImageList_Destroy failed\n");
1029 iml_clear_stream_data();
1031 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 209, 207);
1032 ok(himl != 0, "ImageList_Create failed\n");
1033 check_iml_data(himl, BMP_CX, BMP_CX, 0, 210, 208, BMP_CX * 4, BMP_CX * 53, 24, "init 209 grow 207");
1034 ret = ImageList_Destroy(himl);
1035 ok(ret, "ImageList_Destroy failed\n");
1036 iml_clear_stream_data();
1038 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 14, 4);
1039 ok(himl != 0, "ImageList_Create failed\n");
1040 check_iml_data(himl, BMP_CX, BMP_CX, 0, 15, 4, BMP_CX * 4, BMP_CX * 4, 24, "init 14 grow 4");
1041 ret = ImageList_Destroy(himl);
1042 ok(ret, "ImageList_Destroy failed\n");
1043 iml_clear_stream_data();
1045 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 5, 9);
1046 ok(himl != 0, "ImageList_Create failed\n");
1047 check_iml_data(himl, BMP_CX, BMP_CX, 0, 6, 12, BMP_CX * 4, BMP_CX * 2, 24, "init 5 grow 9");
1048 ret = ImageList_Destroy(himl);
1049 ok(ret, "ImageList_Destroy failed\n");
1050 iml_clear_stream_data();
1052 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 9, 5);
1053 ok(himl != 0, "ImageList_Create failed\n");
1054 check_iml_data(himl, BMP_CX, BMP_CX, 0, 10, 8, BMP_CX * 4, BMP_CX * 3, 24, "init 9 grow 5");
1055 ret = ImageList_Destroy(himl);
1056 ok(ret, "ImageList_Destroy failed\n");
1057 iml_clear_stream_data();
1059 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 2, 4);
1060 ok(himl != 0, "ImageList_Create failed\n");
1061 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX * 1, 24, "init 2 grow 4");
1062 ret = ImageList_Destroy(himl);
1063 ok(ret, "ImageList_Destroy failed\n");
1064 iml_clear_stream_data();
1066 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 2);
1067 ok(himl != 0, "ImageList_Create failed\n");
1068 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, 24, "init 4 grow 2");
1069 ret = ImageList_Destroy(himl);
1070 ok(ret, "ImageList_Destroy failed\n");
1071 iml_clear_stream_data();
1074 static void test_shell_imagelist(void)
1076 BOOL (WINAPI *pSHGetImageList)(INT, REFIID, void**);
1077 IImageList *iml = NULL;
1084 /* Try to load function from shell32 */
1085 hShell32 = LoadLibrary("shell32.dll");
1086 pSHGetImageList = (void*)GetProcAddress(hShell32, (LPCSTR) 727);
1088 if (!pSHGetImageList)
1090 win_skip("SHGetImageList not available, skipping test\n");
1094 /* Get system image list */
1095 hr = (pSHGetImageList)(SHIL_SYSSMALL, &IID_IImageList, (void**)&iml);
1097 ok(SUCCEEDED(hr), "SHGetImageList failed, hr=%x\n", hr);
1102 IImageList_GetImageCount(iml, &out);
1103 ok(out > 0, "IImageList_GetImageCount returned out <= 0\n");
1105 /* Fetch the small icon size */
1106 cx = GetSystemMetrics(SM_CXSMICON);
1107 cy = GetSystemMetrics(SM_CYSMICON);
1109 /* Check icon size matches */
1110 IImageList_GetImageRect(iml, 0, &rect);
1111 ok(((rect.right == cx) && (rect.bottom == cy)),
1112 "IImageList_GetImageRect returned r:%d,b:%d\n",
1113 rect.right, rect.bottom);
1115 IImageList_Release(iml);
1116 FreeLibrary(hShell32);
1119 static HBITMAP create_test_bitmap(HDC hdc, int bpp, UINT32 pixel1, UINT32 pixel2)
1122 UINT32 *buffer = NULL;
1123 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, bpp, BI_RGB,
1126 hBitmap = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, NULL, 0);
1127 ok(hBitmap != NULL && buffer != NULL, "CreateDIBSection failed.\n");
1129 if(!hBitmap || !buffer)
1131 DeleteObject(hBitmap);
1141 static BOOL colour_match(UINT32 x, UINT32 y)
1143 const INT32 tolerance = 8;
1145 const INT32 dr = abs((INT32)(x & 0x000000FF) - (INT32)(y & 0x000000FF));
1146 const INT32 dg = abs((INT32)((x & 0x0000FF00) >> 8) - (INT32)((y & 0x0000FF00) >> 8));
1147 const INT32 db = abs((INT32)((x & 0x00FF0000) >> 16) - (INT32)((y & 0x00FF0000) >> 16));
1149 return (dr <= tolerance && dg <= tolerance && db <= tolerance);
1152 static void check_ImageList_DrawIndirect(IMAGELISTDRAWPARAMS *ildp, UINT32 *bits,
1153 UINT32 expected, int line)
1155 bits[0] = 0x00FFFFFF;
1156 pImageList_DrawIndirect(ildp);
1157 ok(colour_match(bits[0], expected),
1158 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1159 bits[0] & 0x00FFFFFF, expected, line);
1163 static void check_ImageList_DrawIndirect_fStyle(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1164 UINT fStyle, UINT32 expected, int line)
1166 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1167 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, ILS_NORMAL, 0, 0x00000000};
1168 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1171 static void check_ImageList_DrawIndirect_ILD_ROP(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1172 DWORD dwRop, UINT32 expected, int line)
1174 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1175 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_IMAGE | ILD_ROP, dwRop, ILS_NORMAL, 0, 0x00000000};
1176 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1179 static void check_ImageList_DrawIndirect_fState(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i, UINT fStyle,
1180 UINT fState, DWORD Frame, UINT32 expected, int line)
1182 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1183 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1184 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1187 static void check_ImageList_DrawIndirect_broken(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1188 UINT fStyle, UINT fState, DWORD Frame, UINT32 expected,
1189 UINT32 broken_expected, int line)
1191 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1192 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1193 bits[0] = 0x00FFFFFF;
1194 pImageList_DrawIndirect(&ildp);
1195 ok(colour_match(bits[0], expected) ||
1196 broken(colour_match(bits[0], broken_expected)),
1197 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1198 bits[0] & 0x00FFFFFF, expected, line);
1201 static void test_ImageList_DrawIndirect(void)
1203 HIMAGELIST himl = NULL;
1206 HBITMAP hbmOld = NULL, hbmDst = NULL;
1207 HBITMAP hbmMask = NULL, hbmInverseMask = NULL;
1208 HBITMAP hbmImage = NULL, hbmAlphaImage = NULL, hbmTransparentImage = NULL;
1209 int iImage = -1, iAlphaImage = -1, iTransparentImage = -1;
1211 UINT32 maskBits = 0x00000000, inverseMaskBits = 0xFFFFFFFF;
1213 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB,
1216 hdcDst = CreateCompatibleDC(0);
1217 ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
1221 hbmMask = CreateBitmap(2, 1, 1, 1, &maskBits);
1222 ok(hbmMask != 0, "CreateBitmap failed\n");
1223 if(!hbmMask) goto cleanup;
1225 hbmInverseMask = CreateBitmap(2, 1, 1, 1, &inverseMaskBits);
1226 ok(hbmInverseMask != 0, "CreateBitmap failed\n");
1227 if(!hbmInverseMask) goto cleanup;
1229 himl = pImageList_Create(2, 1, ILC_COLOR32, 0, 1);
1230 ok(himl != 0, "ImageList_Create failed\n");
1231 if(!himl) goto cleanup;
1233 /* Add a no-alpha image */
1234 hbmImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x00ABCDEF);
1235 if(!hbmImage) goto cleanup;
1237 iImage = pImageList_Add(himl, hbmImage, hbmMask);
1238 ok(iImage != -1, "ImageList_Add failed\n");
1239 if(iImage == -1) goto cleanup;
1241 /* Add an alpha image */
1242 hbmAlphaImage = create_test_bitmap(hdcDst, 32, 0x89ABCDEF, 0x89ABCDEF);
1243 if(!hbmAlphaImage) goto cleanup;
1245 iAlphaImage = pImageList_Add(himl, hbmAlphaImage, hbmMask);
1246 ok(iAlphaImage != -1, "ImageList_Add failed\n");
1247 if(iAlphaImage == -1) goto cleanup;
1249 /* Add a transparent alpha image */
1250 hbmTransparentImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x89ABCDEF);
1251 if(!hbmTransparentImage) goto cleanup;
1253 iTransparentImage = pImageList_Add(himl, hbmTransparentImage, hbmMask);
1254 ok(iTransparentImage != -1, "ImageList_Add failed\n");
1255 if(iTransparentImage == -1) goto cleanup;
1258 bitmapInfo.bmiHeader.biBitCount = 32;
1259 hbmDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1260 ok (hbmDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1261 if (!hbmDst || !bits)
1263 hbmOld = SelectObject(hdcDst, hbmDst);
1265 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_NORMAL, 0x00ABCDEF, __LINE__);
1266 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_TRANSPARENT, 0x00ABCDEF, __LINE__);
1267 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x00D4D9DD, __LINE__);
1268 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, 0x00B4BDC4, __LINE__);
1269 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_MASK, 0x00ABCDEF, __LINE__);
1270 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_IMAGE, 0x00ABCDEF, __LINE__);
1271 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_PRESERVEALPHA, 0x00ABCDEF, __LINE__);
1273 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, 0x00D3E5F7, __LINE__);
1274 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_TRANSPARENT, 0x00D3E5F7, __LINE__);
1277 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x009DA8B1, __LINE__);
1278 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, 0x008C99A3, __LINE__);
1281 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0x00D3E5F7, __LINE__);
1282 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0x00D3E5F7, __LINE__);
1283 todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__);
1285 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__);
1287 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCCOPY, 0x00ABCDEF, __LINE__);
1288 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCINVERT, 0x00543210, __LINE__);
1290 /* ILD_ROP is ignored when the image has an alpha channel */
1291 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCCOPY, 0x00D3E5F7, __LINE__);
1292 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCINVERT, 0x00D3E5F7, __LINE__);
1294 todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00CCCCCC, __LINE__);
1295 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00AFAFAF, 0x00F0F0F0, __LINE__);
1297 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_GLOW, 0, 0x00ABCDEF, __LINE__);
1298 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SHADOW, 0, 0x00ABCDEF, __LINE__);
1300 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00D5E6F7, __LINE__);
1301 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00E9F2FB, 0x00AEB7C0, __LINE__);
1302 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_NORMAL, 127, 0x00E9F2FB, 0x00D3E5F7, __LINE__);
1307 SelectObject(hdcDst, hbmOld);
1309 DeleteObject(hbmDst);
1315 DeleteObject(hbmMask);
1317 DeleteObject(hbmInverseMask);
1320 DeleteObject(hbmImage);
1322 DeleteObject(hbmAlphaImage);
1323 if(hbmTransparentImage)
1324 DeleteObject(hbmTransparentImage);
1328 ret = ImageList_Destroy(himl);
1329 ok(ret, "ImageList_Destroy failed\n");
1333 static void test_iimagelist(void)
1340 if (!pHIMAGELIST_QueryInterface)
1342 win_skip("XP imagelist functions not available\n");
1346 /* test reference counting on destruction */
1347 imgl = (IImageList*)createImageList(32, 32);
1348 ret = IUnknown_AddRef(imgl);
1349 ok(ret == 2, "Expected 2, got %d\n", ret);
1350 ret = ImageList_Destroy((HIMAGELIST)imgl);
1351 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1352 ret = ImageList_Destroy((HIMAGELIST)imgl);
1353 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1354 ret = ImageList_Destroy((HIMAGELIST)imgl);
1355 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1357 imgl = (IImageList*)createImageList(32, 32);
1358 ret = IUnknown_AddRef(imgl);
1359 ok(ret == 2, "Expected 2, got %d\n", ret);
1360 ret = ImageList_Destroy((HIMAGELIST)imgl);
1361 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1362 ret = IImageList_Release(imgl);
1363 ok(ret == 0, "Expected 0, got %d\n", ret);
1364 ret = ImageList_Destroy((HIMAGELIST)imgl);
1365 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1367 if (!pImageList_CoCreateInstance)
1369 win_skip("Vista imagelist functions not available\n");
1373 hr = pImageList_CoCreateInstance(&CLSID_ImageList, NULL, &IID_IImageList, (void **) &imgl);
1374 ok(SUCCEEDED(hr), "ImageList_CoCreateInstance failed, hr=%x\n", hr);
1377 IImageList_Release(imgl);
1379 himl = createImageList(32, 32);
1384 hr = (pHIMAGELIST_QueryInterface)(himl, &IID_IImageList, (void **) &imgl);
1385 ok(SUCCEEDED(hr), "HIMAGELIST_QueryInterface failed, hr=%x\n", hr);
1388 IImageList_Release(imgl);
1390 ImageList_Destroy(himl);
1393 static void test_hotspot_v6(void)
1404 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
1405 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
1412 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
1413 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
1414 IImageList *imgl1, *imgl2;
1417 /* cast to IImageList */
1418 imgl1 = (IImageList *) himl1;
1419 imgl2 = (IImageList *) himl2;
1421 for (i = 0; i < HOTSPOTS_MAX; i++) {
1422 for (j = 0; j < HOTSPOTS_MAX; j++) {
1423 int dx1 = hotspots[i].dx;
1424 int dy1 = hotspots[i].dy;
1425 int dx2 = hotspots[j].dx;
1426 int dy2 = hotspots[j].dy;
1427 int correctx, correcty, newx, newy;
1429 IImageList *imglNew;
1432 hr = IImageList_BeginDrag(imgl1, 0, dx1, dy1);
1433 ok(SUCCEEDED(hr), "BeginDrag failed for { %d, %d }\n", dx1, dy1);
1434 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
1436 /* check merging the dragged image with a second image */
1437 hr = IImageList_SetDragCursorImage(imgl2, (IUnknown *) imgl2, 0, dx2, dy2);
1438 ok(SUCCEEDED(hr), "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
1439 dx1, dy1, dx2, dy2);
1440 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
1442 /* check new hotspot, it should be the same like the old one */
1443 hr = IImageList_GetDragImage(imgl2, NULL, &ppt, &IID_IImageList, (PVOID *) &imglNew);
1444 ok(SUCCEEDED(hr), "GetDragImage failed\n");
1445 ok(ppt.x == dx1 && ppt.y == dy1,
1446 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
1447 dx1, dy1, ppt.x, ppt.y);
1448 /* check size of new dragged image */
1449 IImageList_GetIconSize(imglNew, &newx, &newy);
1450 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
1451 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
1452 ok(newx == correctx && newy == correcty,
1453 "Expected drag image size [%d,%d] got [%d,%d]\n",
1454 correctx, correcty, newx, newy);
1455 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
1456 IImageList_EndDrag(imgl2);
1464 IImageList_Release(imgl2);
1465 IImageList_Release(imgl1);
1468 static void test_IImageList_Add_Remove(void)
1480 /* create an imagelist to play with */
1481 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1482 ok(himl != 0,"failed to create imagelist\n");
1484 imgl = (IImageList *) himl;
1486 /* load the icons to add to the image list */
1487 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1488 ok(hicon1 != 0, "no hicon1\n");
1489 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1490 ok(hicon2 != 0, "no hicon2\n");
1491 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1492 ok(hicon3 != 0, "no hicon3\n");
1494 /* remove when nothing exists */
1495 hr = IImageList_Remove(imgl, 0);
1496 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1498 /* removing everything from an empty imagelist should succeed */
1499 hr = IImageList_Remove(imgl, -1);
1500 ok(hr == S_OK, "removed nonexistent icon\n");
1504 ok( IImageList_ReplaceIcon(imgl, -1, hicon1, &ret) == S_OK && (ret == 0),"failed to add icon1\n");
1506 ok( IImageList_ReplaceIcon(imgl, -1, hicon2, &ret) == S_OK && (ret == 1),"failed to add icon2\n");
1508 ok( IImageList_ReplaceIcon(imgl, -1, hicon3, &ret) == S_OK && (ret == 2),"failed to add icon3\n");
1510 /* remove an index out of range */
1511 ok( IImageList_Remove(imgl, 4711) == E_INVALIDARG, "got 0x%08x\n", hr);
1514 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1515 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1516 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1518 /* remove one extra */
1519 ok( IImageList_Remove(imgl, 0) == E_INVALIDARG, "got 0x%08x\n", hr);
1521 IImageList_Release(imgl);
1522 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
1523 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
1524 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
1527 static void test_IImageList_Get_SetImageCount(void)
1534 /* create an imagelist to play with */
1535 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1536 ok(himl != 0,"failed to create imagelist\n");
1538 imgl = (IImageList *) himl;
1540 /* check SetImageCount/GetImageCount */
1541 hr = IImageList_SetImageCount(imgl, 3);
1542 ok(hr == S_OK, "got 0x%08x\n", hr);
1544 hr = IImageList_GetImageCount(imgl, &ret);
1545 ok(hr == S_OK && ret == 3, "invalid image count after increase\n");
1546 hr = IImageList_SetImageCount(imgl, 1);
1547 ok(hr == S_OK, "got 0x%08x\n", hr);
1549 hr = IImageList_GetImageCount(imgl, &ret);
1550 ok(hr == S_OK && ret == 1, "invalid image count after decrease to 1\n");
1551 hr = IImageList_SetImageCount(imgl, 0);
1552 ok(hr == S_OK, "got 0x%08x\n", hr);
1554 hr = IImageList_GetImageCount(imgl, &ret);
1555 ok(hr == S_OK && ret == 0, "invalid image count after decrease to 0\n");
1557 IImageList_Release(imgl);
1560 static void test_IImageList_Draw(void)
1569 IMAGELISTDRAWPARAMS imldp;
1575 hwndfortest = create_a_window();
1576 hdc = GetDC(hwndfortest);
1577 ok(hdc!=NULL, "couldn't get DC\n");
1579 /* create an imagelist to play with */
1580 himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
1581 ok(himl!=0,"failed to create imagelist\n");
1583 imgl = (IImageList *) himl;
1585 /* load the icons to add to the image list */
1586 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1587 ok(hbm1 != 0, "no bitmap 1\n");
1588 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1589 ok(hbm2 != 0, "no bitmap 2\n");
1590 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1591 ok(hbm3 != 0, "no bitmap 3\n");
1595 ok( IImageList_Add(imgl, hbm1, 0, &ret) == S_OK && (ret == 0), "failed to add bitmap 1\n");
1597 ok( IImageList_Add(imgl, hbm2, 0, &ret) == S_OK && (ret == 1), "failed to add bitmap 2\n");
1599 ok( IImageList_SetImageCount(imgl, 3) == S_OK, "Setimage count failed\n");
1600 ok( IImageList_Replace(imgl, 2, hbm3, 0) == S_OK, "failed to replace bitmap 3\n");
1604 /* crashes on native */
1605 hr = IImageList_Draw(imgl, NULL);
1608 memset(&imldp, 0, sizeof (imldp));
1609 hr = IImageList_Draw(imgl, &imldp);
1610 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
1612 imldp.cbSize = IMAGELISTDRAWPARAMS_V3_SIZE;
1616 REDRAW(hwndfortest);
1619 imldp.fStyle = SRCCOPY;
1620 imldp.rgbBk = CLR_DEFAULT;
1621 imldp.rgbFg = CLR_DEFAULT;
1624 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1626 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1628 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1630 ok( IImageList_Draw(imgl, &imldp) == E_INVALIDARG, "should fail\n");
1633 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 1st bitmap\n");
1634 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 2nd bitmap\n");
1635 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 3rd bitmap\n");
1638 IImageList_Release(imgl);
1640 /* bitmaps should not be deleted by the imagelist */
1641 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
1642 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
1643 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
1645 ReleaseDC(hwndfortest, hdc);
1646 DestroyWindow(hwndfortest);
1649 static void test_IImageList_Merge(void)
1651 HIMAGELIST himl1, himl2;
1652 IImageList *imgl1, *imgl2, *merge;
1654 HWND hwnd = create_a_window();
1658 himl1 = ImageList_Create(32,32,0,0,3);
1659 ok(himl1 != NULL,"failed to create himl1\n");
1661 himl2 = ImageList_Create(32,32,0,0,3);
1662 ok(himl2 != NULL,"failed to create himl2\n");
1664 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1665 ok(hicon1 != NULL, "failed to create hicon1\n");
1667 if (!himl1 || !himl2 || !hicon1)
1670 /* cast to IImageList */
1671 imgl1 = (IImageList *) himl1;
1672 imgl2 = (IImageList *) himl2;
1675 ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (ret == 0),"add icon1 to himl2 failed\n");
1677 /* If himl1 has no images, merge still succeeds */
1678 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1679 ok(hr == S_OK, "merge himl1,-1 failed\n");
1680 if (hr == S_OK) IImageList_Release(merge);
1682 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1683 ok(hr == S_OK, "merge himl1,0 failed\n");
1684 if (hr == S_OK) IImageList_Release(merge);
1686 /* Same happens if himl2 is empty */
1687 IImageList_Release(imgl2);
1688 himl2 = ImageList_Create(32,32,0,0,3);
1689 ok(himl2 != NULL,"failed to recreate himl2\n");
1691 imgl2 = (IImageList *) himl2;
1693 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, -1, 0, 0, &IID_IImageList, (void **) &merge);
1694 ok(hr == S_OK, "merge himl2,-1 failed\n");
1695 if (hr == S_OK) IImageList_Release(merge);
1697 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1698 ok(hr == S_OK, "merge himl2,0 failed\n");
1699 if (hr == S_OK) IImageList_Release(merge);
1701 /* Now try merging an image with itself */
1703 ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (ret == 0),"re-add icon1 to himl2 failed\n");
1705 hr = IImageList_Merge(imgl2, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1706 ok(hr == S_OK, "merge himl2 with itself failed\n");
1707 if (hr == S_OK) IImageList_Release(merge);
1709 /* Try merging 2 different image lists */
1711 ok( IImageList_ReplaceIcon(imgl1, -1, hicon1, &ret) == S_OK && (ret == 0),"add icon1 to himl1 failed\n");
1713 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1714 ok(hr == S_OK, "merge himl1 with himl2 failed\n");
1715 if (hr == S_OK) IImageList_Release(merge);
1717 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 8, 16, &IID_IImageList, (void **) &merge);
1718 ok(hr == S_OK, "merge himl1 with himl2 8,16 failed\n");
1719 if (hr == S_OK) IImageList_Release(merge);
1721 IImageList_Release(imgl1);
1722 IImageList_Release(imgl2);
1724 DestroyIcon(hicon1);
1725 DestroyWindow(hwnd);
1728 static void test_iconsize(void)
1734 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1735 /* null pointers, not zero imagelist dimensions */
1736 ret = ImageList_GetIconSize(himl, NULL, NULL);
1737 todo_wine ok(!ret, "got %d\n", ret);
1739 /* doesn't touch return pointers */
1741 ret = ImageList_GetIconSize(himl, &cx, NULL);
1743 ok(!ret, "got %d\n", ret);
1744 ok(cx == 0xdeadbeef, "got %d\n", cx);
1747 ret = ImageList_GetIconSize(himl, NULL, &cy);
1749 ok(!ret, "got %d\n", ret);
1750 ok(cy == 0xdeadbeef, "got %d\n", cy);
1752 ImageList_Destroy(himl);
1755 static void test_create(void)
1760 /* list with zero or negative image dimensions */
1761 himl = ImageList_Create(0, 0, ILC_COLOR16, 0, 3);
1762 ok(himl == NULL, "got %p\n", himl);
1764 himl = ImageList_Create(0, 16, ILC_COLOR16, 0, 3);
1765 ok(himl == NULL, "got %p\n", himl);
1767 himl = ImageList_Create(16, 0, ILC_COLOR16, 0, 3);
1768 ok(himl == NULL, "got %p\n", himl);
1770 himl = ImageList_Create(16, -1, ILC_COLOR16, 0, 3);
1771 ok(himl == NULL, "got %p\n", himl);
1773 himl = ImageList_Create(-1, 16, ILC_COLOR16, 0, 3);
1774 ok(himl == NULL, "got %p\n", himl);
1779 START_TEST(imagelist)
1781 ULONG_PTR ctx_cookie;
1784 HMODULE hComCtl32 = GetModuleHandle("comctl32.dll");
1785 pImageList_Create = NULL; /* These are not needed for non-v6.0 tests*/
1786 pImageList_Add = NULL;
1787 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
1788 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
1790 hinst = GetModuleHandleA(NULL);
1792 InitCommonControls();
1798 test_DrawIndirect();
1800 test_imagelist_storage();
1803 FreeLibrary(hComCtl32);
1805 /* Now perform v6 tests */
1807 if (!load_v6_module(&ctx_cookie, &hCtx))
1810 /* Reload comctl32 */
1811 hComCtl32 = LoadLibraryA("comctl32.dll");
1812 pImageList_Create = (void*)GetProcAddress(hComCtl32, "ImageList_Create");
1813 pImageList_Add = (void*)GetProcAddress(hComCtl32, "ImageList_Add");
1814 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
1815 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
1816 pImageList_CoCreateInstance = (void*)GetProcAddress(hComCtl32, "ImageList_CoCreateInstance");
1817 pHIMAGELIST_QueryInterface = (void*)GetProcAddress(hComCtl32, "HIMAGELIST_QueryInterface");
1819 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1822 test_ImageList_DrawIndirect();
1823 test_shell_imagelist();
1827 test_IImageList_Add_Remove();
1828 test_IImageList_Get_SetImageCount();
1829 test_IImageList_Draw();
1830 test_IImageList_Merge();
1834 unload_v6_module(ctx_cookie, hCtx);