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;
1212 int bpp, broken_value;
1214 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB,
1217 hdcDst = CreateCompatibleDC(0);
1218 ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
1221 bpp = GetDeviceCaps(hdcDst, BITSPIXEL);
1223 hbmMask = CreateBitmap(2, 1, 1, 1, &maskBits);
1224 ok(hbmMask != 0, "CreateBitmap failed\n");
1225 if(!hbmMask) goto cleanup;
1227 hbmInverseMask = CreateBitmap(2, 1, 1, 1, &inverseMaskBits);
1228 ok(hbmInverseMask != 0, "CreateBitmap failed\n");
1229 if(!hbmInverseMask) goto cleanup;
1231 himl = pImageList_Create(2, 1, ILC_COLOR32, 0, 1);
1232 ok(himl != 0, "ImageList_Create failed\n");
1233 if(!himl) goto cleanup;
1235 /* Add a no-alpha image */
1236 hbmImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x00ABCDEF);
1237 if(!hbmImage) goto cleanup;
1239 iImage = pImageList_Add(himl, hbmImage, hbmMask);
1240 ok(iImage != -1, "ImageList_Add failed\n");
1241 if(iImage == -1) goto cleanup;
1243 /* Add an alpha image */
1244 hbmAlphaImage = create_test_bitmap(hdcDst, 32, 0x89ABCDEF, 0x89ABCDEF);
1245 if(!hbmAlphaImage) goto cleanup;
1247 iAlphaImage = pImageList_Add(himl, hbmAlphaImage, hbmMask);
1248 ok(iAlphaImage != -1, "ImageList_Add failed\n");
1249 if(iAlphaImage == -1) goto cleanup;
1251 /* Add a transparent alpha image */
1252 hbmTransparentImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x89ABCDEF);
1253 if(!hbmTransparentImage) goto cleanup;
1255 iTransparentImage = pImageList_Add(himl, hbmTransparentImage, hbmMask);
1256 ok(iTransparentImage != -1, "ImageList_Add failed\n");
1257 if(iTransparentImage == -1) goto cleanup;
1260 bitmapInfo.bmiHeader.biBitCount = 32;
1261 hbmDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1262 ok (hbmDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1263 if (!hbmDst || !bits)
1265 hbmOld = SelectObject(hdcDst, hbmDst);
1267 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_NORMAL, 0x00ABCDEF, __LINE__);
1268 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_TRANSPARENT, 0x00ABCDEF, __LINE__);
1269 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x00D4D9DD, __LINE__);
1270 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1271 else broken_value = 0x00B4BDC4;
1272 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1273 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_MASK, 0x00ABCDEF, __LINE__);
1274 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_IMAGE, 0x00ABCDEF, __LINE__);
1275 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_PRESERVEALPHA, 0x00ABCDEF, __LINE__);
1277 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, 0x00D3E5F7, __LINE__);
1278 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_TRANSPARENT, 0x00D3E5F7, __LINE__);
1280 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1281 else broken_value = 0x009DA8B1;
1282 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1283 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1284 else broken_value = 0x008C99A3;
1285 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1286 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0x00D3E5F7, __LINE__);
1287 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0x00D3E5F7, __LINE__);
1288 todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__);
1290 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__);
1292 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCCOPY, 0x00ABCDEF, __LINE__);
1293 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCINVERT, 0x00543210, __LINE__);
1295 /* ILD_ROP is ignored when the image has an alpha channel */
1296 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCCOPY, 0x00D3E5F7, __LINE__);
1297 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCINVERT, 0x00D3E5F7, __LINE__);
1299 todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00CCCCCC, __LINE__);
1300 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00AFAFAF, 0x00F0F0F0, __LINE__);
1302 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_GLOW, 0, 0x00ABCDEF, __LINE__);
1303 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SHADOW, 0, 0x00ABCDEF, __LINE__);
1305 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00D5E6F7, __LINE__);
1306 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00E9F2FB, 0x00AEB7C0, __LINE__);
1307 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_NORMAL, 127, 0x00E9F2FB, 0x00D3E5F7, __LINE__);
1312 SelectObject(hdcDst, hbmOld);
1314 DeleteObject(hbmDst);
1320 DeleteObject(hbmMask);
1322 DeleteObject(hbmInverseMask);
1325 DeleteObject(hbmImage);
1327 DeleteObject(hbmAlphaImage);
1328 if(hbmTransparentImage)
1329 DeleteObject(hbmTransparentImage);
1333 ret = ImageList_Destroy(himl);
1334 ok(ret, "ImageList_Destroy failed\n");
1338 static void test_iimagelist(void)
1340 IImageList *imgl, *imgl2;
1345 if (!pHIMAGELIST_QueryInterface)
1347 win_skip("XP imagelist functions not available\n");
1351 /* test reference counting on destruction */
1352 imgl = (IImageList*)createImageList(32, 32);
1353 ret = IUnknown_AddRef(imgl);
1354 ok(ret == 2, "Expected 2, got %d\n", ret);
1355 ret = ImageList_Destroy((HIMAGELIST)imgl);
1356 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1357 ret = ImageList_Destroy((HIMAGELIST)imgl);
1358 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1359 ret = ImageList_Destroy((HIMAGELIST)imgl);
1360 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1362 imgl = (IImageList*)createImageList(32, 32);
1363 ret = IUnknown_AddRef(imgl);
1364 ok(ret == 2, "Expected 2, got %d\n", ret);
1365 ret = ImageList_Destroy((HIMAGELIST)imgl);
1366 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1367 ret = IImageList_Release(imgl);
1368 ok(ret == 0, "Expected 0, got %d\n", ret);
1369 ret = ImageList_Destroy((HIMAGELIST)imgl);
1370 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1372 /* ref counting, HIMAGELIST_QueryInterface adds a reference */
1373 imgl = (IImageList*)createImageList(32, 32);
1374 hr = pHIMAGELIST_QueryInterface((HIMAGELIST)imgl, &IID_IImageList, (void**)&imgl2);
1375 ok(hr == S_OK, "got 0x%08x\n", hr);
1376 ok(imgl2 == imgl, "got different pointer\n");
1377 ret = IImageList_Release(imgl);
1378 ok(ret == 1, "got %u\n", ret);
1379 IImageList_Release(imgl);
1381 if (!pImageList_CoCreateInstance)
1383 win_skip("Vista imagelist functions not available\n");
1387 hr = pImageList_CoCreateInstance(&CLSID_ImageList, NULL, &IID_IImageList, (void **) &imgl);
1388 ok(SUCCEEDED(hr), "ImageList_CoCreateInstance failed, hr=%x\n", hr);
1391 IImageList_Release(imgl);
1393 himl = createImageList(32, 32);
1398 hr = (pHIMAGELIST_QueryInterface)(himl, &IID_IImageList, (void **) &imgl);
1399 ok(SUCCEEDED(hr), "HIMAGELIST_QueryInterface failed, hr=%x\n", hr);
1402 IImageList_Release(imgl);
1404 ImageList_Destroy(himl);
1407 static void test_hotspot_v6(void)
1418 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
1419 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
1426 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
1427 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
1428 IImageList *imgl1, *imgl2;
1431 /* cast to IImageList */
1432 imgl1 = (IImageList *) himl1;
1433 imgl2 = (IImageList *) himl2;
1435 for (i = 0; i < HOTSPOTS_MAX; i++) {
1436 for (j = 0; j < HOTSPOTS_MAX; j++) {
1437 int dx1 = hotspots[i].dx;
1438 int dy1 = hotspots[i].dy;
1439 int dx2 = hotspots[j].dx;
1440 int dy2 = hotspots[j].dy;
1441 int correctx, correcty, newx, newy;
1443 IImageList *imglNew;
1446 hr = IImageList_BeginDrag(imgl1, 0, dx1, dy1);
1447 ok(SUCCEEDED(hr), "BeginDrag failed for { %d, %d }\n", dx1, dy1);
1448 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
1450 /* check merging the dragged image with a second image */
1451 hr = IImageList_SetDragCursorImage(imgl2, (IUnknown *) imgl2, 0, dx2, dy2);
1452 ok(SUCCEEDED(hr), "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
1453 dx1, dy1, dx2, dy2);
1454 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
1456 /* check new hotspot, it should be the same like the old one */
1457 hr = IImageList_GetDragImage(imgl2, NULL, &ppt, &IID_IImageList, (PVOID *) &imglNew);
1458 ok(SUCCEEDED(hr), "GetDragImage failed\n");
1459 ok(ppt.x == dx1 && ppt.y == dy1,
1460 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
1461 dx1, dy1, ppt.x, ppt.y);
1462 /* check size of new dragged image */
1463 IImageList_GetIconSize(imglNew, &newx, &newy);
1464 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
1465 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
1466 ok(newx == correctx && newy == correcty,
1467 "Expected drag image size [%d,%d] got [%d,%d]\n",
1468 correctx, correcty, newx, newy);
1469 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
1470 IImageList_EndDrag(imgl2);
1478 IImageList_Release(imgl2);
1479 IImageList_Release(imgl1);
1482 static void test_IImageList_Add_Remove(void)
1494 /* create an imagelist to play with */
1495 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1496 ok(himl != 0,"failed to create imagelist\n");
1498 imgl = (IImageList *) himl;
1500 /* load the icons to add to the image list */
1501 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1502 ok(hicon1 != 0, "no hicon1\n");
1503 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1504 ok(hicon2 != 0, "no hicon2\n");
1505 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1506 ok(hicon3 != 0, "no hicon3\n");
1508 /* remove when nothing exists */
1509 hr = IImageList_Remove(imgl, 0);
1510 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1512 /* removing everything from an empty imagelist should succeed */
1513 hr = IImageList_Remove(imgl, -1);
1514 ok(hr == S_OK, "removed nonexistent icon\n");
1518 ok( IImageList_ReplaceIcon(imgl, -1, hicon1, &ret) == S_OK && (ret == 0),"failed to add icon1\n");
1520 ok( IImageList_ReplaceIcon(imgl, -1, hicon2, &ret) == S_OK && (ret == 1),"failed to add icon2\n");
1522 ok( IImageList_ReplaceIcon(imgl, -1, hicon3, &ret) == S_OK && (ret == 2),"failed to add icon3\n");
1524 /* remove an index out of range */
1525 ok( IImageList_Remove(imgl, 4711) == E_INVALIDARG, "got 0x%08x\n", hr);
1528 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1529 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1530 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1532 /* remove one extra */
1533 ok( IImageList_Remove(imgl, 0) == E_INVALIDARG, "got 0x%08x\n", hr);
1535 IImageList_Release(imgl);
1536 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
1537 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
1538 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
1541 static void test_IImageList_Get_SetImageCount(void)
1548 /* create an imagelist to play with */
1549 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1550 ok(himl != 0,"failed to create imagelist\n");
1552 imgl = (IImageList *) himl;
1554 /* check SetImageCount/GetImageCount */
1555 hr = IImageList_SetImageCount(imgl, 3);
1556 ok(hr == S_OK, "got 0x%08x\n", hr);
1558 hr = IImageList_GetImageCount(imgl, &ret);
1559 ok(hr == S_OK && ret == 3, "invalid image count after increase\n");
1560 hr = IImageList_SetImageCount(imgl, 1);
1561 ok(hr == S_OK, "got 0x%08x\n", hr);
1563 hr = IImageList_GetImageCount(imgl, &ret);
1564 ok(hr == S_OK && ret == 1, "invalid image count after decrease to 1\n");
1565 hr = IImageList_SetImageCount(imgl, 0);
1566 ok(hr == S_OK, "got 0x%08x\n", hr);
1568 hr = IImageList_GetImageCount(imgl, &ret);
1569 ok(hr == S_OK && ret == 0, "invalid image count after decrease to 0\n");
1571 IImageList_Release(imgl);
1574 static void test_IImageList_Draw(void)
1583 IMAGELISTDRAWPARAMS imldp;
1589 hwndfortest = create_a_window();
1590 hdc = GetDC(hwndfortest);
1591 ok(hdc!=NULL, "couldn't get DC\n");
1593 /* create an imagelist to play with */
1594 himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
1595 ok(himl!=0,"failed to create imagelist\n");
1597 imgl = (IImageList *) himl;
1599 /* load the icons to add to the image list */
1600 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1601 ok(hbm1 != 0, "no bitmap 1\n");
1602 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1603 ok(hbm2 != 0, "no bitmap 2\n");
1604 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1605 ok(hbm3 != 0, "no bitmap 3\n");
1609 ok( IImageList_Add(imgl, hbm1, 0, &ret) == S_OK && (ret == 0), "failed to add bitmap 1\n");
1611 ok( IImageList_Add(imgl, hbm2, 0, &ret) == S_OK && (ret == 1), "failed to add bitmap 2\n");
1613 ok( IImageList_SetImageCount(imgl, 3) == S_OK, "Setimage count failed\n");
1614 ok( IImageList_Replace(imgl, 2, hbm3, 0) == S_OK, "failed to replace bitmap 3\n");
1618 /* crashes on native */
1619 hr = IImageList_Draw(imgl, NULL);
1622 memset(&imldp, 0, sizeof (imldp));
1623 hr = IImageList_Draw(imgl, &imldp);
1624 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
1626 imldp.cbSize = IMAGELISTDRAWPARAMS_V3_SIZE;
1630 REDRAW(hwndfortest);
1633 imldp.fStyle = SRCCOPY;
1634 imldp.rgbBk = CLR_DEFAULT;
1635 imldp.rgbFg = CLR_DEFAULT;
1638 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1640 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1642 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1644 ok( IImageList_Draw(imgl, &imldp) == E_INVALIDARG, "should fail\n");
1647 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 1st bitmap\n");
1648 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 2nd bitmap\n");
1649 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 3rd bitmap\n");
1652 IImageList_Release(imgl);
1654 /* bitmaps should not be deleted by the imagelist */
1655 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
1656 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
1657 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
1659 ReleaseDC(hwndfortest, hdc);
1660 DestroyWindow(hwndfortest);
1663 static void test_IImageList_Merge(void)
1665 HIMAGELIST himl1, himl2;
1666 IImageList *imgl1, *imgl2, *merge;
1668 HWND hwnd = create_a_window();
1672 himl1 = ImageList_Create(32,32,0,0,3);
1673 ok(himl1 != NULL,"failed to create himl1\n");
1675 himl2 = ImageList_Create(32,32,0,0,3);
1676 ok(himl2 != NULL,"failed to create himl2\n");
1678 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1679 ok(hicon1 != NULL, "failed to create hicon1\n");
1681 if (!himl1 || !himl2 || !hicon1)
1684 /* cast to IImageList */
1685 imgl1 = (IImageList *) himl1;
1686 imgl2 = (IImageList *) himl2;
1689 ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (ret == 0),"add icon1 to himl2 failed\n");
1693 /* null cases that crash on native */
1694 hr = IImageList_Merge(imgl1, -1, NULL, 0, 0, 0, &IID_IImageList, (void**)&merge);
1695 hr = IImageList_Merge(imgl1, -1, (IUnknown*) imgl2, 0, 0, 0, &IID_IImageList, NULL);
1698 /* If himl1 has no images, merge still succeeds */
1699 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1700 ok(hr == S_OK, "merge himl1,-1 failed\n");
1701 if (hr == S_OK) IImageList_Release(merge);
1703 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1704 ok(hr == S_OK, "merge himl1,0 failed\n");
1705 if (hr == S_OK) IImageList_Release(merge);
1707 /* Same happens if himl2 is empty */
1708 IImageList_Release(imgl2);
1709 himl2 = ImageList_Create(32,32,0,0,3);
1710 ok(himl2 != NULL,"failed to recreate himl2\n");
1712 imgl2 = (IImageList *) himl2;
1714 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, -1, 0, 0, &IID_IImageList, (void **) &merge);
1715 ok(hr == S_OK, "merge himl2,-1 failed\n");
1716 if (hr == S_OK) IImageList_Release(merge);
1718 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1719 ok(hr == S_OK, "merge himl2,0 failed\n");
1720 if (hr == S_OK) IImageList_Release(merge);
1722 /* Now try merging an image with itself */
1724 ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (ret == 0),"re-add icon1 to himl2 failed\n");
1726 hr = IImageList_Merge(imgl2, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1727 ok(hr == S_OK, "merge himl2 with itself failed\n");
1728 if (hr == S_OK) IImageList_Release(merge);
1730 /* Try merging 2 different image lists */
1732 ok( IImageList_ReplaceIcon(imgl1, -1, hicon1, &ret) == S_OK && (ret == 0),"add icon1 to himl1 failed\n");
1734 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1735 ok(hr == S_OK, "merge himl1 with himl2 failed\n");
1736 if (hr == S_OK) IImageList_Release(merge);
1738 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 8, 16, &IID_IImageList, (void **) &merge);
1739 ok(hr == S_OK, "merge himl1 with himl2 8,16 failed\n");
1740 if (hr == S_OK) IImageList_Release(merge);
1742 IImageList_Release(imgl1);
1743 IImageList_Release(imgl2);
1745 DestroyIcon(hicon1);
1746 DestroyWindow(hwnd);
1749 static void test_iconsize(void)
1755 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1756 /* null pointers, not zero imagelist dimensions */
1757 ret = ImageList_GetIconSize(himl, NULL, NULL);
1758 ok(!ret, "got %d\n", ret);
1760 /* doesn't touch return pointers */
1762 ret = ImageList_GetIconSize(himl, &cx, NULL);
1763 ok(!ret, "got %d\n", ret);
1764 ok(cx == 0xdeadbeef, "got %d\n", cx);
1767 ret = ImageList_GetIconSize(himl, NULL, &cy);
1768 ok(!ret, "got %d\n", ret);
1769 ok(cy == 0xdeadbeef, "got %d\n", cy);
1771 ImageList_Destroy(himl);
1774 static void test_create(void)
1778 /* list with zero or negative image dimensions */
1779 himl = ImageList_Create(0, 0, ILC_COLOR16, 0, 3);
1780 ok(himl == NULL, "got %p\n", himl);
1782 himl = ImageList_Create(0, 16, ILC_COLOR16, 0, 3);
1783 ok(himl == NULL, "got %p\n", himl);
1785 himl = ImageList_Create(16, 0, ILC_COLOR16, 0, 3);
1786 ok(himl == NULL, "got %p\n", himl);
1788 himl = ImageList_Create(16, -1, ILC_COLOR16, 0, 3);
1789 ok(himl == NULL, "got %p\n", himl);
1791 himl = ImageList_Create(-1, 16, ILC_COLOR16, 0, 3);
1792 ok(himl == NULL, "got %p\n", himl);
1795 static void test_IImageList_Clone(void)
1797 IImageList *imgl, *imgl2;
1802 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1803 imgl = (IImageList*)himl;
1807 /* crashes on native */
1808 hr = IImageList_Clone(imgl, &IID_IImageList, NULL);
1811 hr = IImageList_Clone(imgl, &IID_IImageList, (void**)&imgl2);
1812 ok(hr == S_OK, "got 0x%08x\n", hr);
1813 ref = IImageList_Release(imgl2);
1814 ok(ref == 0, "got %u\n", ref);
1816 IImageList_Release(imgl);
1819 static void test_IImageList_GetBkColor(void)
1826 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1827 imgl = (IImageList*)himl;
1831 /* crashes on native */
1832 hr = IImageList_GetBkColor(imgl, NULL);
1835 hr = IImageList_GetBkColor(imgl, &color);
1836 ok(hr == S_OK, "got 0x%08x\n", hr);
1838 IImageList_Release(imgl);
1841 static void test_IImageList_SetBkColor(void)
1848 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1849 imgl = (IImageList*)himl;
1853 /* crashes on native */
1854 hr = IImageList_SetBkColor(imgl, RGB(0, 0, 0), NULL);
1857 hr = IImageList_SetBkColor(imgl, CLR_NONE, &color);
1858 ok(hr == S_OK, "got 0x%08x\n", hr);
1860 hr = IImageList_SetBkColor(imgl, CLR_NONE, &color);
1861 ok(hr == S_OK, "got 0x%08x\n", hr);
1864 hr = IImageList_GetBkColor(imgl, &color);
1865 ok(hr == S_OK, "got 0x%08x\n", hr);
1866 ok(color == CLR_NONE, "got %x\n", color);
1868 IImageList_Release(imgl);
1871 static void test_IImageList_GetImageCount(void)
1878 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1879 imgl = (IImageList*)himl;
1883 /* crashes on native */
1884 hr = IImageList_GetImageCount(imgl, NULL);
1888 hr = IImageList_GetImageCount(imgl, &count);
1889 ok(hr == S_OK, "got 0x%08x\n", hr);
1890 ok(count == 0, "got %d\n", count);
1892 IImageList_Release(imgl);
1895 static void test_IImageList_GetIconSize(void)
1902 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1903 imgl = (IImageList*)himl;
1905 hr = IImageList_GetIconSize(imgl, NULL, NULL);
1906 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1908 hr = IImageList_GetIconSize(imgl, &cx, NULL);
1909 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1911 hr = IImageList_GetIconSize(imgl, NULL, &cy);
1912 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1914 IImageList_Release(imgl);
1917 START_TEST(imagelist)
1919 ULONG_PTR ctx_cookie;
1922 HMODULE hComCtl32 = GetModuleHandle("comctl32.dll");
1923 pImageList_Create = NULL; /* These are not needed for non-v6.0 tests*/
1924 pImageList_Add = NULL;
1925 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
1926 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
1928 hinst = GetModuleHandleA(NULL);
1930 InitCommonControls();
1936 test_DrawIndirect();
1938 test_imagelist_storage();
1941 FreeLibrary(hComCtl32);
1943 /* Now perform v6 tests */
1945 if (!load_v6_module(&ctx_cookie, &hCtx))
1948 /* Reload comctl32 */
1949 hComCtl32 = LoadLibraryA("comctl32.dll");
1950 pImageList_Create = (void*)GetProcAddress(hComCtl32, "ImageList_Create");
1951 pImageList_Add = (void*)GetProcAddress(hComCtl32, "ImageList_Add");
1952 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
1953 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
1954 pImageList_CoCreateInstance = (void*)GetProcAddress(hComCtl32, "ImageList_CoCreateInstance");
1955 pHIMAGELIST_QueryInterface = (void*)GetProcAddress(hComCtl32, "HIMAGELIST_QueryInterface");
1957 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1960 test_ImageList_DrawIndirect();
1961 test_shell_imagelist();
1965 test_IImageList_Add_Remove();
1966 test_IImageList_Get_SetImageCount();
1967 test_IImageList_Draw();
1968 test_IImageList_Merge();
1969 test_IImageList_Clone();
1970 test_IImageList_GetBkColor();
1971 test_IImageList_SetBkColor();
1972 test_IImageList_GetImageCount();
1973 test_IImageList_GetIconSize();
1977 unload_v6_module(ctx_cookie, hCtx);