push 149f0a5527ac85057a8ef03858d34d91c36f97e8
[wine/hacks.git] / dlls / comctl32 / tests / imagelist.c
blob52907887979b2882dbef8b8951f866af5441a724
1 /*
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
24 #define COBJMACROS
25 #define CONST_VTABLE
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <assert.h>
31 #include "windef.h"
32 #include "winbase.h"
33 #include "wingdi.h"
34 #include "winuser.h"
35 #include "objbase.h"
36 #include "commctrl.h" /* must be included after objbase.h to get ImageList_Write */
37 #include "initguid.h"
38 #include "commoncontrols.h"
39 #include "shellapi.h"
41 #include "wine/test.h"
42 #include "v6util.h"
44 #undef VISIBLE
46 #ifdef VISIBLE
47 #define WAIT Sleep (1000)
48 #define REDRAW(hwnd) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW)
49 #else
50 #define WAIT
51 #define REDRAW(hwnd)
52 #endif
54 #define IMAGELIST_MAGIC (('L' << 8) | 'I')
56 #include "pshpack2.h"
57 /* Header used by ImageList_Read() and ImageList_Write() */
58 typedef struct _ILHEAD
60 USHORT usMagic;
61 USHORT usVersion;
62 WORD cCurImage;
63 WORD cMaxImage;
64 WORD cGrow;
65 WORD cx;
66 WORD cy;
67 COLORREF bkcolor;
68 WORD flags;
69 SHORT ovls[4];
70 } ILHEAD;
71 #include "poppack.h"
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 *,
78 REFIID,void **);
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);
129 return himl;
132 static HWND create_a_window(void)
134 char className[] = "bmwnd";
135 char winName[] = "Test Bitmap";
136 HWND hWnd;
137 static int registered = 0;
139 if (!registered)
141 WNDCLASSA cls;
143 cls.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
144 cls.lpfnWndProc = DefWindowProcA;
145 cls.cbClsExtra = 0;
146 cls.cbWndExtra = 0;
147 cls.hInstance = 0;
148 cls.hIcon = LoadIconA (0, IDI_APPLICATION);
149 cls.hCursor = LoadCursorA (0, IDC_ARROW);
150 cls.hbrBackground = GetStockObject (WHITE_BRUSH);
151 cls.lpszMenuName = 0;
152 cls.lpszClassName = className;
154 RegisterClassA (&cls);
155 registered = 1;
158 /* Setup window */
159 hWnd = CreateWindowA (className, winName,
160 WS_OVERLAPPEDWINDOW ,
161 CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
162 0, hinst, 0);
164 #ifdef VISIBLE
165 ShowWindow (hWnd, SW_SHOW);
166 #endif
167 REDRAW(hWnd);
168 WAIT;
170 return hWnd;
173 static HDC show_image(HWND hwnd, HIMAGELIST himl, int idx, int size,
174 LPCSTR loc, BOOL clear)
176 HDC hdc = NULL;
177 #ifdef VISIBLE
178 if (!himl) return NULL;
180 SetWindowText(hwnd, loc);
181 hdc = GetDC(hwnd);
182 ImageList_Draw(himl, idx, hdc, 0, 0, ILD_TRANSPARENT);
184 REDRAW(hwnd);
185 WAIT;
187 if (clear)
189 BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
190 ReleaseDC(hwnd, hdc);
191 hdc = NULL;
193 #endif /* VISIBLE */
194 return hdc;
197 /* Useful for checking differences */
198 #if 0
199 static void dump_bits(const BYTE *p, const BYTE *q, int size)
201 int i, j;
203 size /= 8;
205 for (i = 0; i < size * 2; i++)
207 printf("|");
208 for (j = 0; j < size; j++)
209 printf("%c%c", p[j] & 0xf0 ? 'X' : ' ', p[j] & 0xf ? 'X' : ' ');
210 printf(" -- ");
211 for (j = 0; j < size; j++)
212 printf("%c%c", q[j] & 0xf0 ? 'X' : ' ', q[j] & 0xf ? 'X' : ' ');
213 printf("|\n");
214 p += size * 4;
215 q += size * 4;
217 printf("\n");
219 #endif
221 static void check_bits(HWND hwnd, HIMAGELIST himl, int idx, int size,
222 const BYTE *checkbits, LPCSTR loc)
224 #ifdef VISIBLE
225 BYTE bits[100*100/8];
226 COLORREF c;
227 HDC hdc;
228 int x, y, i = -1;
230 if (!himl) return;
232 memset(bits, 0, sizeof(bits));
233 hdc = show_image(hwnd, himl, idx, size, loc, FALSE);
235 c = GetPixel(hdc, 0, 0);
237 for (y = 0; y < size; y ++)
239 for (x = 0; x < size; x++)
241 if (!(x & 0x7)) i++;
242 if (GetPixel(hdc, x, y) != c) bits[i] |= (0x80 >> (x & 0x7));
246 BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
247 ReleaseDC(hwnd, hdc);
249 ok (memcmp(bits, checkbits, (size * size)/8) == 0,
250 "%s: bits different\n", loc);
251 if (memcmp(bits, checkbits, (size * size)/8))
252 dump_bits(bits, checkbits, size);
253 #endif /* VISIBLE */
256 static void testHotspot (void)
258 struct hotspot {
259 int dx;
260 int dy;
263 #define SIZEX1 47
264 #define SIZEY1 31
265 #define SIZEX2 11
266 #define SIZEY2 17
267 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
268 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
269 { 10, 7 },
270 { SIZEX1, SIZEY1 },
271 { -9, -8 },
272 { -7, 35 }
274 int i, j, ret;
275 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
276 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
277 HWND hwnd = create_a_window();
280 for (i = 0; i < HOTSPOTS_MAX; i++) {
281 for (j = 0; j < HOTSPOTS_MAX; j++) {
282 int dx1 = hotspots[i].dx;
283 int dy1 = hotspots[i].dy;
284 int dx2 = hotspots[j].dx;
285 int dy2 = hotspots[j].dy;
286 int correctx, correcty, newx, newy;
287 char loc[256];
288 HIMAGELIST himlNew;
289 POINT ppt;
291 ret = ImageList_BeginDrag(himl1, 0, dx1, dy1);
292 ok(ret != 0, "BeginDrag failed for { %d, %d }\n", dx1, dy1);
293 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
294 show_image(hwnd, himl1, 0, max(SIZEX1, SIZEY1), loc, TRUE);
296 /* check merging the dragged image with a second image */
297 ret = ImageList_SetDragCursorImage(himl2, 0, dx2, dy2);
298 ok(ret != 0, "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
299 dx1, dy1, dx2, dy2);
300 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
301 show_image(hwnd, himl2, 0, max(SIZEX2, SIZEY2), loc, TRUE);
303 /* check new hotspot, it should be the same like the old one */
304 himlNew = ImageList_GetDragImage(NULL, &ppt);
305 ok(ppt.x == dx1 && ppt.y == dy1,
306 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
307 dx1, dy1, ppt.x, ppt.y);
308 /* check size of new dragged image */
309 ImageList_GetIconSize(himlNew, &newx, &newy);
310 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
311 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
312 ok(newx == correctx && newy == correcty,
313 "Expected drag image size [%d,%d] got [%d,%d]\n",
314 correctx, correcty, newx, newy);
315 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
316 show_image(hwnd, himlNew, 0, max(correctx, correcty), loc, TRUE);
317 ImageList_EndDrag();
320 #undef SIZEX1
321 #undef SIZEY1
322 #undef SIZEX2
323 #undef SIZEY2
324 #undef HOTSPOTS_MAX
325 ImageList_Destroy(himl2);
326 ImageList_Destroy(himl1);
327 DestroyWindow(hwnd);
330 static BOOL DoTest1(void)
332 HIMAGELIST himl ;
334 HICON hicon1 ;
335 HICON hicon2 ;
336 HICON hicon3 ;
338 /* create an imagelist to play with */
339 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
340 ok(himl!=0,"failed to create imagelist\n");
342 /* load the icons to add to the image list */
343 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
344 ok(hicon1 != 0, "no hicon1\n");
345 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
346 ok(hicon2 != 0, "no hicon2\n");
347 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
348 ok(hicon3 != 0, "no hicon3\n");
350 /* remove when nothing exists */
351 ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
352 /* removing everything from an empty imagelist should succeed */
353 ok(ImageList_RemoveAll(himl),"removed nonexistent icon\n");
355 /* add three */
356 ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
357 ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
358 ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
360 /* remove an index out of range */
361 ok(!ImageList_Remove(himl,4711),"removed nonexistent icon\n");
363 /* remove three */
364 ok(ImageList_Remove(himl,0),"can't remove 0\n");
365 ok(ImageList_Remove(himl,0),"can't remove 0\n");
366 ok(ImageList_Remove(himl,0),"can't remove 0\n");
368 /* remove one extra */
369 ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
371 /* check SetImageCount/GetImageCount */
372 if (pImageList_SetImageCount)
374 ok(pImageList_SetImageCount(himl, 3), "couldn't increase image count\n");
375 ok(ImageList_GetImageCount(himl) == 3, "invalid image count after increase\n");
376 ok(pImageList_SetImageCount(himl, 1), "couldn't decrease image count\n");
377 ok(ImageList_GetImageCount(himl) == 1, "invalid image count after decrease to 1\n");
378 ok(pImageList_SetImageCount(himl, 0), "couldn't decrease image count\n");
379 ok(ImageList_GetImageCount(himl) == 0, "invalid image count after decrease to 0\n");
381 else
383 skip("skipped ImageList_SetImageCount tests\n");
386 /* destroy it */
387 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
389 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
390 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
391 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
393 return TRUE;
396 static BOOL DoTest2(void)
398 HIMAGELIST himl ;
400 HICON hicon1 ;
401 HICON hicon2 ;
402 HICON hicon3 ;
404 /* create an imagelist to play with */
405 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
406 ok(himl!=0,"failed to create imagelist\n");
408 /* load the icons to add to the image list */
409 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
410 ok(hicon1 != 0, "no hicon1\n");
411 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
412 ok(hicon2 != 0, "no hicon2\n");
413 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
414 ok(hicon3 != 0, "no hicon3\n");
416 /* add three */
417 ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
418 ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
419 ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
421 /* destroy it */
422 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
424 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
425 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
426 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
428 return TRUE;
431 static BOOL DoTest3(void)
433 HIMAGELIST himl;
435 HBITMAP hbm1;
436 HBITMAP hbm2;
437 HBITMAP hbm3;
439 IMAGELISTDRAWPARAMS imldp;
440 HDC hdc;
441 HWND hwndfortest;
443 if (!pImageList_DrawIndirect)
445 win_skip("ImageList_DrawIndirect not available, skipping test\n");
446 return TRUE;
449 hwndfortest = create_a_window();
450 hdc = GetDC(hwndfortest);
451 ok(hdc!=NULL, "couldn't get DC\n");
453 /* create an imagelist to play with */
454 himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
455 ok(himl!=0,"failed to create imagelist\n");
457 /* load the icons to add to the image list */
458 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
459 ok(hbm1 != 0, "no bitmap 1\n");
460 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
461 ok(hbm2 != 0, "no bitmap 2\n");
462 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
463 ok(hbm3 != 0, "no bitmap 3\n");
465 /* add three */
466 ok(0==ImageList_Add(himl, hbm1, 0),"failed to add bitmap 1\n");
467 ok(1==ImageList_Add(himl, hbm2, 0),"failed to add bitmap 2\n");
469 if (pImageList_SetImageCount)
471 ok(pImageList_SetImageCount(himl,3),"Setimage count failed\n");
472 /*ok(2==ImageList_Add(himl, hbm3, NULL),"failed to add bitmap 3\n"); */
473 ok(ImageList_Replace(himl, 2, hbm3, 0),"failed to replace bitmap 3\n");
476 memset(&imldp, 0, sizeof (imldp));
477 ok(!pImageList_DrawIndirect(&imldp), "zero data succeeded!\n");
478 imldp.cbSize = sizeof (imldp);
479 ok(!pImageList_DrawIndirect(&imldp), "zero hdc succeeded!\n");
480 imldp.hdcDst = hdc;
481 ok(!pImageList_DrawIndirect(&imldp),"zero himl succeeded!\n");
482 imldp.himl = himl;
483 if (!pImageList_DrawIndirect(&imldp))
485 /* Earlier versions of native comctl32 use a smaller structure */
486 imldp.cbSize -= 3 * sizeof(DWORD);
487 ok(pImageList_DrawIndirect(&imldp),"DrawIndirect should succeed\n");
489 REDRAW(hwndfortest);
490 WAIT;
492 imldp.fStyle = SRCCOPY;
493 imldp.rgbBk = CLR_DEFAULT;
494 imldp.rgbFg = CLR_DEFAULT;
495 imldp.y = 100;
496 imldp.x = 100;
497 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
498 imldp.i ++;
499 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
500 imldp.i ++;
501 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
502 imldp.i ++;
503 ok(!pImageList_DrawIndirect(&imldp),"should fail\n");
505 /* remove three */
506 ok(ImageList_Remove(himl, 0), "removing 1st bitmap\n");
507 ok(ImageList_Remove(himl, 0), "removing 2nd bitmap\n");
508 ok(ImageList_Remove(himl, 0), "removing 3rd bitmap\n");
510 /* destroy it */
511 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
513 /* bitmaps should not be deleted by the imagelist */
514 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
515 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
516 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
518 ReleaseDC(hwndfortest, hdc);
519 DestroyWindow(hwndfortest);
521 return TRUE;
524 static void testMerge(void)
526 HIMAGELIST himl1, himl2, hmerge;
527 HICON hicon1;
528 HWND hwnd = create_a_window();
530 himl1 = ImageList_Create(32,32,0,0,3);
531 ok(himl1 != NULL,"failed to create himl1\n");
533 himl2 = ImageList_Create(32,32,0,0,3);
534 ok(himl2 != NULL,"failed to create himl2\n");
536 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
537 ok(hicon1 != NULL, "failed to create hicon1\n");
539 if (!himl1 || !himl2 || !hicon1)
540 return;
542 ok(0==ImageList_AddIcon(himl2, hicon1),"add icon1 to himl2 failed\n");
543 check_bits(hwnd, himl2, 0, 32, icon_bits, "add icon1 to himl2");
545 /* If himl1 has no images, merge still succeeds */
546 hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
547 ok(hmerge != NULL, "merge himl1,-1 failed\n");
548 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,-1");
549 if (hmerge) ImageList_Destroy(hmerge);
551 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
552 ok(hmerge != NULL,"merge himl1,0 failed\n");
553 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,0");
554 if (hmerge) ImageList_Destroy(hmerge);
556 /* Same happens if himl2 is empty */
557 ImageList_Destroy(himl2);
558 himl2 = ImageList_Create(32,32,0,0,3);
559 ok(himl2 != NULL,"failed to recreate himl2\n");
560 if (!himl2)
561 return;
563 hmerge = ImageList_Merge(himl1, -1, himl2, -1, 0, 0);
564 ok(hmerge != NULL, "merge himl2,-1 failed\n");
565 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,-1");
566 if (hmerge) ImageList_Destroy(hmerge);
568 hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
569 ok(hmerge != NULL, "merge himl2,0 failed\n");
570 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,0");
571 if (hmerge) ImageList_Destroy(hmerge);
573 /* Now try merging an image with itself */
574 ok(0==ImageList_AddIcon(himl2, hicon1),"re-add icon1 to himl2 failed\n");
576 hmerge = ImageList_Merge(himl2, 0, himl2, 0, 0, 0);
577 ok(hmerge != NULL, "merge himl2 with itself failed\n");
578 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2 with itself");
579 if (hmerge) ImageList_Destroy(hmerge);
581 /* Try merging 2 different image lists */
582 ok(0==ImageList_AddIcon(himl1, hicon1),"add icon1 to himl1 failed\n");
584 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
585 ok(hmerge != NULL, "merge himl1 with himl2 failed\n");
586 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2");
587 if (hmerge) ImageList_Destroy(hmerge);
589 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 8, 16);
590 ok(hmerge != NULL, "merge himl1 with himl2 8,16 failed\n");
591 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2, 8,16");
592 if (hmerge) ImageList_Destroy(hmerge);
594 ImageList_Destroy(himl1);
595 ImageList_Destroy(himl2);
596 DestroyIcon(hicon1);
597 DestroyWindow(hwnd);
600 /*********************** imagelist storage test ***************************/
602 #define BMP_CX 48
604 struct my_IStream
606 IStream is;
607 char *iml_data; /* written imagelist data */
608 ULONG iml_data_size;
611 static HRESULT STDMETHODCALLTYPE Test_Stream_QueryInterface(
612 IStream* This,
613 REFIID riid,
614 void** ppvObject)
616 assert(0);
617 return E_NOTIMPL;
620 static ULONG STDMETHODCALLTYPE Test_Stream_AddRef(
621 IStream* This)
623 assert(0);
624 return 2;
627 static ULONG STDMETHODCALLTYPE Test_Stream_Release(
628 IStream* This)
630 assert(0);
631 return 1;
634 static HRESULT STDMETHODCALLTYPE Test_Stream_Read(
635 IStream* This,
636 void* pv,
637 ULONG cb,
638 ULONG* pcbRead)
640 assert(0);
641 return E_NOTIMPL;
644 static BOOL allocate_storage(struct my_IStream *my_is, ULONG add)
646 my_is->iml_data_size += add;
648 if (!my_is->iml_data)
649 my_is->iml_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, my_is->iml_data_size);
650 else
651 my_is->iml_data = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, my_is->iml_data, my_is->iml_data_size);
653 return my_is->iml_data ? TRUE : FALSE;
656 static HRESULT STDMETHODCALLTYPE Test_Stream_Write(
657 IStream* This,
658 const void* pv,
659 ULONG cb,
660 ULONG* pcbWritten)
662 struct my_IStream *my_is = (struct my_IStream *)This;
663 ULONG current_iml_data_size = my_is->iml_data_size;
665 if (!allocate_storage(my_is, cb)) return E_FAIL;
667 memcpy(my_is->iml_data + current_iml_data_size, pv, cb);
668 if (pcbWritten) *pcbWritten = cb;
670 return S_OK;
673 static HRESULT STDMETHODCALLTYPE Test_Stream_Seek(
674 IStream* This,
675 LARGE_INTEGER dlibMove,
676 DWORD dwOrigin,
677 ULARGE_INTEGER* plibNewPosition)
679 assert(0);
680 return E_NOTIMPL;
683 static HRESULT STDMETHODCALLTYPE Test_Stream_SetSize(
684 IStream* This,
685 ULARGE_INTEGER libNewSize)
687 assert(0);
688 return E_NOTIMPL;
691 static HRESULT STDMETHODCALLTYPE Test_Stream_CopyTo(
692 IStream* This,
693 IStream* pstm,
694 ULARGE_INTEGER cb,
695 ULARGE_INTEGER* pcbRead,
696 ULARGE_INTEGER* pcbWritten)
698 assert(0);
699 return E_NOTIMPL;
702 static HRESULT STDMETHODCALLTYPE Test_Stream_Commit(
703 IStream* This,
704 DWORD grfCommitFlags)
706 assert(0);
707 return E_NOTIMPL;
710 static HRESULT STDMETHODCALLTYPE Test_Stream_Revert(
711 IStream* This)
713 assert(0);
714 return E_NOTIMPL;
717 static HRESULT STDMETHODCALLTYPE Test_Stream_LockRegion(
718 IStream* This,
719 ULARGE_INTEGER libOffset,
720 ULARGE_INTEGER cb,
721 DWORD dwLockType)
723 assert(0);
724 return E_NOTIMPL;
727 static HRESULT STDMETHODCALLTYPE Test_Stream_UnlockRegion(
728 IStream* This,
729 ULARGE_INTEGER libOffset,
730 ULARGE_INTEGER cb,
731 DWORD dwLockType)
733 assert(0);
734 return E_NOTIMPL;
737 static HRESULT STDMETHODCALLTYPE Test_Stream_Stat(
738 IStream* This,
739 STATSTG* pstatstg,
740 DWORD grfStatFlag)
742 assert(0);
743 return E_NOTIMPL;
746 static HRESULT STDMETHODCALLTYPE Test_Stream_Clone(
747 IStream* This,
748 IStream** ppstm)
750 assert(0);
751 return E_NOTIMPL;
754 static const IStreamVtbl Test_Stream_Vtbl =
756 Test_Stream_QueryInterface,
757 Test_Stream_AddRef,
758 Test_Stream_Release,
759 Test_Stream_Read,
760 Test_Stream_Write,
761 Test_Stream_Seek,
762 Test_Stream_SetSize,
763 Test_Stream_CopyTo,
764 Test_Stream_Commit,
765 Test_Stream_Revert,
766 Test_Stream_LockRegion,
767 Test_Stream_UnlockRegion,
768 Test_Stream_Stat,
769 Test_Stream_Clone
772 static struct my_IStream Test_Stream = { { &Test_Stream_Vtbl }, 0, 0 };
774 static INT DIB_GetWidthBytes( int width, int bpp )
776 int words;
778 switch (bpp)
780 case 1: words = (width + 31) / 32; break;
781 case 4: words = (width + 7) / 8; break;
782 case 8: words = (width + 3) / 4; break;
783 case 15:
784 case 16: words = (width + 1) / 2; break;
785 case 24: words = (width * 3 + 3)/4; break;
786 case 32: words = width; break;
788 default:
789 words=0;
790 trace("Unknown depth %d, please report.\n", bpp );
791 assert(0);
792 break;
794 return 4 * words;
797 static void check_bitmap_data(const char *bm_data, ULONG bm_data_size,
798 INT width, INT height, INT bpp,
799 const char *comment)
801 const BITMAPFILEHEADER *bmfh = (const BITMAPFILEHEADER *)bm_data;
802 const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)(bm_data + sizeof(*bmfh));
803 ULONG hdr_size, image_size;
805 hdr_size = sizeof(*bmfh) + sizeof(*bmih);
806 if (bmih->biBitCount <= 8) hdr_size += (1 << bpp) * sizeof(RGBQUAD);
808 ok(bmfh->bfType == (('M' << 8) | 'B'), "wrong bfType 0x%02x\n", bmfh->bfType);
809 ok(bmfh->bfSize == hdr_size, "wrong bfSize 0x%02x\n", bmfh->bfSize);
810 ok(bmfh->bfReserved1 == 0, "wrong bfReserved1 0x%02x\n", bmfh->bfReserved1);
811 ok(bmfh->bfReserved2 == 0, "wrong bfReserved2 0x%02x\n", bmfh->bfReserved2);
812 ok(bmfh->bfOffBits == hdr_size, "wrong bfOffBits 0x%02x\n", bmfh->bfOffBits);
814 ok(bmih->biSize == sizeof(*bmih), "wrong biSize %d\n", bmih->biSize);
815 ok(bmih->biWidth == width, "wrong biWidth %d (expected %d)\n", bmih->biWidth, width);
816 ok(bmih->biHeight == height, "wrong biHeight %d (expected %d)\n", bmih->biHeight, height);
817 ok(bmih->biPlanes == 1, "wrong biPlanes %d\n", bmih->biPlanes);
818 ok(bmih->biBitCount == bpp, "wrong biBitCount %d\n", bmih->biBitCount);
820 image_size = DIB_GetWidthBytes(bmih->biWidth, bmih->biBitCount) * bmih->biHeight;
821 ok(bmih->biSizeImage == image_size, "wrong biSizeImage %u\n", bmih->biSizeImage);
822 #if 0
824 char fname[256];
825 FILE *f;
826 sprintf(fname, "bmp_%s.bmp", comment);
827 f = fopen(fname, "wb");
828 fwrite(bm_data, 1, bm_data_size, f);
829 fclose(f);
831 #endif
834 static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max)
836 ILHEAD *ilh = (ILHEAD *)ilh_data;
838 ok(ilh->usMagic == IMAGELIST_MAGIC, "wrong usMagic %4x (expected %02x)\n", ilh->usMagic, IMAGELIST_MAGIC);
839 ok(ilh->usVersion == 0x101, "wrong usVersion %x (expected 0x101)\n", ilh->usVersion);
840 ok(ilh->cCurImage == cur, "wrong cCurImage %d (expected %d)\n", ilh->cCurImage, cur);
841 ok(ilh->cMaxImage == max, "wrong cMaxImage %d (expected %d)\n", ilh->cMaxImage, max);
842 ok(ilh->cGrow == 4, "wrong cGrow %d (expected 4)\n", ilh->cGrow);
843 ok(ilh->cx == cx, "wrong cx %d (expected %d)\n", ilh->cx, cx);
844 ok(ilh->cy == cy, "wrong cy %d (expected %d)\n", ilh->cy, cy);
845 ok(ilh->bkcolor == CLR_NONE, "wrong bkcolor %x\n", ilh->bkcolor);
846 ok(ilh->flags == ILC_COLOR24, "wrong flags %04x\n", ilh->flags);
847 ok(ilh->ovls[0] == -1 ||
848 ilh->ovls[0] == 0, /* win95 */
849 "wrong ovls[0] %04x\n", ilh->ovls[0]);
850 ok(ilh->ovls[1] == -1 ||
851 ilh->ovls[1] == 0, /* win95 */
852 "wrong ovls[1] %04x\n", ilh->ovls[1]);
853 ok(ilh->ovls[2] == -1 ||
854 ilh->ovls[2] == 0, /* win95 */
855 "wrong ovls[2] %04x\n", ilh->ovls[2]);
856 ok(ilh->ovls[3] == -1 ||
857 ilh->ovls[3] == 0, /* win95 */
858 "wrong ovls[3] %04x\n", ilh->ovls[3]);
861 static HBITMAP create_bitmap(INT cx, INT cy, COLORREF color, const char *comment)
863 HDC hdc;
864 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
865 BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
866 HBITMAP hbmp, hbmp_old;
867 HBRUSH hbrush;
868 RECT rc = { 0, 0, cx, cy };
870 hdc = CreateCompatibleDC(0);
872 memset(bmi, 0, sizeof(*bmi));
873 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
874 bmi->bmiHeader.biHeight = cx;
875 bmi->bmiHeader.biWidth = cy;
876 bmi->bmiHeader.biBitCount = 24;
877 bmi->bmiHeader.biPlanes = 1;
878 bmi->bmiHeader.biCompression = BI_RGB;
879 hbmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
881 hbmp_old = SelectObject(hdc, hbmp);
883 hbrush = CreateSolidBrush(color);
884 FillRect(hdc, &rc, hbrush);
885 DeleteObject(hbrush);
887 DrawText(hdc, comment, -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
889 SelectObject(hdc, hbmp_old);
890 DeleteDC(hdc);
892 return hbmp;
895 static void image_list_init(HIMAGELIST himl)
897 HBITMAP hbm;
898 char comment[16];
899 INT n = 1;
901 #define add_bitmap(grey) \
902 sprintf(comment, "%d", n++); \
903 hbm = create_bitmap(BMP_CX, BMP_CX, RGB((grey),(grey),(grey)), comment); \
904 ImageList_Add(himl, hbm, NULL);
906 add_bitmap(255); add_bitmap(170); add_bitmap(85); add_bitmap(0);
907 add_bitmap(0); add_bitmap(85); add_bitmap(170); add_bitmap(255);
908 add_bitmap(255); add_bitmap(170); add_bitmap(85); add_bitmap(0);
909 add_bitmap(0); add_bitmap(85); add_bitmap(170); add_bitmap(255);
910 add_bitmap(255); add_bitmap(170); add_bitmap(85); add_bitmap(0);
911 add_bitmap(0); add_bitmap(85); add_bitmap(170); add_bitmap(255);
912 #undef add_bitmap
915 #define iml_clear_stream_data() \
916 HeapFree(GetProcessHeap(), 0, Test_Stream.iml_data); \
917 Test_Stream.iml_data = NULL; \
918 Test_Stream.iml_data_size = 0;
920 static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max,
921 INT width, INT height, INT bpp, const char *comment)
923 INT ret, cxx, cyy;
925 ret = ImageList_GetImageCount(himl);
926 ok(ret == cur, "expected cur %d got %d\n", cur, ret);
928 ret = ImageList_GetIconSize(himl, &cxx, &cyy);
929 ok(ret, "ImageList_GetIconSize failed\n");
930 ok(cxx == cx, "wrong cx %d (expected %d)\n", cxx, cx);
931 ok(cyy == cy, "wrong cy %d (expected %d)\n", cyy, cy);
933 iml_clear_stream_data();
934 ret = ImageList_Write(himl, &Test_Stream.is);
935 ok(ret, "ImageList_Write failed\n");
937 ok(Test_Stream.iml_data != 0, "ImageList_Write didn't write any data\n");
938 ok(Test_Stream.iml_data_size > sizeof(ILHEAD), "ImageList_Write wrote not enough data\n");
940 check_ilhead_data(Test_Stream.iml_data, cx, cy, cur, max);
941 check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD),
942 Test_Stream.iml_data_size - sizeof(ILHEAD),
943 width, height, bpp, comment);
946 static void test_imagelist_storage(void)
948 HIMAGELIST himl;
949 BOOL ret;
951 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 1, 1);
952 ok(himl != 0, "ImageList_Create failed\n");
954 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, BMP_CX * 4, BMP_CX * 1, 24, "empty");
956 image_list_init(himl);
957 check_iml_data(himl, BMP_CX, BMP_CX, 24, 27, BMP_CX * 4, BMP_CX * 7, 24, "orig");
959 ret = ImageList_Remove(himl, 4);
960 ok(ret, "ImageList_Remove failed\n");
961 check_iml_data(himl, BMP_CX, BMP_CX, 23, 27, BMP_CX * 4, BMP_CX * 7, 24, "1");
963 ret = ImageList_Remove(himl, 5);
964 ok(ret, "ImageList_Remove failed\n");
965 check_iml_data(himl, BMP_CX, BMP_CX, 22, 27, BMP_CX * 4, BMP_CX * 7, 24, "2");
967 ret = ImageList_Remove(himl, 6);
968 ok(ret, "ImageList_Remove failed\n");
969 check_iml_data(himl, BMP_CX, BMP_CX, 21, 27, BMP_CX * 4, BMP_CX * 7, 24, "3");
971 ret = ImageList_Remove(himl, 7);
972 ok(ret, "ImageList_Remove failed\n");
973 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, BMP_CX * 4, BMP_CX * 7, 24, "4");
975 ret = ImageList_Remove(himl, -2);
976 ok(!ret, "ImageList_Remove(-2) should fail\n");
977 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, BMP_CX * 4, BMP_CX * 7, 24, "5");
979 ret = ImageList_Remove(himl, 20);
980 ok(!ret, "ImageList_Remove(20) should fail\n");
981 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, BMP_CX * 4, BMP_CX * 7, 24, "6");
983 ret = ImageList_Remove(himl, -1);
984 ok(ret, "ImageList_Remove(-1) failed\n");
985 check_iml_data(himl, BMP_CX, BMP_CX, 0, 4, BMP_CX * 4, BMP_CX * 1, 24, "7");
987 ret = ImageList_Destroy(himl);
988 ok(ret, "ImageList_Destroy failed\n");
990 iml_clear_stream_data();
993 static void test_shell_imagelist(void)
995 BOOL (WINAPI *pSHGetImageList)(INT, REFIID, void**);
996 IImageList *iml = NULL;
997 HMODULE hShell32;
998 HRESULT hr;
999 int out = 0;
1000 RECT rect;
1001 int cx, cy;
1003 /* Try to load function from shell32 */
1004 hShell32 = LoadLibrary("shell32.dll");
1005 pSHGetImageList = (void*)GetProcAddress(hShell32, (LPCSTR) 727);
1007 if (!pSHGetImageList)
1009 win_skip("SHGetImageList not available, skipping test\n");
1010 return;
1013 /* Get system image list */
1014 hr = (pSHGetImageList)(SHIL_SYSSMALL, &IID_IImageList, (void**)&iml);
1016 ok(SUCCEEDED(hr), "SHGetImageList failed, hr=%x\n", hr);
1018 if (hr != S_OK)
1019 return;
1021 IImageList_GetImageCount(iml, &out);
1022 ok(out > 0, "IImageList_GetImageCount returned out <= 0\n");
1024 /* Fetch the small icon size */
1025 cx = GetSystemMetrics(SM_CXSMICON);
1026 cy = GetSystemMetrics(SM_CYSMICON);
1028 /* Check icon size matches */
1029 IImageList_GetImageRect(iml, 0, &rect);
1030 ok(((rect.right == cx) && (rect.bottom == cy)),
1031 "IImageList_GetImageRect returned r:%d,b:%d\n",
1032 rect.right, rect.bottom);
1034 IImageList_Release(iml);
1035 FreeLibrary(hShell32);
1038 static HBITMAP create_test_bitmap(HDC hdc, int bpp, UINT32 pixel1, UINT32 pixel2)
1040 HBITMAP hBitmap;
1041 UINT32 *buffer = NULL;
1042 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, bpp, BI_RGB,
1043 0, 0, 0, 0, 0}};
1045 hBitmap = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, NULL, 0);
1046 ok(hBitmap != NULL && buffer != NULL, "CreateDIBSection failed.\n");
1048 if(!hBitmap || !buffer)
1050 DeleteObject(hBitmap);
1051 return NULL;
1054 buffer[0] = pixel1;
1055 buffer[1] = pixel2;
1057 return hBitmap;
1060 static BOOL colour_match(UINT32 x, UINT32 y)
1062 const INT32 tolerance = 8;
1064 const INT32 dr = abs((INT32)(x & 0x000000FF) - (INT32)(y & 0x000000FF));
1065 const INT32 dg = abs((INT32)((x & 0x0000FF00) >> 8) - (INT32)((y & 0x0000FF00) >> 8));
1066 const INT32 db = abs((INT32)((x & 0x00FF0000) >> 16) - (INT32)((y & 0x00FF0000) >> 16));
1068 return (dr <= tolerance && dg <= tolerance && db <= tolerance);
1071 static void check_ImageList_DrawIndirect(IMAGELISTDRAWPARAMS *ildp, UINT32 *bits,
1072 UINT32 expected, int line)
1074 bits[0] = 0x00FFFFFF;
1075 pImageList_DrawIndirect(ildp);
1076 ok(colour_match(bits[0], expected),
1077 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1078 bits[0] & 0x00FFFFFF, expected, line);
1082 static void check_ImageList_DrawIndirect_fStyle(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1083 UINT fStyle, UINT32 expected, int line)
1085 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1086 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, ILS_NORMAL, 0, 0x00000000};
1087 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1090 static void check_ImageList_DrawIndirect_ILD_ROP(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1091 DWORD dwRop, UINT32 expected, int line)
1093 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1094 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_IMAGE | ILD_ROP, dwRop, ILS_NORMAL, 0, 0x00000000};
1095 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1098 static void check_ImageList_DrawIndirect_fState(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i, UINT fStyle,
1099 UINT fState, DWORD Frame, UINT32 expected, int line)
1101 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1102 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1103 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1106 static void check_ImageList_DrawIndirect_broken(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1107 UINT fStyle, UINT fState, DWORD Frame, UINT32 expected,
1108 UINT32 broken_expected, int line)
1110 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1111 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1112 bits[0] = 0x00FFFFFF;
1113 pImageList_DrawIndirect(&ildp);
1114 ok(colour_match(bits[0], expected) ||
1115 broken(colour_match(bits[0], broken_expected)),
1116 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1117 bits[0] & 0x00FFFFFF, expected, line);
1120 static void test_ImageList_DrawIndirect(void)
1122 HIMAGELIST himl = NULL;
1123 int ret;
1124 HDC hdcDst = NULL;
1125 HBITMAP hbmOld = NULL, hbmDst = NULL;
1126 HBITMAP hbmMask = NULL, hbmInverseMask = NULL;
1127 HBITMAP hbmImage = NULL, hbmAlphaImage = NULL, hbmTransparentImage = NULL;
1128 int iImage = -1, iAlphaImage = -1, iTransparentImage = -1;
1129 UINT32 *bits = 0;
1130 UINT32 maskBits = 0x00000000, inverseMaskBits = 0xFFFFFFFF;
1132 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB,
1133 0, 0, 0, 0, 0}};
1135 hdcDst = CreateCompatibleDC(0);
1136 ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
1137 if (!hdcDst)
1138 return;
1140 hbmMask = CreateBitmap(2, 1, 1, 1, &maskBits);
1141 ok(hbmMask != 0, "CreateBitmap failed\n");
1142 if(!hbmMask) goto cleanup;
1144 hbmInverseMask = CreateBitmap(2, 1, 1, 1, &inverseMaskBits);
1145 ok(hbmInverseMask != 0, "CreateBitmap failed\n");
1146 if(!hbmInverseMask) goto cleanup;
1148 himl = pImageList_Create(2, 1, ILC_COLOR32, 0, 1);
1149 ok(himl != 0, "ImageList_Create failed\n");
1150 if(!himl) goto cleanup;
1152 /* Add a no-alpha image */
1153 hbmImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x00ABCDEF);
1154 if(!hbmImage) goto cleanup;
1156 iImage = pImageList_Add(himl, hbmImage, hbmMask);
1157 ok(iImage != -1, "ImageList_Add failed\n");
1158 if(iImage == -1) goto cleanup;
1160 /* Add an alpha image */
1161 hbmAlphaImage = create_test_bitmap(hdcDst, 32, 0x89ABCDEF, 0x89ABCDEF);
1162 if(!hbmAlphaImage) goto cleanup;
1164 iAlphaImage = pImageList_Add(himl, hbmAlphaImage, hbmMask);
1165 ok(iAlphaImage != -1, "ImageList_Add failed\n");
1166 if(iAlphaImage == -1) goto cleanup;
1168 /* Add a transparent alpha image */
1169 hbmTransparentImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x89ABCDEF);
1170 if(!hbmTransparentImage) goto cleanup;
1172 iTransparentImage = pImageList_Add(himl, hbmTransparentImage, hbmMask);
1173 ok(iTransparentImage != -1, "ImageList_Add failed\n");
1174 if(iTransparentImage == -1) goto cleanup;
1176 /* 32-bit Tests */
1177 bitmapInfo.bmiHeader.biBitCount = 32;
1178 hbmDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1179 ok (hbmDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1180 if (!hbmDst || !bits)
1181 goto cleanup;
1182 hbmOld = SelectObject(hdcDst, hbmDst);
1184 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_NORMAL, 0x00ABCDEF, __LINE__);
1185 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_TRANSPARENT, 0x00ABCDEF, __LINE__);
1186 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x00D4D9DD, __LINE__);
1187 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, 0x00B4BDC4, __LINE__);
1188 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_MASK, 0x00ABCDEF, __LINE__);
1189 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_IMAGE, 0x00ABCDEF, __LINE__);
1190 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_PRESERVEALPHA, 0x00ABCDEF, __LINE__);
1192 todo_wine
1194 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, 0x00D3E5F7, __LINE__);
1195 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_TRANSPARENT, 0x00D3E5F7, __LINE__);
1196 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x009DA8B1, __LINE__);
1197 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, 0x008C99A3, __LINE__);
1199 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0x00D3E5F7, __LINE__);
1200 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0x00D3E5F7, __LINE__);
1201 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__);
1204 todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__);
1206 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCCOPY, 0x00ABCDEF, __LINE__);
1207 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCINVERT, 0x00543210, __LINE__);
1209 /* ILD_ROP is ignored when the image has an alpha channel */
1210 todo_wine check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCCOPY, 0x00D3E5F7, __LINE__);
1211 todo_wine check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCINVERT, 0x00D3E5F7, __LINE__);
1213 todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00CCCCCC, __LINE__);
1214 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00AFAFAF, 0x00F0F0F0, __LINE__);
1216 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_GLOW, 0, 0x00ABCDEF, __LINE__);
1217 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SHADOW, 0, 0x00ABCDEF, __LINE__);
1219 todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00D5E6F7, __LINE__);
1220 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00E9F2FB, 0x00AEB7C0, __LINE__);
1221 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_NORMAL, 127, 0x00E9F2FB, 0x00D3E5F7, __LINE__);
1223 cleanup:
1225 if(hbmOld)
1226 SelectObject(hdcDst, hbmOld);
1227 if(hbmDst)
1228 DeleteObject(hbmDst);
1230 if(hdcDst)
1231 DeleteDC(hdcDst);
1233 if(hbmMask)
1234 DeleteObject(hbmMask);
1235 if(hbmInverseMask)
1236 DeleteObject(hbmInverseMask);
1238 if(hbmImage)
1239 DeleteObject(hbmImage);
1240 if(hbmAlphaImage)
1241 DeleteObject(hbmAlphaImage);
1242 if(hbmTransparentImage)
1243 DeleteObject(hbmTransparentImage);
1245 if(himl)
1247 ret = ImageList_Destroy(himl);
1248 ok(ret, "ImageList_Destroy failed\n");
1252 static void test_iimagelist(void)
1254 IImageList *imgl;
1255 HIMAGELIST himl;
1256 HRESULT hr;
1257 ULONG ret;
1259 if (!pHIMAGELIST_QueryInterface)
1261 win_skip("XP imagelist functions not available\n");
1262 return;
1265 /* test reference counting on destruction */
1266 imgl = (IImageList*)createImageList(32, 32);
1267 ret = IUnknown_AddRef(imgl);
1268 ok(ret == 2, "Expected 2, got %d\n", ret);
1269 ret = ImageList_Destroy((HIMAGELIST)imgl);
1270 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1271 ret = ImageList_Destroy((HIMAGELIST)imgl);
1272 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1273 ret = ImageList_Destroy((HIMAGELIST)imgl);
1274 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1276 imgl = (IImageList*)createImageList(32, 32);
1277 ret = IUnknown_AddRef(imgl);
1278 ok(ret == 2, "Expected 2, got %d\n", ret);
1279 ret = ImageList_Destroy((HIMAGELIST)imgl);
1280 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1281 ret = IImageList_Release(imgl);
1282 ok(ret == 0, "Expected 0, got %d\n", ret);
1283 ret = ImageList_Destroy((HIMAGELIST)imgl);
1284 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1286 if (!pImageList_CoCreateInstance)
1288 win_skip("Vista imagelist functions not available\n");
1289 return;
1292 hr = pImageList_CoCreateInstance(&CLSID_ImageList, NULL, &IID_IImageList, (void **) &imgl);
1293 ok(SUCCEEDED(hr), "ImageList_CoCreateInstance failed, hr=%x\n", hr);
1295 if (hr == S_OK)
1296 IImageList_Release(imgl);
1298 himl = createImageList(32, 32);
1300 if (!himl)
1301 return;
1303 hr = (pHIMAGELIST_QueryInterface)(himl, &IID_IImageList, (void **) &imgl);
1304 ok(SUCCEEDED(hr), "HIMAGELIST_QueryInterface failed, hr=%x\n", hr);
1306 if (hr == S_OK)
1307 IImageList_Release(imgl);
1309 ImageList_Destroy(himl);
1312 static void testHotspot_v6(void)
1314 struct hotspot {
1315 int dx;
1316 int dy;
1319 #define SIZEX1 47
1320 #define SIZEY1 31
1321 #define SIZEX2 11
1322 #define SIZEY2 17
1323 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
1324 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
1325 { 10, 7 },
1326 { SIZEX1, SIZEY1 },
1327 { -9, -8 },
1328 { -7, 35 }
1330 int i, j;
1331 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
1332 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
1333 IImageList *imgl1, *imgl2;
1334 HRESULT hr;
1336 /* cast to IImageList */
1337 imgl1 = (IImageList *) himl1;
1338 imgl2 = (IImageList *) himl2;
1340 for (i = 0; i < HOTSPOTS_MAX; i++) {
1341 for (j = 0; j < HOTSPOTS_MAX; j++) {
1342 int dx1 = hotspots[i].dx;
1343 int dy1 = hotspots[i].dy;
1344 int dx2 = hotspots[j].dx;
1345 int dy2 = hotspots[j].dy;
1346 int correctx, correcty, newx, newy;
1347 char loc[256];
1348 IImageList *imglNew;
1349 POINT ppt;
1351 hr = IImageList_BeginDrag(imgl1, 0, dx1, dy1);
1352 ok(SUCCEEDED(hr), "BeginDrag failed for { %d, %d }\n", dx1, dy1);
1353 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
1355 /* check merging the dragged image with a second image */
1356 hr = IImageList_SetDragCursorImage(imgl2, (IUnknown *) imgl2, 0, dx2, dy2);
1357 ok(SUCCEEDED(hr), "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
1358 dx1, dy1, dx2, dy2);
1359 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
1361 /* check new hotspot, it should be the same like the old one */
1362 hr = IImageList_GetDragImage(imgl2, NULL, &ppt, &IID_IImageList, (PVOID *) &imglNew);
1363 ok(SUCCEEDED(hr), "GetDragImage failed\n");
1364 ok(ppt.x == dx1 && ppt.y == dy1,
1365 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
1366 dx1, dy1, ppt.x, ppt.y);
1367 /* check size of new dragged image */
1368 IImageList_GetIconSize(imglNew, &newx, &newy);
1369 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
1370 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
1371 ok(newx == correctx && newy == correcty,
1372 "Expected drag image size [%d,%d] got [%d,%d]\n",
1373 correctx, correcty, newx, newy);
1374 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
1375 IImageList_EndDrag(imgl2);
1378 #undef SIZEX1
1379 #undef SIZEY1
1380 #undef SIZEX2
1381 #undef SIZEY2
1382 #undef HOTSPOTS_MAX
1383 IImageList_Release(imgl2);
1384 IImageList_Release(imgl1);
1387 static void DoTest1_v6(void)
1389 IImageList *imgl;
1390 HIMAGELIST himl;
1391 HRESULT hr;
1393 HICON hicon1;
1394 HICON hicon2;
1395 HICON hicon3;
1397 int ret = 0;
1399 /* create an imagelist to play with */
1400 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1401 ok(himl != 0,"failed to create imagelist\n");
1403 imgl = (IImageList *) himl;
1405 /* load the icons to add to the image list */
1406 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1407 ok(hicon1 != 0, "no hicon1\n");
1408 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1409 ok(hicon2 != 0, "no hicon2\n");
1410 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1411 ok(hicon3 != 0, "no hicon3\n");
1413 /* remove when nothing exists */
1414 hr = IImageList_Remove(imgl, 0);
1415 ok(!(SUCCEEDED(hr)), "removed nonexistent icon\n");
1417 /* removing everything from an empty imagelist should succeed */
1418 hr = IImageList_Remove(imgl, -1);
1419 ok(SUCCEEDED(hr), "removed nonexistent icon\n");
1421 /* add three */
1422 ok(SUCCEEDED(IImageList_ReplaceIcon(imgl, -1, hicon1, &ret)) && (ret == 0),"failed to add icon1\n");
1423 ok(SUCCEEDED(IImageList_ReplaceIcon(imgl, -1, hicon2, &ret)) && (ret == 1),"failed to add icon2\n");
1424 ok(SUCCEEDED(IImageList_ReplaceIcon(imgl, -1, hicon3, &ret)) && (ret == 2),"failed to add icon3\n");
1426 /* remove an index out of range */
1427 ok(FAILED(IImageList_Remove(imgl, 4711)),"removed nonexistent icon\n");
1429 /* remove three */
1430 ok(SUCCEEDED(IImageList_Remove(imgl,0)),"can't remove 0\n");
1431 ok(SUCCEEDED(IImageList_Remove(imgl,0)),"can't remove 0\n");
1432 ok(SUCCEEDED(IImageList_Remove(imgl,0)),"can't remove 0\n");
1434 /* remove one extra */
1435 ok(FAILED(IImageList_Remove(imgl, 0)),"removed nonexistent icon\n");
1437 /* check SetImageCount/GetImageCount */
1438 ok(SUCCEEDED(IImageList_SetImageCount(imgl, 3)), "couldn't increase image count\n");
1439 ok(SUCCEEDED(IImageList_GetImageCount(imgl, &ret)) && (ret == 3), "invalid image count after increase\n");
1440 ok(SUCCEEDED(IImageList_SetImageCount(imgl, 1)), "couldn't decrease image count\n");
1441 ok(SUCCEEDED(IImageList_GetImageCount(imgl, &ret)) && (ret == 1), "invalid image count after decrease to 1\n");
1442 ok(SUCCEEDED(IImageList_SetImageCount(imgl, 0)), "couldn't decrease image count\n");
1443 ok(SUCCEEDED(IImageList_GetImageCount(imgl, &ret)) && (ret == 0), "invalid image count after decrease to 0\n");
1445 /* destroy it */
1446 ok(SUCCEEDED(IImageList_Release(imgl)),"release imagelist failed\n");
1448 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
1449 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
1450 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
1453 static void DoTest3_v6(void)
1455 IImageList *imgl;
1456 HIMAGELIST himl;
1458 HBITMAP hbm1;
1459 HBITMAP hbm2;
1460 HBITMAP hbm3;
1462 IMAGELISTDRAWPARAMS imldp;
1463 HWND hwndfortest;
1464 HDC hdc;
1465 int ret;
1467 hwndfortest = create_a_window();
1468 hdc = GetDC(hwndfortest);
1469 ok(hdc!=NULL, "couldn't get DC\n");
1471 /* create an imagelist to play with */
1472 himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
1473 ok(himl!=0,"failed to create imagelist\n");
1475 imgl = (IImageList *) himl;
1477 /* load the icons to add to the image list */
1478 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1479 ok(hbm1 != 0, "no bitmap 1\n");
1480 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1481 ok(hbm2 != 0, "no bitmap 2\n");
1482 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1483 ok(hbm3 != 0, "no bitmap 3\n");
1485 /* add three */
1486 ok(SUCCEEDED(IImageList_Add(imgl, hbm1, 0, &ret)) && (ret == 0), "failed to add bitmap 1\n");
1487 ok(SUCCEEDED(IImageList_Add(imgl, hbm2, 0, &ret)) && (ret == 1), "failed to add bitmap 2\n");
1489 ok(SUCCEEDED(IImageList_SetImageCount(imgl, 3)), "Setimage count failed\n");
1490 ok(SUCCEEDED(IImageList_Replace(imgl, 2, hbm3, 0)), "failed to replace bitmap 3\n");
1492 memset(&imldp, 0, sizeof (imldp));
1493 ok(FAILED(IImageList_Draw(imgl, &imldp)), "zero data succeeded!\n");
1495 imldp.cbSize = sizeof (imldp);
1496 imldp.hdcDst = hdc;
1497 imldp.himl = himl;
1499 if (FAILED(IImageList_Draw(imgl, &imldp)))
1501 /* Earlier versions of native comctl32 use a smaller structure */
1502 imldp.cbSize -= 3 * sizeof(DWORD);
1503 ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n");
1506 REDRAW(hwndfortest);
1507 WAIT;
1509 imldp.fStyle = SRCCOPY;
1510 imldp.rgbBk = CLR_DEFAULT;
1511 imldp.rgbFg = CLR_DEFAULT;
1512 imldp.y = 100;
1513 imldp.x = 100;
1514 ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n");
1515 imldp.i ++;
1516 ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n");
1517 imldp.i ++;
1518 ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n");
1519 imldp.i ++;
1520 ok(FAILED(IImageList_Draw(imgl, &imldp)), "should fail\n");
1522 /* remove three */
1523 ok(SUCCEEDED(IImageList_Remove(imgl, 0)), "removing 1st bitmap\n");
1524 ok(SUCCEEDED(IImageList_Remove(imgl, 0)), "removing 2nd bitmap\n");
1525 ok(SUCCEEDED(IImageList_Remove(imgl, 0)), "removing 3rd bitmap\n");
1527 /* destroy it */
1528 ok(SUCCEEDED(IImageList_Release(imgl)), "release imagelist failed\n");
1530 /* bitmaps should not be deleted by the imagelist */
1531 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
1532 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
1533 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
1535 ReleaseDC(hwndfortest, hdc);
1536 DestroyWindow(hwndfortest);
1539 static void testMerge_v6(void)
1541 HIMAGELIST himl1, himl2;
1542 IImageList *imgl1, *imgl2, *merge;
1543 HICON hicon1;
1544 HWND hwnd = create_a_window();
1545 HRESULT hr;
1546 int ret;
1548 himl1 = ImageList_Create(32,32,0,0,3);
1549 ok(himl1 != NULL,"failed to create himl1\n");
1551 himl2 = ImageList_Create(32,32,0,0,3);
1552 ok(himl2 != NULL,"failed to create himl2\n");
1554 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1555 ok(hicon1 != NULL, "failed to create hicon1\n");
1557 if (!himl1 || !himl2 || !hicon1)
1558 return;
1560 /* cast to IImageList */
1561 imgl1 = (IImageList *) himl1;
1562 imgl2 = (IImageList *) himl2;
1564 ok(SUCCEEDED(IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret)) && (ret == 0),"add icon1 to himl2 failed\n");
1566 /* If himl1 has no images, merge still succeeds */
1567 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1568 ok(SUCCEEDED(hr), "merge himl1,-1 failed\n");
1569 if (SUCCEEDED(hr)) IImageList_Release(merge);
1571 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1572 ok(SUCCEEDED(hr), "merge himl1,0 failed\n");
1573 if (SUCCEEDED(hr)) IImageList_Release(merge);
1575 /* Same happens if himl2 is empty */
1576 IImageList_Release(imgl2);
1577 himl2 = ImageList_Create(32,32,0,0,3);
1578 ok(himl2 != NULL,"failed to recreate himl2\n");
1580 imgl2 = (IImageList *) himl2;
1582 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, -1, 0, 0, &IID_IImageList, (void **) &merge);
1583 ok(SUCCEEDED(hr), "merge himl2,-1 failed\n");
1584 if (SUCCEEDED(hr)) IImageList_Release(merge);
1586 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1587 ok(SUCCEEDED(hr), "merge himl2,0 failed\n");
1588 if (SUCCEEDED(hr)) IImageList_Release(merge);
1590 /* Now try merging an image with itself */
1591 ok(SUCCEEDED(IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret)) && (ret == 0),"re-add icon1 to himl2 failed\n");
1593 hr = IImageList_Merge(imgl2, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1594 ok(SUCCEEDED(hr), "merge himl2 with itself failed\n");
1595 if (SUCCEEDED(hr)) IImageList_Release(merge);
1597 /* Try merging 2 different image lists */
1598 ok(SUCCEEDED(IImageList_ReplaceIcon(imgl1, -1, hicon1, &ret)) && (ret == 0),"add icon1 to himl1 failed\n");
1600 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1601 ok(SUCCEEDED(hr), "merge himl1 with himl2 failed\n");
1602 if (SUCCEEDED(hr)) IImageList_Release(merge);
1604 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 8, 16, &IID_IImageList, (void **) &merge);
1605 ok(SUCCEEDED(hr), "merge himl1 with himl2 8,16 failed\n");
1606 if (SUCCEEDED(hr)) IImageList_Release(merge);
1608 IImageList_Release(imgl1);
1609 IImageList_Release(imgl2);
1611 DestroyIcon(hicon1);
1612 DestroyWindow(hwnd);
1615 START_TEST(imagelist)
1617 ULONG_PTR ctx_cookie;
1618 HANDLE hCtx;
1620 HMODULE hComCtl32 = GetModuleHandle("comctl32.dll");
1621 pImageList_Create = NULL; /* These are not needed for non-v6.0 tests*/
1622 pImageList_Add = NULL;
1623 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
1624 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
1626 hinst = GetModuleHandleA(NULL);
1628 InitCommonControls();
1630 testHotspot();
1631 DoTest1();
1632 DoTest2();
1633 DoTest3();
1634 testMerge();
1635 test_imagelist_storage();
1637 FreeLibrary(hComCtl32);
1639 /* Now perform v6 tests */
1641 if (!load_v6_module(&ctx_cookie, &hCtx))
1642 return;
1644 /* Reload comctl32 */
1645 hComCtl32 = LoadLibraryA("comctl32.dll");
1646 pImageList_Create = (void*)GetProcAddress(hComCtl32, "ImageList_Create");
1647 pImageList_Add = (void*)GetProcAddress(hComCtl32, "ImageList_Add");
1648 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
1649 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
1650 pImageList_CoCreateInstance = (void*)GetProcAddress(hComCtl32, "ImageList_CoCreateInstance");
1651 pHIMAGELIST_QueryInterface = (void*)GetProcAddress(hComCtl32, "HIMAGELIST_QueryInterface");
1653 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1655 /* Do v6.0 tests */
1656 test_ImageList_DrawIndirect();
1657 test_shell_imagelist();
1658 test_iimagelist();
1660 testHotspot_v6();
1661 DoTest1_v6();
1662 DoTest3_v6();
1663 testMerge_v6();
1665 CoUninitialize();
1667 unload_v6_module(ctx_cookie, hCtx);