57e7f5c069235dc940aab02912e04d0d60820895
[reactos.git] / modules / rostests / winetests / comctl32 / imagelist.c
1 /*
2 * Unit test suite for imagelist control.
3 *
4 * Copyright 2004 Michael Stefaniuc
5 * Copyright 2002 Mike McCormack for CodeWeavers
6 * Copyright 2007 Dmitry Timoshkov
7 * Copyright 2009 Owen Rudge for CodeWeavers
8 *
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.
13 *
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.
18 *
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
22 */
23
24 #include "precomp.h"
25
26 #include <ole2.h>
27 #include <shellapi.h>
28
29 #include <initguid.h>
30 #include <commoncontrols.h>
31
32 #define IMAGELIST_MAGIC (('L' << 8) | 'I')
33
34 #include "pshpack2.h"
35 /* Header used by ImageList_Read() and ImageList_Write() */
36 typedef struct _ILHEAD
37 {
38 USHORT usMagic;
39 USHORT usVersion;
40 WORD cCurImage;
41 WORD cMaxImage;
42 WORD cGrow;
43 WORD cx;
44 WORD cy;
45 COLORREF bkcolor;
46 WORD flags;
47 SHORT ovls[4];
48 } ILHEAD;
49 #include "poppack.h"
50
51 static HIMAGELIST (WINAPI *pImageList_Create)(int, int, UINT, int, int);
52 static int (WINAPI *pImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
53 static BOOL (WINAPI *pImageList_DrawIndirect)(IMAGELISTDRAWPARAMS*);
54 static BOOL (WINAPI *pImageList_SetImageCount)(HIMAGELIST,UINT);
55 static HRESULT (WINAPI *pImageList_CoCreateInstance)(REFCLSID,const IUnknown *,
56 REFIID,void **);
57 static HRESULT (WINAPI *pHIMAGELIST_QueryInterface)(HIMAGELIST,REFIID,void **);
58 static int (WINAPI *pImageList_SetColorTable)(HIMAGELIST,int,int,RGBQUAD*);
59
60 static HINSTANCE hinst;
61
62 /* only used in interactive mode */
63 static void force_redraw(HWND hwnd)
64 {
65 if (!winetest_interactive)
66 return;
67
68 RedrawWindow(hwnd, NULL, 0, RDW_UPDATENOW);
69 Sleep(1000);
70 }
71
72 /* These macros build cursor/bitmap data in 4x4 pixel blocks */
73 #define B(x,y) ((x?0xf0:0)|(y?0xf:0))
74 #define ROW1(a,b,c,d,e,f,g,h) B(a,b),B(c,d),B(e,f),B(g,h)
75 #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), \
76 ROW1(a,b,c,d,e,f,g,h), ROW1(a,b,c,d,e,f,g,h)
77 #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)
78 #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), \
79 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), \
80 ROW2(a,b,c,d,e,f,g,h,i,j,k,l)
81
82 static const BYTE empty_bits[48*48/8];
83
84 static const BYTE icon_bits[32*32/8] =
85 {
86 ROW32(0,0,0,0,0,0,0,0),
87 ROW32(0,0,1,1,1,1,0,0),
88 ROW32(0,1,1,1,1,1,1,0),
89 ROW32(0,1,1,0,0,1,1,0),
90 ROW32(0,1,1,0,0,1,1,0),
91 ROW32(0,1,1,1,1,1,1,0),
92 ROW32(0,0,1,1,1,1,0,0),
93 ROW32(0,0,0,0,0,0,0,0)
94 };
95
96 static const BYTE bitmap_bits[48*48/8] =
97 {
98 ROW48(0,0,0,0,0,0,0,0,0,0,0,0),
99 ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
100 ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
101 ROW48(0,1,0,0,0,0,0,0,1,0,1,0),
102 ROW48(0,1,0,0,0,0,0,1,0,0,1,0),
103 ROW48(0,1,0,0,0,0,1,0,0,0,1,0),
104 ROW48(0,1,0,0,0,1,0,0,0,0,1,0),
105 ROW48(0,1,0,0,1,0,0,0,0,0,1,0),
106 ROW48(0,1,0,1,0,0,0,0,0,0,1,0),
107 ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
108 ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
109 ROW48(0,0,0,0,0,0,0,0,0,0,0,0)
110 };
111
112 static HIMAGELIST createImageList(int cx, int cy)
113 {
114 /* Create an ImageList and put an image into it */
115 HIMAGELIST himl = ImageList_Create(cx, cy, ILC_COLOR, 1, 1);
116 HBITMAP hbm = CreateBitmap(48, 48, 1, 1, bitmap_bits);
117 ImageList_Add(himl, hbm, NULL);
118 DeleteObject(hbm);
119 return himl;
120 }
121
122 static HWND create_a_window(void)
123 {
124 char className[] = "bmwnd";
125 char winName[] = "Test Bitmap";
126 HWND hWnd;
127 static BOOL registered = FALSE;
128
129 if (!registered)
130 {
131 WNDCLASSA cls;
132
133 cls.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
134 cls.lpfnWndProc = DefWindowProcA;
135 cls.cbClsExtra = 0;
136 cls.cbWndExtra = 0;
137 cls.hInstance = 0;
138 cls.hIcon = LoadIconA(0, (LPCSTR)IDI_APPLICATION);
139 cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
140 cls.hbrBackground = GetStockObject (WHITE_BRUSH);
141 cls.lpszMenuName = 0;
142 cls.lpszClassName = className;
143
144 RegisterClassA (&cls);
145 registered = TRUE;
146 }
147
148 /* Setup window */
149 hWnd = CreateWindowA (className, winName,
150 WS_OVERLAPPEDWINDOW ,
151 CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
152 0, hinst, 0);
153
154 if (winetest_interactive)
155 {
156 ShowWindow (hWnd, SW_SHOW);
157 force_redraw (hWnd);
158 }
159
160 return hWnd;
161 }
162
163 static HDC show_image(HWND hwnd, HIMAGELIST himl, int idx, int size,
164 LPCSTR loc, BOOL clear)
165 {
166 HDC hdc;
167
168 if (!winetest_interactive || !himl) return NULL;
169
170 SetWindowTextA(hwnd, loc);
171 hdc = GetDC(hwnd);
172 ImageList_Draw(himl, idx, hdc, 0, 0, ILD_TRANSPARENT);
173
174 force_redraw(hwnd);
175
176 if (clear)
177 {
178 BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
179 ReleaseDC(hwnd, hdc);
180 hdc = NULL;
181 }
182
183 return hdc;
184 }
185
186 /* Useful for checking differences */
187 static void dump_bits(const BYTE *p, const BYTE *q, int size)
188 {
189 int i, j;
190
191 size /= 8;
192
193 for (i = 0; i < size * 2; i++)
194 {
195 printf("|");
196 for (j = 0; j < size; j++)
197 printf("%c%c", p[j] & 0xf0 ? 'X' : ' ', p[j] & 0xf ? 'X' : ' ');
198 printf(" -- ");
199 for (j = 0; j < size; j++)
200 printf("%c%c", q[j] & 0xf0 ? 'X' : ' ', q[j] & 0xf ? 'X' : ' ');
201 printf("|\n");
202 p += size * 4;
203 q += size * 4;
204 }
205 printf("\n");
206 }
207
208 static void check_bits(HWND hwnd, HIMAGELIST himl, int idx, int size,
209 const BYTE *checkbits, LPCSTR loc)
210 {
211 BYTE bits[100*100/8];
212 COLORREF c;
213 HDC hdc;
214 int x, y, i = -1;
215
216 if (!winetest_interactive || !himl) return;
217
218 memset(bits, 0, sizeof(bits));
219 hdc = show_image(hwnd, himl, idx, size, loc, FALSE);
220
221 c = GetPixel(hdc, 0, 0);
222
223 for (y = 0; y < size; y ++)
224 {
225 for (x = 0; x < size; x++)
226 {
227 if (!(x & 0x7)) i++;
228 if (GetPixel(hdc, x, y) != c) bits[i] |= (0x80 >> (x & 0x7));
229 }
230 }
231
232 BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
233 ReleaseDC(hwnd, hdc);
234
235 ok (memcmp(bits, checkbits, (size * size)/8) == 0,
236 "%s: bits different\n", loc);
237 if (memcmp(bits, checkbits, (size * size)/8))
238 dump_bits(bits, checkbits, size);
239 }
240
241 static void test_begindrag(void)
242 {
243 HIMAGELIST himl = createImageList(7,13);
244 HIMAGELIST drag;
245 BOOL ret;
246 int count;
247 POINT hotspot;
248
249 count = ImageList_GetImageCount(himl);
250 ok(count > 2, "Tests need an ImageList with more than 2 images\n");
251
252 /* Two BeginDrag() without EndDrag() in between */
253 ret = ImageList_BeginDrag(himl, 1, 0, 0);
254 drag = ImageList_GetDragImage(NULL, NULL);
255 ok(ret && drag, "ImageList_BeginDrag() failed\n");
256 ret = ImageList_BeginDrag(himl, 0, 3, 5);
257 ok(!ret, "ImageList_BeginDrag() returned TRUE\n");
258 drag = ImageList_GetDragImage(NULL, &hotspot);
259 ok(!!drag, "No active ImageList drag left\n");
260 ok(hotspot.x == 0 && hotspot.y == 0, "New ImageList drag was created\n");
261 ImageList_EndDrag();
262 drag = ImageList_GetDragImage(NULL, NULL);
263 ok(!drag, "ImageList drag was not destroyed\n");
264
265 /* Invalid image index */
266 ImageList_BeginDrag(himl, 0, 0, 0);
267 ret = ImageList_BeginDrag(himl, count, 3, 5);
268 ok(!ret, "ImageList_BeginDrag() returned TRUE\n");
269 drag = ImageList_GetDragImage(NULL, &hotspot);
270 ok(drag && hotspot.x == 0 && hotspot.y == 0, "Active drag should not have been canceled\n");
271 ImageList_EndDrag();
272 drag = ImageList_GetDragImage(NULL, NULL);
273 ok(!drag, "ImageList drag was not destroyed\n");
274 /* Invalid negative image indexes succeed */
275 ret = ImageList_BeginDrag(himl, -17, 0, 0);
276 drag = ImageList_GetDragImage(NULL, NULL);
277 ok(ret && drag, "ImageList drag was created\n");
278 ImageList_EndDrag();
279 ret = ImageList_BeginDrag(himl, -1, 0, 0);
280 drag = ImageList_GetDragImage(NULL, NULL);
281 ok(ret && drag, "ImageList drag was created\n");
282 ImageList_EndDrag();
283 ImageList_Destroy(himl);
284 }
285
286 static void test_hotspot(void)
287 {
288 struct hotspot {
289 int dx;
290 int dy;
291 };
292
293 #define SIZEX1 47
294 #define SIZEY1 31
295 #define SIZEX2 11
296 #define SIZEY2 17
297 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
298 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
299 { 10, 7 },
300 { SIZEX1, SIZEY1 },
301 { -9, -8 },
302 { -7, 35 }
303 };
304 int i, j, ret;
305 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
306 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
307 HWND hwnd = create_a_window();
308
309
310 for (i = 0; i < HOTSPOTS_MAX; i++) {
311 for (j = 0; j < HOTSPOTS_MAX; j++) {
312 int dx1 = hotspots[i].dx;
313 int dy1 = hotspots[i].dy;
314 int dx2 = hotspots[j].dx;
315 int dy2 = hotspots[j].dy;
316 int correctx, correcty, newx, newy;
317 char loc[256];
318 HIMAGELIST himlNew;
319 POINT ppt;
320
321 ret = ImageList_BeginDrag(himl1, 0, dx1, dy1);
322 ok(ret != 0, "BeginDrag failed for { %d, %d }\n", dx1, dy1);
323 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
324 show_image(hwnd, himl1, 0, max(SIZEX1, SIZEY1), loc, TRUE);
325
326 /* check merging the dragged image with a second image */
327 ret = ImageList_SetDragCursorImage(himl2, 0, dx2, dy2);
328 ok(ret != 0, "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
329 dx1, dy1, dx2, dy2);
330 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
331 show_image(hwnd, himl2, 0, max(SIZEX2, SIZEY2), loc, TRUE);
332
333 /* check new hotspot, it should be the same like the old one */
334 himlNew = ImageList_GetDragImage(NULL, &ppt);
335 ok(ppt.x == dx1 && ppt.y == dy1,
336 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
337 dx1, dy1, ppt.x, ppt.y);
338 /* check size of new dragged image */
339 ImageList_GetIconSize(himlNew, &newx, &newy);
340 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
341 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
342 ok(newx == correctx && newy == correcty,
343 "Expected drag image size [%d,%d] got [%d,%d]\n",
344 correctx, correcty, newx, newy);
345 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
346 show_image(hwnd, himlNew, 0, max(correctx, correcty), loc, TRUE);
347 ImageList_EndDrag();
348 }
349 }
350 #undef SIZEX1
351 #undef SIZEY1
352 #undef SIZEX2
353 #undef SIZEY2
354 #undef HOTSPOTS_MAX
355 ImageList_Destroy(himl2);
356 ImageList_Destroy(himl1);
357 DestroyWindow(hwnd);
358 }
359
360 static void test_add_remove(void)
361 {
362 HIMAGELIST himl ;
363
364 HICON hicon1 ;
365 HICON hicon2 ;
366 HICON hicon3 ;
367
368 /* create an imagelist to play with */
369 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
370 ok(himl!=0,"failed to create imagelist\n");
371
372 /* load the icons to add to the image list */
373 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
374 ok(hicon1 != 0, "no hicon1\n");
375 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
376 ok(hicon2 != 0, "no hicon2\n");
377 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
378 ok(hicon3 != 0, "no hicon3\n");
379
380 /* remove when nothing exists */
381 ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
382 /* removing everything from an empty imagelist should succeed */
383 ok(ImageList_RemoveAll(himl),"removed nonexistent icon\n");
384
385 /* add three */
386 ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
387 ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
388 ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
389
390 /* remove an index out of range */
391 ok(!ImageList_Remove(himl,4711),"removed nonexistent icon\n");
392
393 /* remove three */
394 ok(ImageList_Remove(himl,0),"can't remove 0\n");
395 ok(ImageList_Remove(himl,0),"can't remove 0\n");
396 ok(ImageList_Remove(himl,0),"can't remove 0\n");
397
398 /* remove one extra */
399 ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
400
401 /* destroy it */
402 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
403
404 ok(-1==ImageList_AddIcon((HIMAGELIST)0xdeadbeef, hicon1),"don't crash on bad handle\n");
405
406 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
407 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
408 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
409 }
410
411 static void test_imagecount(void)
412 {
413 HIMAGELIST himl;
414
415 ok(0==ImageList_GetImageCount((HIMAGELIST)0xdeadbeef),"don't crash on bad handle\n");
416
417 if (!pImageList_SetImageCount)
418 {
419 win_skip("ImageList_SetImageCount not available\n");
420 return;
421 }
422
423 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
424 ok(himl!=0,"failed to create imagelist\n");
425
426 ok(pImageList_SetImageCount(himl, 3), "couldn't increase image count\n");
427 ok(ImageList_GetImageCount(himl) == 3, "invalid image count after increase\n");
428 ok(pImageList_SetImageCount(himl, 1), "couldn't decrease image count\n");
429 ok(ImageList_GetImageCount(himl) == 1, "invalid image count after decrease to 1\n");
430 ok(pImageList_SetImageCount(himl, 0), "couldn't decrease image count\n");
431 ok(ImageList_GetImageCount(himl) == 0, "invalid image count after decrease to 0\n");
432
433 ok(ImageList_Destroy(himl), "destroy imagelist failed\n");
434 }
435
436 static void test_DrawIndirect(void)
437 {
438 HIMAGELIST himl;
439
440 HBITMAP hbm1;
441 HBITMAP hbm2;
442 HBITMAP hbm3;
443
444 IMAGELISTDRAWPARAMS imldp;
445 HDC hdc;
446 HWND hwndfortest;
447
448 if (!pImageList_DrawIndirect)
449 {
450 win_skip("ImageList_DrawIndirect not available, skipping test\n");
451 return;
452 }
453
454 hwndfortest = create_a_window();
455 hdc = GetDC(hwndfortest);
456 ok(hdc!=NULL, "couldn't get DC\n");
457
458 /* create an imagelist to play with */
459 himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
460 ok(himl!=0,"failed to create imagelist\n");
461
462 /* load the icons to add to the image list */
463 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
464 ok(hbm1 != 0, "no bitmap 1\n");
465 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
466 ok(hbm2 != 0, "no bitmap 2\n");
467 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
468 ok(hbm3 != 0, "no bitmap 3\n");
469
470 /* add three */
471 ok(0==ImageList_Add(himl, hbm1, 0),"failed to add bitmap 1\n");
472 ok(1==ImageList_Add(himl, hbm2, 0),"failed to add bitmap 2\n");
473
474 if (pImageList_SetImageCount)
475 {
476 ok(pImageList_SetImageCount(himl,3),"Setimage count failed\n");
477 /*ok(2==ImageList_Add(himl, hbm3, NULL),"failed to add bitmap 3\n"); */
478 ok(ImageList_Replace(himl, 2, hbm3, 0),"failed to replace bitmap 3\n");
479 }
480
481 memset(&imldp, 0, sizeof (imldp));
482 ok(!pImageList_DrawIndirect(&imldp), "zero data succeeded!\n");
483 imldp.cbSize = IMAGELISTDRAWPARAMS_V3_SIZE;
484 ok(!pImageList_DrawIndirect(&imldp), "zero hdc succeeded!\n");
485 imldp.hdcDst = hdc;
486 ok(!pImageList_DrawIndirect(&imldp),"zero himl succeeded!\n");
487 imldp.himl = (HIMAGELIST)0xdeadbeef;
488 ok(!pImageList_DrawIndirect(&imldp),"bad himl succeeded!\n");
489 imldp.himl = himl;
490
491 force_redraw(hwndfortest);
492
493 imldp.fStyle = SRCCOPY;
494 imldp.rgbBk = CLR_DEFAULT;
495 imldp.rgbFg = CLR_DEFAULT;
496 imldp.y = 100;
497 imldp.x = 100;
498 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
499 imldp.i ++;
500 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
501 imldp.i ++;
502 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
503 imldp.i ++;
504 ok(!pImageList_DrawIndirect(&imldp),"should fail\n");
505
506 /* remove three */
507 ok(ImageList_Remove(himl, 0), "removing 1st bitmap\n");
508 ok(ImageList_Remove(himl, 0), "removing 2nd bitmap\n");
509 ok(ImageList_Remove(himl, 0), "removing 3rd bitmap\n");
510
511 /* destroy it */
512 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
513
514 /* bitmaps should not be deleted by the imagelist */
515 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
516 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
517 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
518
519 ReleaseDC(hwndfortest, hdc);
520 DestroyWindow(hwndfortest);
521 }
522
523 static int get_color_format(HBITMAP bmp)
524 {
525 BITMAPINFO bmi;
526 HDC hdc = CreateCompatibleDC(0);
527 HBITMAP hOldBmp = SelectObject(hdc, bmp);
528 int ret;
529
530 memset(&bmi, 0, sizeof(bmi));
531 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
532 ret = GetDIBits(hdc, bmp, 0, 0, 0, &bmi, DIB_RGB_COLORS);
533 ok(ret, "GetDIBits failed\n");
534
535 SelectObject(hdc, hOldBmp);
536 DeleteDC(hdc);
537 return bmi.bmiHeader.biBitCount;
538 }
539
540 static void test_merge_colors(void)
541 {
542 HIMAGELIST himl[8], hmerge;
543 int sizes[] = { ILC_COLOR, ILC_COLOR | ILC_MASK, ILC_COLOR4, ILC_COLOR8, ILC_COLOR16, ILC_COLOR24, ILC_COLOR32, ILC_COLORDDB };
544 HICON hicon1;
545 IMAGEINFO info;
546 int bpp, i, j;
547
548 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
549 ok(hicon1 != NULL, "failed to create hicon1\n");
550
551 for (i = 0; i < 8; i++)
552 {
553 himl[i] = ImageList_Create(32, 32, sizes[i], 0, 3);
554 ok(himl[i] != NULL, "failed to create himl[%d]\n", i);
555 ok(0 == ImageList_AddIcon(himl[i], hicon1), "add icon1 to himl[%d] failed\n", i);
556 if (i == 0 || i == 1 || i == 7)
557 {
558 ImageList_GetImageInfo(himl[i], 0, &info);
559 sizes[i] = get_color_format(info.hbmImage);
560 }
561 }
562 DestroyIcon(hicon1);
563 for (i = 0; i < 8; i++)
564 for (j = 0; j < 8; j++)
565 {
566 hmerge = ImageList_Merge(himl[i], 0, himl[j], 0, 0, 0);
567 ok(hmerge != NULL, "merge himl[%d], himl[%d] failed\n", i, j);
568
569 ImageList_GetImageInfo(hmerge, 0, &info);
570 bpp = get_color_format(info.hbmImage);
571 /* ILC_COLOR[X] is defined as [X] */
572 if (i == 4 && j == 7)
573 ok(bpp == 16, /* merging ILC_COLOR16 with ILC_COLORDDB seems to be a special case */
574 "wrong biBitCount %d when merging lists %d (%d) and %d (%d)\n", bpp, i, sizes[i], j, sizes[j]);
575 else
576 ok(bpp == (i > j ? sizes[i] : sizes[j]),
577 "wrong biBitCount %d when merging lists %d (%d) and %d (%d)\n", bpp, i, sizes[i], j, sizes[j]);
578 ok(info.hbmMask != 0, "Imagelist merged from %d and %d had no mask\n", i, j);
579
580 if (hmerge) ImageList_Destroy(hmerge);
581 }
582
583 for (i = 0; i < 8; i++)
584 ImageList_Destroy(himl[i]);
585 }
586
587 static void test_merge(void)
588 {
589 HIMAGELIST himl1, himl2, hmerge;
590 HICON hicon1;
591 HWND hwnd = create_a_window();
592
593 himl1 = ImageList_Create(32,32,0,0,3);
594 ok(himl1 != NULL,"failed to create himl1\n");
595
596 himl2 = ImageList_Create(32,32,0,0,3);
597 ok(himl2 != NULL,"failed to create himl2\n");
598
599 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
600 ok(hicon1 != NULL, "failed to create hicon1\n");
601
602 if (!himl1 || !himl2 || !hicon1)
603 return;
604
605 ok(0==ImageList_AddIcon(himl2, hicon1),"add icon1 to himl2 failed\n");
606 check_bits(hwnd, himl2, 0, 32, icon_bits, "add icon1 to himl2");
607
608 /* If himl1 has no images, merge still succeeds */
609 hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
610 ok(hmerge != NULL, "merge himl1,-1 failed\n");
611 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,-1");
612 if (hmerge) ImageList_Destroy(hmerge);
613
614 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
615 ok(hmerge != NULL,"merge himl1,0 failed\n");
616 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,0");
617 if (hmerge) ImageList_Destroy(hmerge);
618
619 /* Same happens if himl2 is empty */
620 ImageList_Destroy(himl2);
621 himl2 = ImageList_Create(32,32,0,0,3);
622 ok(himl2 != NULL,"failed to recreate himl2\n");
623 if (!himl2)
624 return;
625
626 hmerge = ImageList_Merge(himl1, -1, himl2, -1, 0, 0);
627 ok(hmerge != NULL, "merge himl2,-1 failed\n");
628 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,-1");
629 if (hmerge) ImageList_Destroy(hmerge);
630
631 hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
632 ok(hmerge != NULL, "merge himl2,0 failed\n");
633 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,0");
634 if (hmerge) ImageList_Destroy(hmerge);
635
636 /* Now try merging an image with itself */
637 ok(0==ImageList_AddIcon(himl2, hicon1),"re-add icon1 to himl2 failed\n");
638
639 hmerge = ImageList_Merge(himl2, 0, himl2, 0, 0, 0);
640 ok(hmerge != NULL, "merge himl2 with itself failed\n");
641 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2 with itself");
642 if (hmerge) ImageList_Destroy(hmerge);
643
644 /* Try merging 2 different image lists */
645 ok(0==ImageList_AddIcon(himl1, hicon1),"add icon1 to himl1 failed\n");
646
647 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
648 ok(hmerge != NULL, "merge himl1 with himl2 failed\n");
649 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2");
650 if (hmerge) ImageList_Destroy(hmerge);
651
652 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 8, 16);
653 ok(hmerge != NULL, "merge himl1 with himl2 8,16 failed\n");
654 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2, 8,16");
655 if (hmerge) ImageList_Destroy(hmerge);
656
657 ImageList_Destroy(himl1);
658 ImageList_Destroy(himl2);
659 DestroyIcon(hicon1);
660 DestroyWindow(hwnd);
661 }
662
663 /*********************** imagelist storage test ***************************/
664
665 #define BMP_CX 48
666
667 struct memstream
668 {
669 IStream IStream_iface;
670 IStream *stream;
671 };
672
673 static struct memstream *impl_from_IStream(IStream *iface)
674 {
675 return CONTAINING_RECORD(iface, struct memstream, IStream_iface);
676 }
677
678 static HRESULT STDMETHODCALLTYPE Test_Stream_QueryInterface(IStream *iface, REFIID riid,
679 void **ppvObject)
680 {
681 ok(0, "unexpected call\n");
682 return E_NOTIMPL;
683 }
684
685 static ULONG STDMETHODCALLTYPE Test_Stream_AddRef(IStream *iface)
686 {
687 ok(0, "unexpected call\n");
688 return 2;
689 }
690
691 static ULONG STDMETHODCALLTYPE Test_Stream_Release(IStream *iface)
692 {
693 ok(0, "unexpected call\n");
694 return 1;
695 }
696
697 static HRESULT STDMETHODCALLTYPE Test_Stream_Read(IStream *iface, void *pv, ULONG cb,
698 ULONG *pcbRead)
699 {
700 struct memstream *stream = impl_from_IStream(iface);
701 return IStream_Read(stream->stream, pv, cb, pcbRead);
702 }
703
704 static HRESULT STDMETHODCALLTYPE Test_Stream_Write(IStream *iface, const void *pv, ULONG cb,
705 ULONG *pcbWritten)
706 {
707 struct memstream *stream = impl_from_IStream(iface);
708 return IStream_Write(stream->stream, pv, cb, pcbWritten);
709 }
710
711 static HRESULT STDMETHODCALLTYPE Test_Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove,
712 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
713 {
714 ok(0, "unexpected call\n");
715 return E_NOTIMPL;
716 }
717
718 static HRESULT STDMETHODCALLTYPE Test_Stream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
719 {
720 ok(0, "unexpected call\n");
721 return E_NOTIMPL;
722 }
723
724 static HRESULT STDMETHODCALLTYPE Test_Stream_CopyTo(IStream *iface, IStream *pstm,
725 ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead,
726 ULARGE_INTEGER *pcbWritten)
727 {
728 ok(0, "unexpected call\n");
729 return E_NOTIMPL;
730 }
731
732 static HRESULT STDMETHODCALLTYPE Test_Stream_Commit(IStream *iface, DWORD grfCommitFlags)
733 {
734 ok(0, "unexpected call\n");
735 return E_NOTIMPL;
736 }
737
738 static HRESULT STDMETHODCALLTYPE Test_Stream_Revert(IStream *iface)
739 {
740 ok(0, "unexpected call\n");
741 return E_NOTIMPL;
742 }
743
744 static HRESULT STDMETHODCALLTYPE Test_Stream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset,
745 ULARGE_INTEGER cb, DWORD dwLockType)
746 {
747 ok(0, "unexpected call\n");
748 return E_NOTIMPL;
749 }
750
751 static HRESULT STDMETHODCALLTYPE Test_Stream_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset,
752 ULARGE_INTEGER cb, DWORD dwLockType)
753 {
754 ok(0, "unexpected call\n");
755 return E_NOTIMPL;
756 }
757
758 static HRESULT STDMETHODCALLTYPE Test_Stream_Stat(IStream *iface, STATSTG *pstatstg,
759 DWORD grfStatFlag)
760 {
761 ok(0, "unexpected call\n");
762 return E_NOTIMPL;
763 }
764
765 static HRESULT STDMETHODCALLTYPE Test_Stream_Clone(IStream *iface, IStream **ppstm)
766 {
767 ok(0, "unexpected call\n");
768 return E_NOTIMPL;
769 }
770
771 static const IStreamVtbl Test_Stream_Vtbl =
772 {
773 Test_Stream_QueryInterface,
774 Test_Stream_AddRef,
775 Test_Stream_Release,
776 Test_Stream_Read,
777 Test_Stream_Write,
778 Test_Stream_Seek,
779 Test_Stream_SetSize,
780 Test_Stream_CopyTo,
781 Test_Stream_Commit,
782 Test_Stream_Revert,
783 Test_Stream_LockRegion,
784 Test_Stream_UnlockRegion,
785 Test_Stream_Stat,
786 Test_Stream_Clone
787 };
788
789 static void init_memstream(struct memstream *stream)
790 {
791 stream->IStream_iface.lpVtbl = &Test_Stream_Vtbl;
792 CreateStreamOnHGlobal(NULL, TRUE, &stream->stream);
793 }
794
795 static void cleanup_memstream(struct memstream *stream)
796 {
797 IStream_Release(stream->stream);
798 }
799
800
801 static INT DIB_GetWidthBytes( int width, int bpp )
802 {
803 return ((width * bpp + 31) / 8) & ~3;
804 }
805
806 static ULONG check_bitmap_data(const char *bm_data, ULONG bm_data_size,
807 INT width, INT height, INT bpp,
808 const char *comment)
809 {
810 const BITMAPFILEHEADER *bmfh = (const BITMAPFILEHEADER *)bm_data;
811 const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)(bm_data + sizeof(*bmfh));
812 ULONG hdr_size, image_size;
813
814 hdr_size = sizeof(*bmfh) + sizeof(*bmih);
815 if (bmih->biBitCount <= 8) hdr_size += (1 << bpp) * sizeof(RGBQUAD);
816
817 ok(bmfh->bfType == (('M' << 8) | 'B'), "wrong bfType 0x%02x\n", bmfh->bfType);
818 ok(bmfh->bfSize == hdr_size, "wrong bfSize 0x%02x\n", bmfh->bfSize);
819 ok(bmfh->bfReserved1 == 0, "wrong bfReserved1 0x%02x\n", bmfh->bfReserved1);
820 ok(bmfh->bfReserved2 == 0, "wrong bfReserved2 0x%02x\n", bmfh->bfReserved2);
821 ok(bmfh->bfOffBits == hdr_size, "wrong bfOffBits 0x%02x\n", bmfh->bfOffBits);
822
823 ok(bmih->biSize == sizeof(*bmih), "wrong biSize %d\n", bmih->biSize);
824 ok(bmih->biWidth == width, "wrong biWidth %d (expected %d)\n", bmih->biWidth, width);
825 ok(bmih->biHeight == height, "wrong biHeight %d (expected %d)\n", bmih->biHeight, height);
826 ok(bmih->biPlanes == 1, "wrong biPlanes %d\n", bmih->biPlanes);
827 ok(bmih->biBitCount == bpp, "wrong biBitCount %d\n", bmih->biBitCount);
828
829 image_size = DIB_GetWidthBytes(bmih->biWidth, bmih->biBitCount) * bmih->biHeight;
830 ok(bmih->biSizeImage == image_size, "wrong biSizeImage %u\n", bmih->biSizeImage);
831
832 if (0)
833 {
834 char fname[256];
835 FILE *f;
836 sprintf(fname, "bmp_%s.bmp", comment);
837 f = fopen(fname, "wb");
838 fwrite(bm_data, 1, bm_data_size, f);
839 fclose(f);
840 }
841
842 return hdr_size + image_size;
843 }
844
845 static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max, INT grow, INT flags)
846 {
847 const ILHEAD *ilh = (const ILHEAD *)ilh_data;
848
849 ok(ilh->usMagic == IMAGELIST_MAGIC, "wrong usMagic %4x (expected %02x)\n", ilh->usMagic, IMAGELIST_MAGIC);
850 ok(ilh->usVersion == 0x101, "wrong usVersion %x (expected 0x101)\n", ilh->usVersion);
851 ok(ilh->cCurImage == cur, "wrong cCurImage %d (expected %d)\n", ilh->cCurImage, cur);
852 ok(ilh->cMaxImage == max, "wrong cMaxImage %d (expected %d)\n", ilh->cMaxImage, max);
853 ok(ilh->cGrow == grow, "wrong cGrow %d (expected %d)\n", ilh->cGrow, grow);
854 ok(ilh->cx == cx, "wrong cx %d (expected %d)\n", ilh->cx, cx);
855 ok(ilh->cy == cy, "wrong cy %d (expected %d)\n", ilh->cy, cy);
856 ok(ilh->bkcolor == CLR_NONE, "wrong bkcolor %x\n", ilh->bkcolor);
857 ok(ilh->flags == flags || broken(!(ilh->flags & 0xfe) && (flags & 0xfe) == ILC_COLOR4), /* <= w2k */
858 "wrong flags %04x\n", ilh->flags);
859 ok(ilh->ovls[0] == -1, "wrong ovls[0] %04x\n", ilh->ovls[0]);
860 ok(ilh->ovls[1] == -1, "wrong ovls[1] %04x\n", ilh->ovls[1]);
861 ok(ilh->ovls[2] == -1, "wrong ovls[2] %04x\n", ilh->ovls[2]);
862 ok(ilh->ovls[3] == -1, "wrong ovls[3] %04x\n", ilh->ovls[3]);
863 }
864
865 static HBITMAP create_bitmap(INT cx, INT cy, COLORREF color, const char *comment)
866 {
867 HDC hdc;
868 BITMAPINFO bmi;
869 HBITMAP hbmp, hbmp_old;
870 HBRUSH hbrush;
871 RECT rc = { 0, 0, cx, cy };
872
873 hdc = CreateCompatibleDC(0);
874
875 memset(&bmi, 0, sizeof(bmi));
876 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
877 bmi.bmiHeader.biHeight = cx;
878 bmi.bmiHeader.biWidth = cy;
879 bmi.bmiHeader.biBitCount = 24;
880 bmi.bmiHeader.biPlanes = 1;
881 bmi.bmiHeader.biCompression = BI_RGB;
882 hbmp = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
883
884 hbmp_old = SelectObject(hdc, hbmp);
885
886 hbrush = CreateSolidBrush(color);
887 FillRect(hdc, &rc, hbrush);
888 DeleteObject(hbrush);
889
890 DrawTextA(hdc, comment, -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
891
892 SelectObject(hdc, hbmp_old);
893 DeleteDC(hdc);
894
895 return hbmp;
896 }
897
898 static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max, INT grow,
899 INT width, INT height, INT flags, const char *comment)
900 {
901 INT ret, cxx, cyy, size;
902 struct memstream stream;
903 LARGE_INTEGER mv;
904 HIMAGELIST himl2;
905 HGLOBAL hglobal;
906 STATSTG stat;
907 char *data;
908 HRESULT hr;
909
910 ret = ImageList_GetImageCount(himl);
911 ok(ret == cur, "%s: expected image count %d got %d\n", comment, cur, ret);
912
913 ret = ImageList_GetIconSize(himl, &cxx, &cyy);
914 ok(ret, "ImageList_GetIconSize failed\n");
915 ok(cxx == cx, "%s: wrong cx %d (expected %d)\n", comment, cxx, cx);
916 ok(cyy == cy, "%s: wrong cy %d (expected %d)\n", comment, cyy, cy);
917
918 init_memstream(&stream);
919 ret = ImageList_Write(himl, &stream.IStream_iface);
920 ok(ret, "%s: ImageList_Write failed\n", comment);
921
922 hr = GetHGlobalFromStream(stream.stream, &hglobal);
923 ok(hr == S_OK, "%s: Failed to get hglobal, %#x\n", comment, hr);
924
925 IStream_Stat(stream.stream, &stat, STATFLAG_NONAME);
926
927 data = GlobalLock(hglobal);
928
929 ok(data != 0, "%s: ImageList_Write didn't write any data\n", comment);
930 ok(stat.cbSize.LowPart > sizeof(ILHEAD), "%s: ImageList_Write wrote not enough data\n", comment);
931
932 check_ilhead_data(data, cx, cy, cur, max, grow, flags);
933 size = check_bitmap_data(data + sizeof(ILHEAD), stat.cbSize.LowPart - sizeof(ILHEAD),
934 width, height, flags & 0xfe, comment);
935 if (size < stat.cbSize.LowPart - sizeof(ILHEAD)) /* mask is present */
936 {
937 ok( flags & ILC_MASK, "%s: extra data %u/%u but mask not expected\n", comment, stat.cbSize.LowPart, size );
938 check_bitmap_data(data + sizeof(ILHEAD) + size, stat.cbSize.LowPart - sizeof(ILHEAD) - size,
939 width, height, 1, comment);
940 }
941
942 /* rewind and reconstruct from stream */
943 mv.QuadPart = 0;
944 IStream_Seek(stream.stream, mv, STREAM_SEEK_SET, NULL);
945 himl2 = ImageList_Read(&stream.IStream_iface);
946 ok(himl2 != NULL, "%s: Failed to deserialize imagelist\n", comment);
947 ImageList_Destroy(himl2);
948
949 GlobalUnlock(hglobal);
950 cleanup_memstream(&stream);
951 }
952
953 static void image_list_init(HIMAGELIST himl)
954 {
955 HBITMAP hbm;
956 char comment[16];
957 INT n = 1;
958 DWORD i;
959 static const struct test_data
960 {
961 BYTE grey;
962 INT cx, cy, cur, max, grow, width, height, bpp;
963 const char *comment;
964 } td[] =
965 {
966 { 255, BMP_CX, BMP_CX, 1, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "total 1" },
967 { 170, BMP_CX, BMP_CX, 2, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 2" },
968 { 85, BMP_CX, BMP_CX, 3, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 3" },
969 { 0, BMP_CX, BMP_CX, 4, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 4" },
970 { 0, BMP_CX, BMP_CX, 5, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 5" },
971 { 85, BMP_CX, BMP_CX, 6, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 6" },
972 { 170, BMP_CX, BMP_CX, 7, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 7" },
973 { 255, BMP_CX, BMP_CX, 8, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 8" },
974 { 255, BMP_CX, BMP_CX, 9, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 9" },
975 { 170, BMP_CX, BMP_CX, 10, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 10" },
976 { 85, BMP_CX, BMP_CX, 11, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 11" },
977 { 0, BMP_CX, BMP_CX, 12, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 12" },
978 { 0, BMP_CX, BMP_CX, 13, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 13" },
979 { 85, BMP_CX, BMP_CX, 14, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 14" },
980 { 170, BMP_CX, BMP_CX, 15, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 15" },
981 { 255, BMP_CX, BMP_CX, 16, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 16" },
982 { 255, BMP_CX, BMP_CX, 17, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 17" },
983 { 170, BMP_CX, BMP_CX, 18, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 18" },
984 { 85, BMP_CX, BMP_CX, 19, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 19" },
985 { 0, BMP_CX, BMP_CX, 20, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 20" },
986 { 0, BMP_CX, BMP_CX, 21, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 21" },
987 { 85, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 22" },
988 { 170, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 23" },
989 { 255, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 24" }
990 };
991
992 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "total 0");
993
994 #define add_bitmap(grey) \
995 sprintf(comment, "%d", n++); \
996 hbm = create_bitmap(BMP_CX, BMP_CX, RGB((grey),(grey),(grey)), comment); \
997 ImageList_Add(himl, hbm, NULL); \
998 DeleteObject(hbm);
999
1000 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
1001 {
1002 add_bitmap(td[i].grey);
1003 check_iml_data(himl, td[i].cx, td[i].cy, td[i].cur, td[i].max, td[i].grow,
1004 td[i].width, td[i].height, td[i].bpp, td[i].comment);
1005 }
1006 #undef add_bitmap
1007 }
1008
1009 static void test_imagelist_storage(void)
1010 {
1011 HIMAGELIST himl;
1012 HBITMAP hbm;
1013 HICON icon;
1014 INT ret;
1015
1016 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 1, 1);
1017 ok(himl != 0, "ImageList_Create failed\n");
1018
1019 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "empty");
1020
1021 image_list_init(himl);
1022 check_iml_data(himl, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "orig");
1023
1024 ret = ImageList_Remove(himl, 4);
1025 ok(ret, "ImageList_Remove failed\n");
1026 check_iml_data(himl, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "1");
1027
1028 ret = ImageList_Remove(himl, 5);
1029 ok(ret, "ImageList_Remove failed\n");
1030 check_iml_data(himl, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "2");
1031
1032 ret = ImageList_Remove(himl, 6);
1033 ok(ret, "ImageList_Remove failed\n");
1034 check_iml_data(himl, BMP_CX, BMP_CX, 21, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "3");
1035
1036 ret = ImageList_Remove(himl, 7);
1037 ok(ret, "ImageList_Remove failed\n");
1038 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "4");
1039
1040 ret = ImageList_Remove(himl, -2);
1041 ok(!ret, "ImageList_Remove(-2) should fail\n");
1042 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "5");
1043
1044 ret = ImageList_Remove(himl, 20);
1045 ok(!ret, "ImageList_Remove(20) should fail\n");
1046 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "6");
1047
1048 ret = ImageList_Remove(himl, -1);
1049 ok(ret, "ImageList_Remove(-1) failed\n");
1050 check_iml_data(himl, BMP_CX, BMP_CX, 0, 4, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "7");
1051
1052 ret = ImageList_Destroy(himl);
1053 ok(ret, "ImageList_Destroy failed\n");
1054
1055 /* test ImageList_Create storage allocation */
1056
1057 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 0, 32);
1058 ok(himl != 0, "ImageList_Create failed\n");
1059 check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 32, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "init 0 grow 32");
1060 hbm = create_bitmap(BMP_CX * 9, BMP_CX, 0, "9");
1061 ret = ImageList_Add(himl, hbm, NULL);
1062 ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
1063 check_iml_data(himl, BMP_CX, BMP_CX, 1, 34, 32, BMP_CX * 4, BMP_CX * 9, ILC_COLOR24, "add 1 x 9");
1064 DeleteObject(hbm);
1065 ret = ImageList_Destroy(himl);
1066 ok(ret, "ImageList_Destroy failed\n");
1067
1068 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 4);
1069 ok(himl != 0, "ImageList_Create failed\n");
1070 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24, "init 4 grow 4");
1071 hbm = create_bitmap(BMP_CX, BMP_CX * 9, 0, "9");
1072 ret = ImageList_Add(himl, hbm, NULL);
1073 ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
1074 check_iml_data(himl, BMP_CX, BMP_CX, 9, 15, 4, BMP_CX * 4, BMP_CX * 4, ILC_COLOR24, "add 9 x 1");
1075 ret = ImageList_Add(himl, hbm, NULL);
1076 ok(ret == 9, "ImageList_Add returned %d, expected 9\n", ret);
1077 check_iml_data(himl, BMP_CX, BMP_CX, 18, 25, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "add 9 x 1");
1078 DeleteObject(hbm);
1079 ret = ImageList_Destroy(himl);
1080 ok(ret, "ImageList_Destroy failed\n");
1081
1082 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 207, 209);
1083 ok(himl != 0, "ImageList_Create failed\n");
1084 check_iml_data(himl, BMP_CX, BMP_CX, 0, 208, 212, BMP_CX * 4, BMP_CX * 52, ILC_COLOR24, "init 207 grow 209");
1085 ret = ImageList_Destroy(himl);
1086 ok(ret, "ImageList_Destroy failed\n");
1087
1088 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 209, 207);
1089 ok(himl != 0, "ImageList_Create failed\n");
1090 check_iml_data(himl, BMP_CX, BMP_CX, 0, 210, 208, BMP_CX * 4, BMP_CX * 53, ILC_COLOR24, "init 209 grow 207");
1091 ret = ImageList_Destroy(himl);
1092 ok(ret, "ImageList_Destroy failed\n");
1093
1094 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 14, 4);
1095 ok(himl != 0, "ImageList_Create failed\n");
1096 check_iml_data(himl, BMP_CX, BMP_CX, 0, 15, 4, BMP_CX * 4, BMP_CX * 4, ILC_COLOR24, "init 14 grow 4");
1097 ret = ImageList_Destroy(himl);
1098 ok(ret, "ImageList_Destroy failed\n");
1099
1100 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 5, 9);
1101 ok(himl != 0, "ImageList_Create failed\n");
1102 check_iml_data(himl, BMP_CX, BMP_CX, 0, 6, 12, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24, "init 5 grow 9");
1103 ret = ImageList_Destroy(himl);
1104 ok(ret, "ImageList_Destroy failed\n");
1105
1106 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 9, 5);
1107 ok(himl != 0, "ImageList_Create failed\n");
1108 check_iml_data(himl, BMP_CX, BMP_CX, 0, 10, 8, BMP_CX * 4, BMP_CX * 3, ILC_COLOR24, "init 9 grow 5");
1109 ret = ImageList_Destroy(himl);
1110 ok(ret, "ImageList_Destroy failed\n");
1111
1112 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 2, 4);
1113 ok(himl != 0, "ImageList_Create failed\n");
1114 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "init 2 grow 4");
1115 ret = ImageList_Destroy(himl);
1116 ok(ret, "ImageList_Destroy failed\n");
1117
1118 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 2);
1119 ok(himl != 0, "ImageList_Create failed\n");
1120 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24, "init 4 grow 2");
1121 ret = ImageList_Destroy(himl);
1122 ok(ret, "ImageList_Destroy failed\n");
1123
1124 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR8, 4, 2);
1125 ok(himl != 0, "ImageList_Create failed\n");
1126 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR8, "bpp 8");
1127 ret = ImageList_Destroy(himl);
1128 ok(ret, "ImageList_Destroy failed\n");
1129
1130 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4, 4, 2);
1131 ok(himl != 0, "ImageList_Create failed\n");
1132 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4, "bpp 4");
1133 ret = ImageList_Destroy(himl);
1134 ok(ret, "ImageList_Destroy failed\n");
1135
1136 himl = ImageList_Create(BMP_CX, BMP_CX, 0, 4, 2);
1137 ok(himl != 0, "ImageList_Create failed\n");
1138 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4, "bpp default");
1139 icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1140 ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n");
1141 ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n");
1142 DestroyIcon( icon );
1143 check_iml_data(himl, BMP_CX, BMP_CX, 2, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4, "bpp default");
1144 ret = ImageList_Destroy(himl);
1145 ok(ret, "ImageList_Destroy failed\n");
1146
1147 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24|ILC_MASK, 4, 2);
1148 ok(himl != 0, "ImageList_Create failed\n");
1149 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24|ILC_MASK,
1150 "bpp 24 + mask");
1151 icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1152 ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n");
1153 ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n");
1154 DestroyIcon( icon );
1155 check_iml_data(himl, BMP_CX, BMP_CX, 2, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24|ILC_MASK,
1156 "bpp 24 + mask");
1157 ret = ImageList_Destroy(himl);
1158 ok(ret, "ImageList_Destroy failed\n");
1159
1160 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 4, 2);
1161 ok(himl != 0, "ImageList_Create failed\n");
1162 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4|ILC_MASK,
1163 "bpp 4 + mask");
1164 icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1165 ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n");
1166 ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n");
1167 DestroyIcon( icon );
1168 check_iml_data(himl, BMP_CX, BMP_CX, 2, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4|ILC_MASK,
1169 "bpp 4 + mask");
1170 ret = ImageList_Destroy(himl);
1171 ok(ret, "ImageList_Destroy failed\n");
1172
1173 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 99);
1174 ok(himl != 0, "ImageList_Create failed\n");
1175 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1176 "init 2 grow 99");
1177 icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1178 ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n");
1179 ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n");
1180 check_iml_data(himl, BMP_CX, BMP_CX, 2, 3, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1181 "init 2 grow 99 2 icons");
1182 ok( ImageList_AddIcon(himl, icon) == 2,"failed to add icon\n");
1183 DestroyIcon( icon );
1184 check_iml_data(himl, BMP_CX, BMP_CX, 3, 104, 100, BMP_CX * 4, BMP_CX * 104/4, ILC_COLOR4|ILC_MASK,
1185 "init 2 grow 99 3 icons");
1186 ok( ImageList_Remove(himl, -1) == TRUE,"failed to remove icon\n");
1187 check_iml_data(himl, BMP_CX, BMP_CX, 0, 100, 100, BMP_CX * 4, BMP_CX * 100/4, ILC_COLOR4|ILC_MASK,
1188 "init 2 grow 99 empty");
1189 ok( ImageList_SetImageCount(himl, 22) == TRUE,"failed to set image count\n");
1190 check_iml_data(himl, BMP_CX, BMP_CX, 22, 23, 100, BMP_CX * 4, BMP_CX * 24/4, ILC_COLOR4|ILC_MASK,
1191 "init 2 grow 99 set count 22");
1192 ok( ImageList_SetImageCount(himl, 0) == TRUE,"failed to set image count\n");
1193 check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1194 "init 2 grow 99 set count 0");
1195 ok( ImageList_SetImageCount(himl, 42) == TRUE,"failed to set image count\n");
1196 check_iml_data(himl, BMP_CX, BMP_CX, 42, 43, 100, BMP_CX * 4, BMP_CX * 44/4, ILC_COLOR4|ILC_MASK,
1197 "init 2 grow 99 set count 42");
1198 ret = ImageList_Destroy(himl);
1199 ok(ret, "ImageList_Destroy failed\n");
1200
1201 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 65536+12);
1202 ok(himl != 0, "ImageList_Create failed\n");
1203 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 12, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1204 "init 2 grow 65536+12");
1205 ret = ImageList_Destroy(himl);
1206 ok(ret, "ImageList_Destroy failed\n");
1207
1208 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 65535);
1209 ok(himl != 0, "ImageList_Create failed\n");
1210 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 0, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1211 "init 2 grow 65535");
1212 ret = ImageList_Destroy(himl);
1213 ok(ret, "ImageList_Destroy failed\n");
1214
1215 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, -20);
1216 ok(himl != 0, "ImageList_Create failed\n");
1217 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1218 "init 2 grow -20");
1219 ret = ImageList_Destroy(himl);
1220 ok(ret, "ImageList_Destroy failed\n");
1221 }
1222
1223 static void test_shell_imagelist(void)
1224 {
1225 HRESULT (WINAPI *pSHGetImageList)(INT, REFIID, void**);
1226 IImageList *iml = NULL;
1227 HMODULE hShell32;
1228 HRESULT hr;
1229 int out = 0;
1230 RECT rect;
1231 int cx, cy;
1232
1233 /* Try to load function from shell32 */
1234 hShell32 = LoadLibraryA("shell32.dll");
1235 pSHGetImageList = (void*)GetProcAddress(hShell32, (LPCSTR) 727);
1236
1237 if (!pSHGetImageList)
1238 {
1239 win_skip("SHGetImageList not available, skipping test\n");
1240 FreeLibrary(hShell32);
1241 return;
1242 }
1243
1244 /* Get system image list */
1245 hr = pSHGetImageList(SHIL_SYSSMALL, &IID_IImageList, (void**)&iml);
1246 ok(SUCCEEDED(hr), "SHGetImageList failed, hr=%x\n", hr);
1247
1248 if (hr != S_OK) {
1249 FreeLibrary(hShell32);
1250 return;
1251 }
1252
1253 IImageList_GetImageCount(iml, &out);
1254 ok(out > 0, "IImageList_GetImageCount returned out <= 0\n");
1255
1256 /* Fetch the small icon size */
1257 cx = GetSystemMetrics(SM_CXSMICON);
1258 cy = GetSystemMetrics(SM_CYSMICON);
1259
1260 /* Check icon size matches */
1261 IImageList_GetImageRect(iml, 0, &rect);
1262 ok(((rect.right == cx) && (rect.bottom == cy)),
1263 "IImageList_GetImageRect returned r:%d,b:%d\n",
1264 rect.right, rect.bottom);
1265
1266 IImageList_Release(iml);
1267 FreeLibrary(hShell32);
1268 }
1269
1270 static HBITMAP create_test_bitmap(HDC hdc, int bpp, UINT32 pixel1, UINT32 pixel2)
1271 {
1272 HBITMAP hBitmap;
1273 UINT32 *buffer = NULL;
1274 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, bpp, BI_RGB,
1275 0, 0, 0, 0, 0}};
1276
1277 hBitmap = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, NULL, 0);
1278 ok(hBitmap != NULL && buffer != NULL, "CreateDIBSection failed.\n");
1279
1280 if(!hBitmap || !buffer)
1281 {
1282 DeleteObject(hBitmap);
1283 return NULL;
1284 }
1285
1286 buffer[0] = pixel1;
1287 buffer[1] = pixel2;
1288
1289 return hBitmap;
1290 }
1291
1292 static BOOL colour_match(UINT32 x, UINT32 y)
1293 {
1294 const INT32 tolerance = 8;
1295
1296 const INT32 dr = abs((INT32)(x & 0x000000FF) - (INT32)(y & 0x000000FF));
1297 const INT32 dg = abs((INT32)((x & 0x0000FF00) >> 8) - (INT32)((y & 0x0000FF00) >> 8));
1298 const INT32 db = abs((INT32)((x & 0x00FF0000) >> 16) - (INT32)((y & 0x00FF0000) >> 16));
1299
1300 return (dr <= tolerance && dg <= tolerance && db <= tolerance);
1301 }
1302
1303 static void check_ImageList_DrawIndirect(IMAGELISTDRAWPARAMS *ildp, UINT32 *bits,
1304 UINT32 expected, int line)
1305 {
1306 bits[0] = 0x00FFFFFF;
1307 pImageList_DrawIndirect(ildp);
1308 ok(colour_match(bits[0], expected),
1309 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1310 bits[0] & 0x00FFFFFF, expected, line);
1311 }
1312
1313
1314 static void check_ImageList_DrawIndirect_fStyle(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1315 UINT fStyle, UINT32 expected, int line)
1316 {
1317 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1318 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, ILS_NORMAL, 0, 0x00000000};
1319 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1320 }
1321
1322 static void check_ImageList_DrawIndirect_ILD_ROP(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1323 DWORD dwRop, UINT32 expected, int line)
1324 {
1325 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1326 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_IMAGE | ILD_ROP, dwRop, ILS_NORMAL, 0, 0x00000000};
1327 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1328 }
1329
1330 static void check_ImageList_DrawIndirect_fState(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i, UINT fStyle,
1331 UINT fState, DWORD Frame, UINT32 expected, int line)
1332 {
1333 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1334 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1335 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1336 }
1337
1338 static void check_ImageList_DrawIndirect_broken(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1339 UINT fStyle, UINT fState, DWORD Frame, UINT32 expected,
1340 UINT32 broken_expected, int line)
1341 {
1342 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1343 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1344 bits[0] = 0x00FFFFFF;
1345 pImageList_DrawIndirect(&ildp);
1346 ok(colour_match(bits[0], expected) ||
1347 broken(colour_match(bits[0], broken_expected)),
1348 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1349 bits[0] & 0x00FFFFFF, expected, line);
1350 }
1351
1352 static void test_ImageList_DrawIndirect(void)
1353 {
1354 HIMAGELIST himl = NULL;
1355 int ret;
1356 HDC hdcDst = NULL;
1357 HBITMAP hbmOld = NULL, hbmDst = NULL;
1358 HBITMAP hbmMask = NULL, hbmInverseMask = NULL;
1359 HBITMAP hbmImage = NULL, hbmAlphaImage = NULL, hbmTransparentImage = NULL;
1360 int iImage = -1, iAlphaImage = -1, iTransparentImage = -1;
1361 UINT32 *bits = 0;
1362 UINT32 maskBits = 0x00000000, inverseMaskBits = 0xFFFFFFFF;
1363 int bpp, broken_value;
1364
1365 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB,
1366 0, 0, 0, 0, 0}};
1367
1368 hdcDst = CreateCompatibleDC(0);
1369 ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
1370 if (!hdcDst)
1371 return;
1372 bpp = GetDeviceCaps(hdcDst, BITSPIXEL);
1373
1374 hbmMask = CreateBitmap(2, 1, 1, 1, &maskBits);
1375 ok(hbmMask != 0, "CreateBitmap failed\n");
1376 if(!hbmMask) goto cleanup;
1377
1378 hbmInverseMask = CreateBitmap(2, 1, 1, 1, &inverseMaskBits);
1379 ok(hbmInverseMask != 0, "CreateBitmap failed\n");
1380 if(!hbmInverseMask) goto cleanup;
1381
1382 himl = pImageList_Create(2, 1, ILC_COLOR32, 0, 1);
1383 ok(himl != 0, "ImageList_Create failed\n");
1384 if(!himl) goto cleanup;
1385
1386 /* Add a no-alpha image */
1387 hbmImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x00ABCDEF);
1388 if(!hbmImage) goto cleanup;
1389
1390 iImage = pImageList_Add(himl, hbmImage, hbmMask);
1391 ok(iImage != -1, "ImageList_Add failed\n");
1392 if(iImage == -1) goto cleanup;
1393
1394 /* Add an alpha image */
1395 hbmAlphaImage = create_test_bitmap(hdcDst, 32, 0x89ABCDEF, 0x89ABCDEF);
1396 if(!hbmAlphaImage) goto cleanup;
1397
1398 iAlphaImage = pImageList_Add(himl, hbmAlphaImage, hbmMask);
1399 ok(iAlphaImage != -1, "ImageList_Add failed\n");
1400 if(iAlphaImage == -1) goto cleanup;
1401
1402 /* Add a transparent alpha image */
1403 hbmTransparentImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x89ABCDEF);
1404 if(!hbmTransparentImage) goto cleanup;
1405
1406 iTransparentImage = pImageList_Add(himl, hbmTransparentImage, hbmMask);
1407 ok(iTransparentImage != -1, "ImageList_Add failed\n");
1408 if(iTransparentImage == -1) goto cleanup;
1409
1410 /* 32-bit Tests */
1411 bitmapInfo.bmiHeader.biBitCount = 32;
1412 hbmDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1413 ok (hbmDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1414 if (!hbmDst || !bits)
1415 goto cleanup;
1416 hbmOld = SelectObject(hdcDst, hbmDst);
1417
1418 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_NORMAL, 0x00ABCDEF, __LINE__);
1419 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_TRANSPARENT, 0x00ABCDEF, __LINE__);
1420 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x00D4D9DD, __LINE__);
1421 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1422 else broken_value = 0x00B4BDC4;
1423 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1424 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_MASK, 0x00ABCDEF, __LINE__);
1425 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_IMAGE, 0x00ABCDEF, __LINE__);
1426 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_PRESERVEALPHA, 0x00ABCDEF, __LINE__);
1427
1428 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, 0x00D3E5F7, __LINE__);
1429 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_TRANSPARENT, 0x00D3E5F7, __LINE__);
1430
1431 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1432 else broken_value = 0x009DA8B1;
1433 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1434 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1435 else broken_value = 0x008C99A3;
1436 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1437 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0x00D3E5F7, __LINE__);
1438 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0x00D3E5F7, __LINE__);
1439 todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__);
1440
1441 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__);
1442
1443 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCCOPY, 0x00ABCDEF, __LINE__);
1444 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCINVERT, 0x00543210, __LINE__);
1445
1446 /* ILD_ROP is ignored when the image has an alpha channel */
1447 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCCOPY, 0x00D3E5F7, __LINE__);
1448 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCINVERT, 0x00D3E5F7, __LINE__);
1449
1450 todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00CCCCCC, __LINE__);
1451 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00AFAFAF, 0x00F0F0F0, __LINE__);
1452
1453 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_GLOW, 0, 0x00ABCDEF, __LINE__);
1454 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SHADOW, 0, 0x00ABCDEF, __LINE__);
1455
1456 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00D5E6F7, __LINE__);
1457 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00E9F2FB, 0x00AEB7C0, __LINE__);
1458 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_NORMAL, 127, 0x00E9F2FB, 0x00D3E5F7, __LINE__);
1459
1460 cleanup:
1461
1462 if(hbmOld)
1463 SelectObject(hdcDst, hbmOld);
1464 if(hbmDst)
1465 DeleteObject(hbmDst);
1466
1467 if(hdcDst)
1468 DeleteDC(hdcDst);
1469
1470 if(hbmMask)
1471 DeleteObject(hbmMask);
1472 if(hbmInverseMask)
1473 DeleteObject(hbmInverseMask);
1474
1475 if(hbmImage)
1476 DeleteObject(hbmImage);
1477 if(hbmAlphaImage)
1478 DeleteObject(hbmAlphaImage);
1479 if(hbmTransparentImage)
1480 DeleteObject(hbmTransparentImage);
1481
1482 if(himl)
1483 {
1484 ret = ImageList_Destroy(himl);
1485 ok(ret, "ImageList_Destroy failed\n");
1486 }
1487 }
1488
1489 static void test_iimagelist(void)
1490 {
1491 IImageList *imgl, *imgl2;
1492 IImageList2 *imagelist;
1493 HIMAGELIST himl;
1494 HRESULT hr;
1495 ULONG ret;
1496
1497 if (!pHIMAGELIST_QueryInterface)
1498 {
1499 win_skip("XP imagelist functions not available\n");
1500 return;
1501 }
1502
1503 /* test reference counting on destruction */
1504 imgl = (IImageList*)createImageList(32, 32);
1505 ret = IImageList_AddRef(imgl);
1506 ok(ret == 2, "Expected 2, got %d\n", ret);
1507 ret = ImageList_Destroy((HIMAGELIST)imgl);
1508 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1509 ret = ImageList_Destroy((HIMAGELIST)imgl);
1510 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1511 ret = ImageList_Destroy((HIMAGELIST)imgl);
1512 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1513
1514 imgl = (IImageList*)createImageList(32, 32);
1515 ret = IImageList_AddRef(imgl);
1516 ok(ret == 2, "Expected 2, got %d\n", ret);
1517 ret = ImageList_Destroy((HIMAGELIST)imgl);
1518 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1519 ret = IImageList_Release(imgl);
1520 ok(ret == 0, "Expected 0, got %d\n", ret);
1521 ret = ImageList_Destroy((HIMAGELIST)imgl);
1522 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1523
1524 /* ref counting, HIMAGELIST_QueryInterface adds a reference */
1525 imgl = (IImageList*)createImageList(32, 32);
1526 hr = pHIMAGELIST_QueryInterface((HIMAGELIST)imgl, &IID_IImageList, (void**)&imgl2);
1527 ok(hr == S_OK, "got 0x%08x\n", hr);
1528 ok(imgl2 == imgl, "got different pointer\n");
1529 ret = IImageList_Release(imgl);
1530 ok(ret == 1, "got %u\n", ret);
1531 IImageList_Release(imgl);
1532
1533 if (!pImageList_CoCreateInstance)
1534 {
1535 win_skip("Vista imagelist functions not available\n");
1536 return;
1537 }
1538
1539 hr = pImageList_CoCreateInstance(&CLSID_ImageList, NULL, &IID_IImageList, (void **) &imgl);
1540 ok(SUCCEEDED(hr), "ImageList_CoCreateInstance failed, hr=%x\n", hr);
1541
1542 if (hr == S_OK)
1543 IImageList_Release(imgl);
1544
1545 himl = createImageList(32, 32);
1546
1547 if (!himl)
1548 return;
1549
1550 hr = (pHIMAGELIST_QueryInterface)(himl, &IID_IImageList, (void **) &imgl);
1551 ok(SUCCEEDED(hr), "HIMAGELIST_QueryInterface failed, hr=%x\n", hr);
1552
1553 if (hr == S_OK)
1554 IImageList_Release(imgl);
1555
1556 ImageList_Destroy(himl);
1557
1558 /* IImageList2 */
1559 hr = pImageList_CoCreateInstance(&CLSID_ImageList, NULL, &IID_IImageList2, (void**)&imagelist);
1560 if (hr != S_OK)
1561 {
1562 win_skip("IImageList2 is not supported.\n");
1563 return;
1564 }
1565 ok(hr == S_OK, "got 0x%08x\n", hr);
1566 IImageList2_Release(imagelist);
1567 }
1568
1569 static void test_hotspot_v6(void)
1570 {
1571 struct hotspot {
1572 int dx;
1573 int dy;
1574 };
1575
1576 #define SIZEX1 47
1577 #define SIZEY1 31
1578 #define SIZEX2 11
1579 #define SIZEY2 17
1580 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
1581 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
1582 { 10, 7 },
1583 { SIZEX1, SIZEY1 },
1584 { -9, -8 },
1585 { -7, 35 }
1586 };
1587 int i, j;
1588 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
1589 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
1590 IImageList *imgl1, *imgl2;
1591 HRESULT hr;
1592
1593 /* cast to IImageList */
1594 imgl1 = (IImageList *) himl1;
1595 imgl2 = (IImageList *) himl2;
1596
1597 for (i = 0; i < HOTSPOTS_MAX; i++) {
1598 for (j = 0; j < HOTSPOTS_MAX; j++) {
1599 int dx1 = hotspots[i].dx;
1600 int dy1 = hotspots[i].dy;
1601 int dx2 = hotspots[j].dx;
1602 int dy2 = hotspots[j].dy;
1603 int correctx, correcty, newx, newy;
1604 char loc[256];
1605 IImageList *imglNew;
1606 POINT ppt;
1607
1608 hr = IImageList_BeginDrag(imgl1, 0, dx1, dy1);
1609 ok(SUCCEEDED(hr), "BeginDrag failed for { %d, %d }\n", dx1, dy1);
1610 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
1611
1612 /* check merging the dragged image with a second image */
1613 hr = IImageList_SetDragCursorImage(imgl2, (IUnknown *) imgl2, 0, dx2, dy2);
1614 ok(SUCCEEDED(hr), "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
1615 dx1, dy1, dx2, dy2);
1616 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
1617
1618 /* check new hotspot, it should be the same like the old one */
1619 hr = IImageList_GetDragImage(imgl2, NULL, &ppt, &IID_IImageList, (PVOID *) &imglNew);
1620 ok(SUCCEEDED(hr), "GetDragImage failed\n");
1621 ok(ppt.x == dx1 && ppt.y == dy1,
1622 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
1623 dx1, dy1, ppt.x, ppt.y);
1624 /* check size of new dragged image */
1625 IImageList_GetIconSize(imglNew, &newx, &newy);
1626 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
1627 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
1628 ok(newx == correctx && newy == correcty,
1629 "Expected drag image size [%d,%d] got [%d,%d]\n",
1630 correctx, correcty, newx, newy);
1631 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
1632 IImageList_EndDrag(imgl2);
1633 }
1634 }
1635 #undef SIZEX1
1636 #undef SIZEY1
1637 #undef SIZEX2
1638 #undef SIZEY2
1639 #undef HOTSPOTS_MAX
1640 IImageList_Release(imgl2);
1641 IImageList_Release(imgl1);
1642 }
1643
1644 static void test_IImageList_Add_Remove(void)
1645 {
1646 IImageList *imgl;
1647 HIMAGELIST himl;
1648 HRESULT hr;
1649
1650 HICON hicon1;
1651 HICON hicon2;
1652 HICON hicon3;
1653
1654 int ret;
1655
1656 /* create an imagelist to play with */
1657 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1658 ok(himl != 0,"failed to create imagelist\n");
1659
1660 imgl = (IImageList *) himl;
1661
1662 /* load the icons to add to the image list */
1663 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1664 ok(hicon1 != 0, "no hicon1\n");
1665 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1666 ok(hicon2 != 0, "no hicon2\n");
1667 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1668 ok(hicon3 != 0, "no hicon3\n");
1669
1670 /* remove when nothing exists */
1671 hr = IImageList_Remove(imgl, 0);
1672 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1673
1674 /* removing everything from an empty imagelist should succeed */
1675 hr = IImageList_Remove(imgl, -1);
1676 ok(hr == S_OK, "removed nonexistent icon\n");
1677
1678 /* add three */
1679 ret = -1;
1680 ok( IImageList_ReplaceIcon(imgl, -1, hicon1, &ret) == S_OK && (ret == 0),"failed to add icon1\n");
1681 ret = -1;
1682 ok( IImageList_ReplaceIcon(imgl, -1, hicon2, &ret) == S_OK && (ret == 1),"failed to add icon2\n");
1683 ret = -1;
1684 ok( IImageList_ReplaceIcon(imgl, -1, hicon3, &ret) == S_OK && (ret == 2),"failed to add icon3\n");
1685
1686 /* remove an index out of range */
1687 ok( IImageList_Remove(imgl, 4711) == E_INVALIDARG, "got 0x%08x\n", hr);
1688
1689 /* remove three */
1690 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1691 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1692 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1693
1694 /* remove one extra */
1695 ok( IImageList_Remove(imgl, 0) == E_INVALIDARG, "got 0x%08x\n", hr);
1696
1697 IImageList_Release(imgl);
1698 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
1699 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
1700 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
1701 }
1702
1703 static void test_IImageList_Get_SetImageCount(void)
1704 {
1705 IImageList *imgl;
1706 HIMAGELIST himl;
1707 HRESULT hr;
1708 INT ret;
1709
1710 /* create an imagelist to play with */
1711 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1712 ok(himl != 0,"failed to create imagelist\n");
1713
1714 imgl = (IImageList *) himl;
1715
1716 /* check SetImageCount/GetImageCount */
1717 hr = IImageList_SetImageCount(imgl, 3);
1718 ok(hr == S_OK, "got 0x%08x\n", hr);
1719 ret = 0;
1720 hr = IImageList_GetImageCount(imgl, &ret);
1721 ok(hr == S_OK && ret == 3, "invalid image count after increase\n");
1722 hr = IImageList_SetImageCount(imgl, 1);
1723 ok(hr == S_OK, "got 0x%08x\n", hr);
1724 ret = 0;
1725 hr = IImageList_GetImageCount(imgl, &ret);
1726 ok(hr == S_OK && ret == 1, "invalid image count after decrease to 1\n");
1727 hr = IImageList_SetImageCount(imgl, 0);
1728 ok(hr == S_OK, "got 0x%08x\n", hr);
1729 ret = -1;
1730 hr = IImageList_GetImageCount(imgl, &ret);
1731 ok(hr == S_OK && ret == 0, "invalid image count after decrease to 0\n");
1732
1733 IImageList_Release(imgl);
1734 }
1735
1736 static void test_IImageList_Draw(void)
1737 {
1738 IImageList *imgl;
1739 HIMAGELIST himl;
1740
1741 HBITMAP hbm1;
1742 HBITMAP hbm2;
1743 HBITMAP hbm3;
1744
1745 IMAGELISTDRAWPARAMS imldp;
1746 HWND hwndfortest;
1747 HRESULT hr;
1748 HDC hdc;
1749 int ret;
1750
1751 hwndfortest = create_a_window();
1752 hdc = GetDC(hwndfortest);
1753 ok(hdc!=NULL, "couldn't get DC\n");
1754
1755 /* create an imagelist to play with */
1756 himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
1757 ok(himl!=0,"failed to create imagelist\n");
1758
1759 imgl = (IImageList *) himl;
1760
1761 /* load the icons to add to the image list */
1762 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1763 ok(hbm1 != 0, "no bitmap 1\n");
1764 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1765 ok(hbm2 != 0, "no bitmap 2\n");
1766 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1767 ok(hbm3 != 0, "no bitmap 3\n");
1768
1769 /* add three */
1770 ret = -1;
1771 ok( IImageList_Add(imgl, hbm1, 0, &ret) == S_OK && (ret == 0), "failed to add bitmap 1\n");
1772 ret = -1;
1773 ok( IImageList_Add(imgl, hbm2, 0, &ret) == S_OK && (ret == 1), "failed to add bitmap 2\n");
1774
1775 ok( IImageList_SetImageCount(imgl, 3) == S_OK, "Setimage count failed\n");
1776 ok( IImageList_Replace(imgl, 2, hbm3, 0) == S_OK, "failed to replace bitmap 3\n");
1777
1778 if (0)
1779 {
1780 /* crashes on native */
1781 IImageList_Draw(imgl, NULL);
1782 }
1783
1784 memset(&imldp, 0, sizeof (imldp));
1785 hr = IImageList_Draw(imgl, &imldp);
1786 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
1787
1788 imldp.cbSize = IMAGELISTDRAWPARAMS_V3_SIZE;
1789 imldp.hdcDst = hdc;
1790 imldp.himl = himl;
1791
1792 force_redraw(hwndfortest);
1793
1794 imldp.fStyle = SRCCOPY;
1795 imldp.rgbBk = CLR_DEFAULT;
1796 imldp.rgbFg = CLR_DEFAULT;
1797 imldp.y = 100;
1798 imldp.x = 100;
1799 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1800 imldp.i ++;
1801 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1802 imldp.i ++;
1803 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1804 imldp.i ++;
1805 ok( IImageList_Draw(imgl, &imldp) == E_INVALIDARG, "should fail\n");
1806
1807 /* remove three */
1808 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 1st bitmap\n");
1809 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 2nd bitmap\n");
1810 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 3rd bitmap\n");
1811
1812 /* destroy it */
1813 IImageList_Release(imgl);
1814
1815 /* bitmaps should not be deleted by the imagelist */
1816 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
1817 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
1818 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
1819
1820 ReleaseDC(hwndfortest, hdc);
1821 DestroyWindow(hwndfortest);
1822 }
1823
1824 static void test_IImageList_Merge(void)
1825 {
1826 HIMAGELIST himl1, himl2;
1827 IImageList *imgl1, *imgl2, *merge;
1828 HICON hicon1;
1829 HWND hwnd = create_a_window();
1830 HRESULT hr;
1831 int ret;
1832
1833 himl1 = ImageList_Create(32,32,0,0,3);
1834 ok(himl1 != NULL,"failed to create himl1\n");
1835
1836 himl2 = ImageList_Create(32,32,0,0,3);
1837 ok(himl2 != NULL,"failed to create himl2\n");
1838
1839 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1840 ok(hicon1 != NULL, "failed to create hicon1\n");
1841
1842 if (!himl1 || !himl2 || !hicon1)
1843 return;
1844
1845 /* cast to IImageList */
1846 imgl1 = (IImageList *) himl1;
1847 imgl2 = (IImageList *) himl2;
1848
1849 ret = -1;
1850 ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (ret == 0),"add icon1 to himl2 failed\n");
1851
1852 if (0)
1853 {
1854 /* null cases that crash on native */
1855 IImageList_Merge(imgl1, -1, NULL, 0, 0, 0, &IID_IImageList, (void**)&merge);
1856 IImageList_Merge(imgl1, -1, (IUnknown*) imgl2, 0, 0, 0, &IID_IImageList, NULL);
1857 }
1858
1859 /* If himl1 has no images, merge still succeeds */
1860 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1861 ok(hr == S_OK, "merge himl1,-1 failed\n");
1862 if (hr == S_OK) IImageList_Release(merge);
1863
1864 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1865 ok(hr == S_OK, "merge himl1,0 failed\n");
1866 if (hr == S_OK) IImageList_Release(merge);
1867
1868 /* Same happens if himl2 is empty */
1869 IImageList_Release(imgl2);
1870 himl2 = ImageList_Create(32,32,0,0,3);
1871 ok(himl2 != NULL,"failed to recreate himl2\n");
1872
1873 imgl2 = (IImageList *) himl2;
1874
1875 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, -1, 0, 0, &IID_IImageList, (void **) &merge);
1876 ok(hr == S_OK, "merge himl2,-1 failed\n");
1877 if (hr == S_OK) IImageList_Release(merge);
1878
1879 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1880 ok(hr == S_OK, "merge himl2,0 failed\n");
1881 if (hr == S_OK) IImageList_Release(merge);
1882
1883 /* Now try merging an image with itself */
1884 ret = -1;
1885 ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (ret == 0),"re-add icon1 to himl2 failed\n");
1886
1887 hr = IImageList_Merge(imgl2, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1888 ok(hr == S_OK, "merge himl2 with itself failed\n");
1889 if (hr == S_OK) IImageList_Release(merge);
1890
1891 /* Try merging 2 different image lists */
1892 ret = -1;
1893 ok( IImageList_ReplaceIcon(imgl1, -1, hicon1, &ret) == S_OK && (ret == 0),"add icon1 to himl1 failed\n");
1894
1895 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1896 ok(hr == S_OK, "merge himl1 with himl2 failed\n");
1897 if (hr == S_OK) IImageList_Release(merge);
1898
1899 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 8, 16, &IID_IImageList, (void **) &merge);
1900 ok(hr == S_OK, "merge himl1 with himl2 8,16 failed\n");
1901 if (hr == S_OK) IImageList_Release(merge);
1902
1903 IImageList_Release(imgl1);
1904 IImageList_Release(imgl2);
1905
1906 DestroyIcon(hicon1);
1907 DestroyWindow(hwnd);
1908 }
1909
1910 static void test_iconsize(void)
1911 {
1912 HIMAGELIST himl;
1913 INT cx, cy;
1914 BOOL ret;
1915
1916 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1917 /* null pointers, not zero imagelist dimensions */
1918 ret = ImageList_GetIconSize(himl, NULL, NULL);
1919 ok(!ret, "got %d\n", ret);
1920
1921 /* doesn't touch return pointers */
1922 cx = 0x1abe11ed;
1923 ret = ImageList_GetIconSize(himl, &cx, NULL);
1924 ok(!ret, "got %d\n", ret);
1925 ok(cx == 0x1abe11ed, "got %d\n", cx);
1926
1927 cy = 0x1abe11ed;
1928 ret = ImageList_GetIconSize(himl, NULL, &cy);
1929 ok(!ret, "got %d\n", ret);
1930 ok(cy == 0x1abe11ed, "got %d\n", cy);
1931
1932 ImageList_Destroy(himl);
1933
1934 ret = ImageList_GetIconSize((HIMAGELIST)0xdeadbeef, &cx, &cy);
1935 ok(!ret, "got %d\n", ret);
1936 }
1937
1938 static void test_create_destroy(void)
1939 {
1940 HIMAGELIST himl;
1941 IImageList *imgl;
1942 INT cx, cy;
1943 BOOL rc;
1944 HRESULT hr;
1945 INT ret;
1946
1947 /* list with zero or negative image dimensions */
1948 himl = ImageList_Create(0, 0, ILC_COLOR16, 0, 3);
1949 ok(himl == NULL, "got %p\n", himl);
1950
1951 himl = ImageList_Create(0, 16, ILC_COLOR16, 0, 3);
1952 ok(himl == NULL, "got %p\n", himl);
1953
1954 himl = ImageList_Create(16, 0, ILC_COLOR16, 0, 3);
1955 ok(himl == NULL, "got %p\n", himl);
1956
1957 himl = ImageList_Create(16, -1, ILC_COLOR16, 0, 3);
1958 ok(himl == NULL, "got %p\n", himl);
1959
1960 himl = ImageList_Create(-1, 16, ILC_COLOR16, 0, 3);
1961 ok(himl == NULL, "got %p\n", himl);
1962
1963 rc = ImageList_Destroy((HIMAGELIST)0xdeadbeef);
1964 ok(rc == FALSE, "ImageList_Destroy(0xdeadbeef) should fail and not crash\n");
1965
1966 /* DDB image lists */
1967 himl = ImageList_Create(0, 14, ILC_COLORDDB, 4, 4);
1968 ok(himl != NULL, "got %p\n", himl);
1969 imgl = (IImageList*)himl;
1970 IImageList_GetIconSize(imgl, &cx, &cy);
1971 ok (cx == 0, "Wrong cx (%i)\n", cx);
1972 ok (cy == 14, "Wrong cy (%i)\n", cy);
1973 ImageList_Destroy(himl);
1974
1975 himl = ImageList_Create(0, 0, ILC_COLORDDB, 4, 4);
1976 ok(himl != NULL, "got %p\n", himl);
1977 imgl = (IImageList*)himl;
1978 IImageList_GetIconSize(imgl, &cx, &cy);
1979 ok (cx == 0, "Wrong cx (%i)\n", cx);
1980 ok (cy == 0, "Wrong cy (%i)\n", cy);
1981 ImageList_Destroy(himl);
1982
1983 himl = ImageList_Create(0, 0, ILC_COLORDDB, 0, 4);
1984 ok(himl != NULL, "got %p\n", himl);
1985 imgl = (IImageList*)himl;
1986 IImageList_GetIconSize(imgl, &cx, &cy);
1987 ok (cx == 0, "Wrong cx (%i)\n", cx);
1988 ok (cy == 0, "Wrong cy (%i)\n", cy);
1989
1990 hr = IImageList_SetImageCount(imgl, 3);
1991 ok(hr == S_OK, "got 0x%08x\n", hr);
1992 hr = IImageList_GetImageCount(imgl, &ret);
1993 ok(hr == S_OK && ret == 3, "invalid image count after increase\n");
1994
1995 /* Trying to actually add an image causes a crash on Windows */
1996 ImageList_Destroy(himl);
1997
1998 /* Negative values fail */
1999 himl = ImageList_Create(-1, -1, ILC_COLORDDB, 4, 4);
2000 ok(himl == NULL, "got %p\n", himl);
2001 himl = ImageList_Create(-1, 1, ILC_COLORDDB, 4, 4);
2002 ok(himl == NULL, "got %p\n", himl);
2003 himl = ImageList_Create(1, -1, ILC_COLORDDB, 4, 4);
2004 ok(himl == NULL, "got %p\n", himl);
2005 }
2006
2007 static void check_color_table(const char *name, HDC hdc, HIMAGELIST himl, UINT ilc,
2008 RGBQUAD *expect, RGBQUAD *broken_expect)
2009 {
2010 IMAGEINFO info;
2011 INT ret;
2012 char bmi_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors) + 256 * sizeof(RGBQUAD)];
2013 BITMAPINFO *bmi = (BITMAPINFO *)bmi_buffer;
2014 int i, depth = ilc & 0xfe;
2015
2016 ret = ImageList_GetImageInfo(himl, 0, &info);
2017 ok(ret, "got %d\n", ret);
2018 ok(info.hbmImage != NULL, "got %p\n", info.hbmImage);
2019
2020 memset(bmi_buffer, 0, sizeof(bmi_buffer));
2021 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
2022 ret = GetDIBits(hdc, info.hbmImage, 0, 0, NULL, bmi, DIB_RGB_COLORS);
2023 ok(ret, "got %d\n", ret);
2024 ok(bmi->bmiHeader.biBitCount == depth, "got %d\n", bmi->bmiHeader.biBitCount);
2025
2026 ret = GetDIBits(hdc, info.hbmImage, 0, 0, NULL, bmi, DIB_RGB_COLORS);
2027 ok(ret, "got %d\n", ret);
2028 ok(bmi->bmiHeader.biBitCount == depth, "got %d\n", bmi->bmiHeader.biBitCount);
2029
2030 for (i = 0; i < (1 << depth); i++)
2031 ok((bmi->bmiColors[i].rgbRed == expect[i].rgbRed &&
2032 bmi->bmiColors[i].rgbGreen == expect[i].rgbGreen &&
2033 bmi->bmiColors[i].rgbBlue == expect[i].rgbBlue) ||
2034 (broken_expect && broken(bmi->bmiColors[i].rgbRed == broken_expect[i].rgbRed &&
2035 bmi->bmiColors[i].rgbGreen == broken_expect[i].rgbGreen &&
2036 bmi->bmiColors[i].rgbBlue == broken_expect[i].rgbBlue)),
2037 "%d: %s: got color[%d] %02x %02x %02x expect %02x %02x %02x\n", depth, name, i,
2038 bmi->bmiColors[i].rgbRed, bmi->bmiColors[i].rgbGreen, bmi->bmiColors[i].rgbBlue,
2039 expect[i].rgbRed, expect[i].rgbGreen, expect[i].rgbBlue);
2040 }
2041
2042 static void get_default_color_table(HDC hdc, int bpp, RGBQUAD *table)
2043 {
2044 char bmi_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors) + 256 * sizeof(RGBQUAD)];
2045 BITMAPINFO *bmi = (BITMAPINFO *)bmi_buffer;
2046 HBITMAP tmp;
2047 int i;
2048 HPALETTE pal;
2049 PALETTEENTRY entries[256];
2050
2051 switch (bpp)
2052 {
2053 case 4:
2054 tmp = CreateBitmap( 1, 1, 1, 1, NULL );
2055 memset(bmi_buffer, 0, sizeof(bmi_buffer));
2056 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
2057 bmi->bmiHeader.biHeight = 1;
2058 bmi->bmiHeader.biWidth = 1;
2059 bmi->bmiHeader.biBitCount = bpp;
2060 bmi->bmiHeader.biPlanes = 1;
2061 bmi->bmiHeader.biCompression = BI_RGB;
2062 GetDIBits( hdc, tmp, 0, 0, NULL, bmi, DIB_RGB_COLORS );
2063
2064 memcpy(table, bmi->bmiColors, (1 << bpp) * sizeof(RGBQUAD));
2065 table[7] = bmi->bmiColors[8];
2066 table[8] = bmi->bmiColors[7];
2067 DeleteObject( tmp );
2068 break;
2069
2070 case 8:
2071 pal = CreateHalftonePalette(hdc);
2072 GetPaletteEntries(pal, 0, 256, entries);
2073 for (i = 0; i < 256; i++)
2074 {
2075 table[i].rgbRed = entries[i].peRed;
2076 table[i].rgbGreen = entries[i].peGreen;
2077 table[i].rgbBlue = entries[i].peBlue;
2078 table[i].rgbReserved = 0;
2079 }
2080 DeleteObject(pal);
2081 break;
2082
2083 default:
2084 ok(0, "unhandled depth %d\n", bpp);
2085 }
2086 }
2087
2088 static void test_color_table(UINT ilc)
2089 {
2090 HIMAGELIST himl;
2091 INT ret;
2092 char bmi_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors) + 256 * sizeof(RGBQUAD)];
2093 BITMAPINFO *bmi = (BITMAPINFO *)bmi_buffer;
2094 HDC hdc = CreateCompatibleDC(0);
2095 HBITMAP dib4, dib8, dib32;
2096 RGBQUAD rgb[256], default_table[256];
2097
2098 get_default_color_table(hdc, ilc & 0xfe, default_table);
2099
2100 himl = ImageList_Create(16, 16, ilc, 0, 3);
2101 ok(himl != NULL, "got %p\n", himl);
2102
2103 memset(bmi_buffer, 0, sizeof(bmi_buffer));
2104 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
2105 bmi->bmiHeader.biHeight = 16;
2106 bmi->bmiHeader.biWidth = 16;
2107 bmi->bmiHeader.biBitCount = 8;
2108 bmi->bmiHeader.biPlanes = 1;
2109 bmi->bmiHeader.biCompression = BI_RGB;
2110 bmi->bmiColors[0].rgbRed = 0xff;
2111 bmi->bmiColors[1].rgbGreen = 0xff;
2112 bmi->bmiColors[2].rgbBlue = 0xff;
2113
2114 dib8 = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
2115
2116 bmi->bmiHeader.biBitCount = 4;
2117 bmi->bmiColors[0].rgbRed = 0xff;
2118 bmi->bmiColors[0].rgbGreen = 0x00;
2119 bmi->bmiColors[0].rgbBlue = 0xff;
2120 bmi->bmiColors[1].rgbRed = 0xff;
2121 bmi->bmiColors[1].rgbGreen = 0xff;
2122 bmi->bmiColors[1].rgbBlue = 0x00;
2123 bmi->bmiColors[2].rgbRed = 0x00;
2124 bmi->bmiColors[2].rgbGreen = 0xff;
2125 bmi->bmiColors[2].rgbBlue = 0xff;
2126
2127 dib4 = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
2128
2129 bmi->bmiHeader.biBitCount = 32;
2130
2131 dib32 = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
2132
2133 /* add 32 first then 8. This won't set the color table */
2134 ret = ImageList_Add(himl, dib32, NULL);
2135 ok(ret == 0, "got %d\n", ret);
2136 ret = ImageList_Add(himl, dib8, NULL);
2137 ok(ret == 1, "got %d\n", ret);
2138
2139 check_color_table("add 32, 8", hdc, himl, ilc, default_table, NULL);
2140
2141 /* since the previous _Adds didn't set the color table, this one will */
2142 ret = ImageList_Remove(himl, -1);
2143 ok(ret, "got %d\n", ret);
2144 ret = ImageList_Add(himl, dib8, NULL);
2145 ok(ret == 0, "got %d\n", ret);
2146
2147 memset(rgb, 0, sizeof(rgb));
2148 rgb[0].rgbRed = 0xff;
2149 rgb[1].rgbGreen = 0xff;
2150 rgb[2].rgbBlue = 0xff;
2151 check_color_table("remove all, add 8", hdc, himl, ilc, rgb, default_table);
2152
2153 /* remove all, add 4. Color table remains the same since it's inplicitly
2154 been set by the previous _Add */
2155 ret = ImageList_Remove(himl, -1);
2156 ok(ret, "got %d\n", ret);
2157 ret = ImageList_Add(himl, dib4, NULL);
2158 ok(ret == 0, "got %d\n", ret);
2159 check_color_table("remove all, add 4", hdc, himl, ilc, rgb, default_table);
2160
2161 ImageList_Destroy(himl);
2162 himl = ImageList_Create(16, 16, ilc, 0, 3);
2163 ok(himl != NULL, "got %p\n", himl);
2164
2165 /* add 4 */
2166 ret = ImageList_Add(himl, dib4, NULL);
2167 ok(ret == 0, "got %d\n", ret);
2168
2169 memset(rgb, 0, 16 * sizeof(rgb[0]));
2170 rgb[0].rgbRed = 0xff;
2171 rgb[0].rgbBlue = 0xff;
2172 rgb[1].rgbRed = 0xff;
2173 rgb[1].rgbGreen = 0xff;
2174 rgb[2].rgbGreen = 0xff;
2175 rgb[2].rgbBlue = 0xff;
2176 memcpy(rgb + 16, default_table + 16, 240 * sizeof(rgb[0]));
2177
2178 check_color_table("add 4", hdc, himl, ilc, rgb, default_table);
2179
2180 ImageList_Destroy(himl);
2181 himl = ImageList_Create(16, 16, ilc, 0, 3);
2182 ok(himl != NULL, "got %p\n", himl);
2183
2184 /* set color table, add 8 */
2185 ret = ImageList_Remove(himl, -1);
2186 ok(ret, "got %d\n", ret);
2187 memset(rgb, 0, sizeof(rgb));
2188 rgb[0].rgbRed = 0xcc;
2189 rgb[1].rgbBlue = 0xcc;
2190 ret = pImageList_SetColorTable(himl, 0, 2, rgb);
2191 ok(ret == 2, "got %d\n", ret);
2192 /* the table is set, so this doesn't change it */
2193 ret = ImageList_Add(himl, dib8, NULL);
2194 ok(ret == 0, "got %d\n", ret);
2195
2196 memcpy(rgb + 2, default_table + 2, 254 * sizeof(rgb[0]));
2197 check_color_table("SetColorTable", hdc, himl, ilc, rgb, NULL);
2198
2199 DeleteObject(dib32);
2200 DeleteObject(dib8);
2201 DeleteObject(dib4);
2202 DeleteDC(hdc);
2203 ImageList_Destroy(himl);
2204 }
2205
2206 static void test_copy(void)
2207 {
2208 HIMAGELIST dst, src;
2209 BOOL ret;
2210 int count;
2211
2212 dst = ImageList_Create(5, 11, ILC_COLOR, 1, 1);
2213 count = ImageList_GetImageCount(dst);
2214 ok(!count, "ImageList not empty.\n");
2215 src = createImageList(7, 13);
2216 count = ImageList_GetImageCount(src);
2217 ok(count > 2, "Tests need an ImageList with more than 2 images\n");
2218
2219 /* ImageList_Copy() cannot copy between two ImageLists */
2220 ret = ImageList_Copy(dst, 0, src, 2, ILCF_MOVE);
2221 ok(!ret, "ImageList_Copy() should have returned FALSE\n");
2222 count = ImageList_GetImageCount(dst);
2223 ok(count == 0, "Expected no image in dst ImageList, got %d\n", count);
2224
2225 ImageList_Destroy(dst);
2226 ImageList_Destroy(src);
2227 }
2228
2229 static void test_IImageList_Clone(void)
2230 {
2231 IImageList *imgl, *imgl2;
2232 HIMAGELIST himl;
2233 HRESULT hr;
2234 ULONG ref;
2235
2236 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
2237 imgl = (IImageList*)himl;
2238
2239 if (0)
2240 {
2241 /* crashes on native */
2242 IImageList_Clone(imgl, &IID_IImageList, NULL);
2243 }
2244
2245 hr = IImageList_Clone(imgl, &IID_IImageList, (void**)&imgl2);
2246 ok(hr == S_OK, "got 0x%08x\n", hr);
2247 ref = IImageList_Release(imgl2);
2248 ok(ref == 0, "got %u\n", ref);
2249
2250 IImageList_Release(imgl);
2251 }
2252
2253 static void test_IImageList_GetBkColor(void)
2254 {
2255 IImageList *imgl;
2256 HIMAGELIST himl;
2257 COLORREF color;
2258 HRESULT hr;
2259
2260 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
2261 imgl = (IImageList*)himl;
2262
2263 if (0)
2264 {
2265 /* crashes on native */
2266 IImageList_GetBkColor(imgl, NULL);
2267 }
2268
2269 hr = IImageList_GetBkColor(imgl, &color);
2270 ok(hr == S_OK, "got 0x%08x\n", hr);
2271
2272 IImageList_Release(imgl);
2273 }
2274
2275 static void test_IImageList_SetBkColor(void)
2276 {
2277 IImageList *imgl;
2278 HIMAGELIST himl;
2279 COLORREF color;
2280 HRESULT hr;
2281
2282 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
2283 imgl = (IImageList*)himl;
2284
2285 if (0)
2286 {
2287 /* crashes on native */
2288 IImageList_SetBkColor(imgl, RGB(0, 0, 0), NULL);
2289 }
2290
2291 hr = IImageList_SetBkColor(imgl, CLR_NONE, &color);
2292 ok(hr == S_OK, "got 0x%08x\n", hr);
2293
2294 hr = IImageList_SetBkColor(imgl, CLR_NONE, &color);
2295 ok(hr == S_OK, "got 0x%08x\n", hr);
2296
2297 color = 0xdeadbeef;
2298 hr = IImageList_GetBkColor(imgl, &color);
2299 ok(hr == S_OK, "got 0x%08x\n", hr);
2300 ok(color == CLR_NONE, "got %x\n", color);
2301
2302 IImageList_Release(imgl);
2303 }
2304
2305 static void test_IImageList_GetImageCount(void)
2306 {
2307 IImageList *imgl;
2308 HIMAGELIST himl;
2309 int count;
2310 HRESULT hr;
2311
2312 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
2313 imgl = (IImageList*)himl;
2314
2315 if (0)
2316 {
2317 /* crashes on native */
2318 IImageList_GetImageCount(imgl, NULL);
2319 }
2320
2321 count = -1;
2322 hr = IImageList_GetImageCount(imgl, &count);
2323 ok(hr == S_OK, "got 0x%08x\n", hr);
2324 ok(count == 0, "got %d\n", count);
2325
2326 IImageList_Release(imgl);
2327 }
2328
2329 static void test_IImageList_GetIconSize(void)
2330 {
2331 IImageList *imgl;
2332 HIMAGELIST himl;
2333 int cx, cy;
2334 HRESULT hr;
2335
2336 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
2337 imgl = (IImageList*)himl;
2338
2339 hr = IImageList_GetIconSize(imgl, NULL, NULL);
2340 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2341
2342 hr = IImageList_GetIconSize(imgl, &cx, NULL);
2343 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2344
2345 hr = IImageList_GetIconSize(imgl, NULL, &cy);
2346 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2347
2348 IImageList_Release(imgl);
2349 }
2350
2351 START_TEST(imagelist)
2352 {
2353 ULONG_PTR ctx_cookie;
2354 HANDLE hCtx;
2355
2356 HMODULE hComCtl32 = GetModuleHandleA("comctl32.dll");
2357 pImageList_Create = NULL; /* These are not needed for non-v6.0 tests*/
2358 pImageList_Add = NULL;
2359 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
2360 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
2361 pImageList_SetColorTable = (void*)GetProcAddress(hComCtl32, (const char*)390);
2362
2363 hinst = GetModuleHandleA(NULL);
2364
2365 InitCommonControls();
2366
2367 test_create_destroy();
2368 test_begindrag();
2369 test_hotspot();
2370 test_add_remove();
2371 test_imagecount();
2372 test_DrawIndirect();
2373 test_merge();
2374 test_merge_colors();
2375 test_imagelist_storage();
2376 test_iconsize();
2377 test_color_table(ILC_COLOR4);
2378 test_color_table(ILC_COLOR8);
2379 test_copy();
2380
2381 FreeLibrary(hComCtl32);
2382
2383 /* Now perform v6 tests */
2384
2385 if (!load_v6_module(&ctx_cookie, &hCtx))
2386 return;
2387
2388 /* Reload comctl32 */
2389 hComCtl32 = LoadLibraryA("comctl32.dll");
2390 pImageList_Create = (void*)GetProcAddress(hComCtl32, "ImageList_Create");
2391 pImageList_Add = (void*)GetProcAddress(hComCtl32, "ImageList_Add");
2392 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
2393 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
2394 pImageList_CoCreateInstance = (void*)GetProcAddress(hComCtl32, "ImageList_CoCreateInstance");
2395 pHIMAGELIST_QueryInterface = (void*)GetProcAddress(hComCtl32, "HIMAGELIST_QueryInterface");
2396
2397 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
2398
2399 /* Do v6.0 tests */
2400 test_ImageList_DrawIndirect();
2401 test_shell_imagelist();
2402 test_iimagelist();
2403
2404 test_hotspot_v6();
2405 test_IImageList_Add_Remove();
2406 test_IImageList_Get_SetImageCount();
2407 test_IImageList_Draw();
2408 test_IImageList_Merge();
2409 test_IImageList_Clone();
2410 test_IImageList_GetBkColor();
2411 test_IImageList_SetBkColor();
2412 test_IImageList_GetImageCount();
2413 test_IImageList_GetIconSize();
2414
2415 CoUninitialize();
2416
2417 unload_v6_module(ctx_cookie, hCtx);
2418 }