msxml3: Leading space chars are allowed in SelectionNamespaces value string.
[wine/multimedia.git] / dlls / comctl32 / tests / imagelist.c
blobb920b9aaf5babca004da1fe638d458b97f73e513
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 DeleteObject(hbm);
130 return himl;
133 static HWND create_a_window(void)
135 char className[] = "bmwnd";
136 char winName[] = "Test Bitmap";
137 HWND hWnd;
138 static int registered = 0;
140 if (!registered)
142 WNDCLASSA cls;
144 cls.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
145 cls.lpfnWndProc = DefWindowProcA;
146 cls.cbClsExtra = 0;
147 cls.cbWndExtra = 0;
148 cls.hInstance = 0;
149 cls.hIcon = LoadIconA (0, IDI_APPLICATION);
150 cls.hCursor = LoadCursorA (0, IDC_ARROW);
151 cls.hbrBackground = GetStockObject (WHITE_BRUSH);
152 cls.lpszMenuName = 0;
153 cls.lpszClassName = className;
155 RegisterClassA (&cls);
156 registered = 1;
159 /* Setup window */
160 hWnd = CreateWindowA (className, winName,
161 WS_OVERLAPPEDWINDOW ,
162 CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
163 0, hinst, 0);
165 #ifdef VISIBLE
166 ShowWindow (hWnd, SW_SHOW);
167 #endif
168 REDRAW(hWnd);
169 WAIT;
171 return hWnd;
174 static HDC show_image(HWND hwnd, HIMAGELIST himl, int idx, int size,
175 LPCSTR loc, BOOL clear)
177 HDC hdc = NULL;
178 #ifdef VISIBLE
179 if (!himl) return NULL;
181 SetWindowText(hwnd, loc);
182 hdc = GetDC(hwnd);
183 ImageList_Draw(himl, idx, hdc, 0, 0, ILD_TRANSPARENT);
185 REDRAW(hwnd);
186 WAIT;
188 if (clear)
190 BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
191 ReleaseDC(hwnd, hdc);
192 hdc = NULL;
194 #endif /* VISIBLE */
195 return hdc;
198 /* Useful for checking differences */
199 #if 0
200 static void dump_bits(const BYTE *p, const BYTE *q, int size)
202 int i, j;
204 size /= 8;
206 for (i = 0; i < size * 2; i++)
208 printf("|");
209 for (j = 0; j < size; j++)
210 printf("%c%c", p[j] & 0xf0 ? 'X' : ' ', p[j] & 0xf ? 'X' : ' ');
211 printf(" -- ");
212 for (j = 0; j < size; j++)
213 printf("%c%c", q[j] & 0xf0 ? 'X' : ' ', q[j] & 0xf ? 'X' : ' ');
214 printf("|\n");
215 p += size * 4;
216 q += size * 4;
218 printf("\n");
220 #endif
222 static void check_bits(HWND hwnd, HIMAGELIST himl, int idx, int size,
223 const BYTE *checkbits, LPCSTR loc)
225 #ifdef VISIBLE
226 BYTE bits[100*100/8];
227 COLORREF c;
228 HDC hdc;
229 int x, y, i = -1;
231 if (!himl) return;
233 memset(bits, 0, sizeof(bits));
234 hdc = show_image(hwnd, himl, idx, size, loc, FALSE);
236 c = GetPixel(hdc, 0, 0);
238 for (y = 0; y < size; y ++)
240 for (x = 0; x < size; x++)
242 if (!(x & 0x7)) i++;
243 if (GetPixel(hdc, x, y) != c) bits[i] |= (0x80 >> (x & 0x7));
247 BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
248 ReleaseDC(hwnd, hdc);
250 ok (memcmp(bits, checkbits, (size * size)/8) == 0,
251 "%s: bits different\n", loc);
252 if (memcmp(bits, checkbits, (size * size)/8))
253 dump_bits(bits, checkbits, size);
254 #endif /* VISIBLE */
257 static void test_hotspot(void)
259 struct hotspot {
260 int dx;
261 int dy;
264 #define SIZEX1 47
265 #define SIZEY1 31
266 #define SIZEX2 11
267 #define SIZEY2 17
268 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
269 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
270 { 10, 7 },
271 { SIZEX1, SIZEY1 },
272 { -9, -8 },
273 { -7, 35 }
275 int i, j, ret;
276 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
277 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
278 HWND hwnd = create_a_window();
281 for (i = 0; i < HOTSPOTS_MAX; i++) {
282 for (j = 0; j < HOTSPOTS_MAX; j++) {
283 int dx1 = hotspots[i].dx;
284 int dy1 = hotspots[i].dy;
285 int dx2 = hotspots[j].dx;
286 int dy2 = hotspots[j].dy;
287 int correctx, correcty, newx, newy;
288 char loc[256];
289 HIMAGELIST himlNew;
290 POINT ppt;
292 ret = ImageList_BeginDrag(himl1, 0, dx1, dy1);
293 ok(ret != 0, "BeginDrag failed for { %d, %d }\n", dx1, dy1);
294 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
295 show_image(hwnd, himl1, 0, max(SIZEX1, SIZEY1), loc, TRUE);
297 /* check merging the dragged image with a second image */
298 ret = ImageList_SetDragCursorImage(himl2, 0, dx2, dy2);
299 ok(ret != 0, "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
300 dx1, dy1, dx2, dy2);
301 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
302 show_image(hwnd, himl2, 0, max(SIZEX2, SIZEY2), loc, TRUE);
304 /* check new hotspot, it should be the same like the old one */
305 himlNew = ImageList_GetDragImage(NULL, &ppt);
306 ok(ppt.x == dx1 && ppt.y == dy1,
307 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
308 dx1, dy1, ppt.x, ppt.y);
309 /* check size of new dragged image */
310 ImageList_GetIconSize(himlNew, &newx, &newy);
311 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
312 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
313 ok(newx == correctx && newy == correcty,
314 "Expected drag image size [%d,%d] got [%d,%d]\n",
315 correctx, correcty, newx, newy);
316 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
317 show_image(hwnd, himlNew, 0, max(correctx, correcty), loc, TRUE);
318 ImageList_EndDrag();
321 #undef SIZEX1
322 #undef SIZEY1
323 #undef SIZEX2
324 #undef SIZEY2
325 #undef HOTSPOTS_MAX
326 ImageList_Destroy(himl2);
327 ImageList_Destroy(himl1);
328 DestroyWindow(hwnd);
331 static void test_add_remove(void)
333 HIMAGELIST himl ;
335 HICON hicon1 ;
336 HICON hicon2 ;
337 HICON hicon3 ;
339 /* create an imagelist to play with */
340 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
341 ok(himl!=0,"failed to create imagelist\n");
343 /* load the icons to add to the image list */
344 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
345 ok(hicon1 != 0, "no hicon1\n");
346 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
347 ok(hicon2 != 0, "no hicon2\n");
348 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
349 ok(hicon3 != 0, "no hicon3\n");
351 /* remove when nothing exists */
352 ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
353 /* removing everything from an empty imagelist should succeed */
354 ok(ImageList_RemoveAll(himl),"removed nonexistent icon\n");
356 /* add three */
357 ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
358 ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
359 ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
361 /* remove an index out of range */
362 ok(!ImageList_Remove(himl,4711),"removed nonexistent icon\n");
364 /* remove three */
365 ok(ImageList_Remove(himl,0),"can't remove 0\n");
366 ok(ImageList_Remove(himl,0),"can't remove 0\n");
367 ok(ImageList_Remove(himl,0),"can't remove 0\n");
369 /* remove one extra */
370 ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
372 /* destroy it */
373 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
375 ok(-1==ImageList_AddIcon((HIMAGELIST)0xdeadbeef, hicon1),"don't crash on bad handle\n");
377 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
378 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
379 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
382 static void test_imagecount(void)
384 HIMAGELIST himl;
386 ok(0==ImageList_GetImageCount((HIMAGELIST)0xdeadbeef),"don't crash on bad handle\n");
388 if (!pImageList_SetImageCount)
390 win_skip("ImageList_SetImageCount not available\n");
391 return;
394 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
395 ok(himl!=0,"failed to create imagelist\n");
397 ok(pImageList_SetImageCount(himl, 3), "couldn't increase image count\n");
398 ok(ImageList_GetImageCount(himl) == 3, "invalid image count after increase\n");
399 ok(pImageList_SetImageCount(himl, 1), "couldn't decrease image count\n");
400 ok(ImageList_GetImageCount(himl) == 1, "invalid image count after decrease to 1\n");
401 ok(pImageList_SetImageCount(himl, 0), "couldn't decrease image count\n");
402 ok(ImageList_GetImageCount(himl) == 0, "invalid image count after decrease to 0\n");
404 ok(ImageList_Destroy(himl), "destroy imagelist failed\n");
407 static void test_DrawIndirect(void)
409 HIMAGELIST himl;
411 HBITMAP hbm1;
412 HBITMAP hbm2;
413 HBITMAP hbm3;
415 IMAGELISTDRAWPARAMS imldp;
416 HDC hdc;
417 HWND hwndfortest;
419 if (!pImageList_DrawIndirect)
421 win_skip("ImageList_DrawIndirect not available, skipping test\n");
422 return;
425 hwndfortest = create_a_window();
426 hdc = GetDC(hwndfortest);
427 ok(hdc!=NULL, "couldn't get DC\n");
429 /* create an imagelist to play with */
430 himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
431 ok(himl!=0,"failed to create imagelist\n");
433 /* load the icons to add to the image list */
434 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
435 ok(hbm1 != 0, "no bitmap 1\n");
436 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
437 ok(hbm2 != 0, "no bitmap 2\n");
438 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
439 ok(hbm3 != 0, "no bitmap 3\n");
441 /* add three */
442 ok(0==ImageList_Add(himl, hbm1, 0),"failed to add bitmap 1\n");
443 ok(1==ImageList_Add(himl, hbm2, 0),"failed to add bitmap 2\n");
445 if (pImageList_SetImageCount)
447 ok(pImageList_SetImageCount(himl,3),"Setimage count failed\n");
448 /*ok(2==ImageList_Add(himl, hbm3, NULL),"failed to add bitmap 3\n"); */
449 ok(ImageList_Replace(himl, 2, hbm3, 0),"failed to replace bitmap 3\n");
452 memset(&imldp, 0, sizeof (imldp));
453 ok(!pImageList_DrawIndirect(&imldp), "zero data succeeded!\n");
454 imldp.cbSize = IMAGELISTDRAWPARAMS_V3_SIZE;
455 ok(!pImageList_DrawIndirect(&imldp), "zero hdc succeeded!\n");
456 imldp.hdcDst = hdc;
457 ok(!pImageList_DrawIndirect(&imldp),"zero himl succeeded!\n");
458 imldp.himl = (HIMAGELIST)0xdeadbeef;
459 ok(!pImageList_DrawIndirect(&imldp),"bad himl succeeded!\n");
460 imldp.himl = himl;
462 REDRAW(hwndfortest);
463 WAIT;
465 imldp.fStyle = SRCCOPY;
466 imldp.rgbBk = CLR_DEFAULT;
467 imldp.rgbFg = CLR_DEFAULT;
468 imldp.y = 100;
469 imldp.x = 100;
470 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
471 imldp.i ++;
472 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
473 imldp.i ++;
474 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
475 imldp.i ++;
476 ok(!pImageList_DrawIndirect(&imldp),"should fail\n");
478 /* remove three */
479 ok(ImageList_Remove(himl, 0), "removing 1st bitmap\n");
480 ok(ImageList_Remove(himl, 0), "removing 2nd bitmap\n");
481 ok(ImageList_Remove(himl, 0), "removing 3rd bitmap\n");
483 /* destroy it */
484 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
486 /* bitmaps should not be deleted by the imagelist */
487 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
488 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
489 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
491 ReleaseDC(hwndfortest, hdc);
492 DestroyWindow(hwndfortest);
495 static void test_merge(void)
497 HIMAGELIST himl1, himl2, hmerge;
498 HICON hicon1;
499 HWND hwnd = create_a_window();
501 himl1 = ImageList_Create(32,32,0,0,3);
502 ok(himl1 != NULL,"failed to create himl1\n");
504 himl2 = ImageList_Create(32,32,0,0,3);
505 ok(himl2 != NULL,"failed to create himl2\n");
507 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
508 ok(hicon1 != NULL, "failed to create hicon1\n");
510 if (!himl1 || !himl2 || !hicon1)
511 return;
513 ok(0==ImageList_AddIcon(himl2, hicon1),"add icon1 to himl2 failed\n");
514 check_bits(hwnd, himl2, 0, 32, icon_bits, "add icon1 to himl2");
516 /* If himl1 has no images, merge still succeeds */
517 hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
518 ok(hmerge != NULL, "merge himl1,-1 failed\n");
519 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,-1");
520 if (hmerge) ImageList_Destroy(hmerge);
522 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
523 ok(hmerge != NULL,"merge himl1,0 failed\n");
524 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,0");
525 if (hmerge) ImageList_Destroy(hmerge);
527 /* Same happens if himl2 is empty */
528 ImageList_Destroy(himl2);
529 himl2 = ImageList_Create(32,32,0,0,3);
530 ok(himl2 != NULL,"failed to recreate himl2\n");
531 if (!himl2)
532 return;
534 hmerge = ImageList_Merge(himl1, -1, himl2, -1, 0, 0);
535 ok(hmerge != NULL, "merge himl2,-1 failed\n");
536 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,-1");
537 if (hmerge) ImageList_Destroy(hmerge);
539 hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
540 ok(hmerge != NULL, "merge himl2,0 failed\n");
541 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,0");
542 if (hmerge) ImageList_Destroy(hmerge);
544 /* Now try merging an image with itself */
545 ok(0==ImageList_AddIcon(himl2, hicon1),"re-add icon1 to himl2 failed\n");
547 hmerge = ImageList_Merge(himl2, 0, himl2, 0, 0, 0);
548 ok(hmerge != NULL, "merge himl2 with itself failed\n");
549 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2 with itself");
550 if (hmerge) ImageList_Destroy(hmerge);
552 /* Try merging 2 different image lists */
553 ok(0==ImageList_AddIcon(himl1, hicon1),"add icon1 to himl1 failed\n");
555 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
556 ok(hmerge != NULL, "merge himl1 with himl2 failed\n");
557 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2");
558 if (hmerge) ImageList_Destroy(hmerge);
560 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 8, 16);
561 ok(hmerge != NULL, "merge himl1 with himl2 8,16 failed\n");
562 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2, 8,16");
563 if (hmerge) ImageList_Destroy(hmerge);
565 ImageList_Destroy(himl1);
566 ImageList_Destroy(himl2);
567 DestroyIcon(hicon1);
568 DestroyWindow(hwnd);
571 /*********************** imagelist storage test ***************************/
573 #define BMP_CX 48
575 struct my_IStream
577 IStream IStream_iface;
578 char *iml_data; /* written imagelist data */
579 ULONG iml_data_size;
582 static struct my_IStream *impl_from_IStream(IStream *iface)
584 return CONTAINING_RECORD(iface, struct my_IStream, IStream_iface);
587 static HRESULT STDMETHODCALLTYPE Test_Stream_QueryInterface(IStream *iface, REFIID riid,
588 void **ppvObject)
590 assert(0);
591 return E_NOTIMPL;
594 static ULONG STDMETHODCALLTYPE Test_Stream_AddRef(IStream *iface)
596 assert(0);
597 return 2;
600 static ULONG STDMETHODCALLTYPE Test_Stream_Release(IStream *iface)
602 assert(0);
603 return 1;
606 static HRESULT STDMETHODCALLTYPE Test_Stream_Read(IStream *iface, void *pv, ULONG cb,
607 ULONG *pcbRead)
609 assert(0);
610 return E_NOTIMPL;
613 static BOOL allocate_storage(struct my_IStream *my_is, ULONG add)
615 my_is->iml_data_size += add;
617 if (!my_is->iml_data)
618 my_is->iml_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, my_is->iml_data_size);
619 else
620 my_is->iml_data = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, my_is->iml_data, my_is->iml_data_size);
622 return my_is->iml_data ? TRUE : FALSE;
625 static HRESULT STDMETHODCALLTYPE Test_Stream_Write(IStream *iface, const void *pv, ULONG cb,
626 ULONG *pcbWritten)
628 struct my_IStream *my_is = impl_from_IStream(iface);
629 ULONG current_iml_data_size = my_is->iml_data_size;
631 if (!allocate_storage(my_is, cb)) return E_FAIL;
633 memcpy(my_is->iml_data + current_iml_data_size, pv, cb);
634 if (pcbWritten) *pcbWritten = cb;
636 return S_OK;
639 static HRESULT STDMETHODCALLTYPE Test_Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove,
640 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
642 assert(0);
643 return E_NOTIMPL;
646 static HRESULT STDMETHODCALLTYPE Test_Stream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
648 assert(0);
649 return E_NOTIMPL;
652 static HRESULT STDMETHODCALLTYPE Test_Stream_CopyTo(IStream *iface, IStream *pstm,
653 ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead,
654 ULARGE_INTEGER *pcbWritten)
656 assert(0);
657 return E_NOTIMPL;
660 static HRESULT STDMETHODCALLTYPE Test_Stream_Commit(IStream *iface, DWORD grfCommitFlags)
662 assert(0);
663 return E_NOTIMPL;
666 static HRESULT STDMETHODCALLTYPE Test_Stream_Revert(IStream *iface)
668 assert(0);
669 return E_NOTIMPL;
672 static HRESULT STDMETHODCALLTYPE Test_Stream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset,
673 ULARGE_INTEGER cb, DWORD dwLockType)
675 assert(0);
676 return E_NOTIMPL;
679 static HRESULT STDMETHODCALLTYPE Test_Stream_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset,
680 ULARGE_INTEGER cb, DWORD dwLockType)
682 assert(0);
683 return E_NOTIMPL;
686 static HRESULT STDMETHODCALLTYPE Test_Stream_Stat(IStream *iface, STATSTG *pstatstg,
687 DWORD grfStatFlag)
689 assert(0);
690 return E_NOTIMPL;
693 static HRESULT STDMETHODCALLTYPE Test_Stream_Clone(IStream *iface, IStream **ppstm)
695 assert(0);
696 return E_NOTIMPL;
699 static const IStreamVtbl Test_Stream_Vtbl =
701 Test_Stream_QueryInterface,
702 Test_Stream_AddRef,
703 Test_Stream_Release,
704 Test_Stream_Read,
705 Test_Stream_Write,
706 Test_Stream_Seek,
707 Test_Stream_SetSize,
708 Test_Stream_CopyTo,
709 Test_Stream_Commit,
710 Test_Stream_Revert,
711 Test_Stream_LockRegion,
712 Test_Stream_UnlockRegion,
713 Test_Stream_Stat,
714 Test_Stream_Clone
717 static struct my_IStream Test_Stream = { { &Test_Stream_Vtbl }, 0, 0 };
719 static INT DIB_GetWidthBytes( int width, int bpp )
721 return ((width * bpp + 31) / 8) & ~3;
724 static ULONG check_bitmap_data(const char *bm_data, ULONG bm_data_size,
725 INT width, INT height, INT bpp,
726 const char *comment)
728 const BITMAPFILEHEADER *bmfh = (const BITMAPFILEHEADER *)bm_data;
729 const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)(bm_data + sizeof(*bmfh));
730 ULONG hdr_size, image_size;
732 hdr_size = sizeof(*bmfh) + sizeof(*bmih);
733 if (bmih->biBitCount <= 8) hdr_size += (1 << bpp) * sizeof(RGBQUAD);
735 ok(bmfh->bfType == (('M' << 8) | 'B'), "wrong bfType 0x%02x\n", bmfh->bfType);
736 ok(bmfh->bfSize == hdr_size, "wrong bfSize 0x%02x\n", bmfh->bfSize);
737 ok(bmfh->bfReserved1 == 0, "wrong bfReserved1 0x%02x\n", bmfh->bfReserved1);
738 ok(bmfh->bfReserved2 == 0, "wrong bfReserved2 0x%02x\n", bmfh->bfReserved2);
739 ok(bmfh->bfOffBits == hdr_size, "wrong bfOffBits 0x%02x\n", bmfh->bfOffBits);
741 ok(bmih->biSize == sizeof(*bmih), "wrong biSize %d\n", bmih->biSize);
742 ok(bmih->biWidth == width, "wrong biWidth %d (expected %d)\n", bmih->biWidth, width);
743 ok(bmih->biHeight == height, "wrong biHeight %d (expected %d)\n", bmih->biHeight, height);
744 ok(bmih->biPlanes == 1, "wrong biPlanes %d\n", bmih->biPlanes);
745 ok(bmih->biBitCount == bpp, "wrong biBitCount %d\n", bmih->biBitCount);
747 image_size = DIB_GetWidthBytes(bmih->biWidth, bmih->biBitCount) * bmih->biHeight;
748 ok(bmih->biSizeImage == image_size, "wrong biSizeImage %u\n", bmih->biSizeImage);
749 #if 0
751 char fname[256];
752 FILE *f;
753 sprintf(fname, "bmp_%s.bmp", comment);
754 f = fopen(fname, "wb");
755 fwrite(bm_data, 1, bm_data_size, f);
756 fclose(f);
758 #endif
759 return hdr_size + image_size;
762 static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max, INT grow, INT flags)
764 const ILHEAD *ilh = (const ILHEAD *)ilh_data;
766 ok(ilh->usMagic == IMAGELIST_MAGIC, "wrong usMagic %4x (expected %02x)\n", ilh->usMagic, IMAGELIST_MAGIC);
767 ok(ilh->usVersion == 0x101, "wrong usVersion %x (expected 0x101)\n", ilh->usVersion);
768 ok(ilh->cCurImage == cur, "wrong cCurImage %d (expected %d)\n", ilh->cCurImage, cur);
769 ok(ilh->cMaxImage == max, "wrong cMaxImage %d (expected %d)\n", ilh->cMaxImage, max);
770 ok(ilh->cGrow == grow, "wrong cGrow %d (expected %d)\n", ilh->cGrow, grow);
771 ok(ilh->cx == cx, "wrong cx %d (expected %d)\n", ilh->cx, cx);
772 ok(ilh->cy == cy, "wrong cy %d (expected %d)\n", ilh->cy, cy);
773 ok(ilh->bkcolor == CLR_NONE, "wrong bkcolor %x\n", ilh->bkcolor);
774 ok(ilh->flags == flags || broken(!(ilh->flags & 0xfe) && (flags & 0xfe) == ILC_COLOR4), /* <= w2k */
775 "wrong flags %04x\n", ilh->flags);
776 ok(ilh->ovls[0] == -1, "wrong ovls[0] %04x\n", ilh->ovls[0]);
777 ok(ilh->ovls[1] == -1, "wrong ovls[1] %04x\n", ilh->ovls[1]);
778 ok(ilh->ovls[2] == -1, "wrong ovls[2] %04x\n", ilh->ovls[2]);
779 ok(ilh->ovls[3] == -1, "wrong ovls[3] %04x\n", ilh->ovls[3]);
782 static HBITMAP create_bitmap(INT cx, INT cy, COLORREF color, const char *comment)
784 HDC hdc;
785 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
786 BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
787 HBITMAP hbmp, hbmp_old;
788 HBRUSH hbrush;
789 RECT rc = { 0, 0, cx, cy };
791 hdc = CreateCompatibleDC(0);
793 memset(bmi, 0, sizeof(*bmi));
794 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
795 bmi->bmiHeader.biHeight = cx;
796 bmi->bmiHeader.biWidth = cy;
797 bmi->bmiHeader.biBitCount = 24;
798 bmi->bmiHeader.biPlanes = 1;
799 bmi->bmiHeader.biCompression = BI_RGB;
800 hbmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
802 hbmp_old = SelectObject(hdc, hbmp);
804 hbrush = CreateSolidBrush(color);
805 FillRect(hdc, &rc, hbrush);
806 DeleteObject(hbrush);
808 DrawText(hdc, comment, -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
810 SelectObject(hdc, hbmp_old);
811 DeleteDC(hdc);
813 return hbmp;
816 #define iml_clear_stream_data() \
817 HeapFree(GetProcessHeap(), 0, Test_Stream.iml_data); \
818 Test_Stream.iml_data = NULL; \
819 Test_Stream.iml_data_size = 0;
821 static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max, INT grow,
822 INT width, INT height, INT flags, const char *comment)
824 INT ret, cxx, cyy, size;
826 trace("%s\n", comment);
828 ret = ImageList_GetImageCount(himl);
829 ok(ret == cur, "expected image count %d got %d\n", cur, ret);
831 ret = ImageList_GetIconSize(himl, &cxx, &cyy);
832 ok(ret, "ImageList_GetIconSize failed\n");
833 ok(cxx == cx, "wrong cx %d (expected %d)\n", cxx, cx);
834 ok(cyy == cy, "wrong cy %d (expected %d)\n", cyy, cy);
836 iml_clear_stream_data();
837 ret = ImageList_Write(himl, &Test_Stream.IStream_iface);
838 ok(ret, "ImageList_Write failed\n");
840 ok(Test_Stream.iml_data != 0, "ImageList_Write didn't write any data\n");
841 ok(Test_Stream.iml_data_size > sizeof(ILHEAD), "ImageList_Write wrote not enough data\n");
843 check_ilhead_data(Test_Stream.iml_data, cx, cy, cur, max, grow, flags);
844 size = check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD),
845 Test_Stream.iml_data_size - sizeof(ILHEAD),
846 width, height, flags & 0xfe, comment);
847 if (size < Test_Stream.iml_data_size - sizeof(ILHEAD)) /* mask is present */
849 ok( flags & ILC_MASK, "extra data %u/%u but mask not expected\n",
850 Test_Stream.iml_data_size, size );
851 check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD) + size,
852 Test_Stream.iml_data_size - sizeof(ILHEAD) - size,
853 width, height, 1, comment);
857 static void image_list_init(HIMAGELIST himl)
859 HBITMAP hbm;
860 char comment[16];
861 INT n = 1;
862 DWORD i;
863 static const struct test_data
865 BYTE grey;
866 INT cx, cy, cur, max, grow, width, height, bpp;
867 const char *comment;
868 } td[] =
870 { 255, BMP_CX, BMP_CX, 1, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "total 1" },
871 { 170, BMP_CX, BMP_CX, 2, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 2" },
872 { 85, BMP_CX, BMP_CX, 3, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 3" },
873 { 0, BMP_CX, BMP_CX, 4, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 4" },
874 { 0, BMP_CX, BMP_CX, 5, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 5" },
875 { 85, BMP_CX, BMP_CX, 6, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 6" },
876 { 170, BMP_CX, BMP_CX, 7, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 7" },
877 { 255, BMP_CX, BMP_CX, 8, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 8" },
878 { 255, BMP_CX, BMP_CX, 9, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 9" },
879 { 170, BMP_CX, BMP_CX, 10, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 10" },
880 { 85, BMP_CX, BMP_CX, 11, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 11" },
881 { 0, BMP_CX, BMP_CX, 12, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 12" },
882 { 0, BMP_CX, BMP_CX, 13, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 13" },
883 { 85, BMP_CX, BMP_CX, 14, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 14" },
884 { 170, BMP_CX, BMP_CX, 15, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 15" },
885 { 255, BMP_CX, BMP_CX, 16, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 16" },
886 { 255, BMP_CX, BMP_CX, 17, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 17" },
887 { 170, BMP_CX, BMP_CX, 18, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 18" },
888 { 85, BMP_CX, BMP_CX, 19, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 19" },
889 { 0, BMP_CX, BMP_CX, 20, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 20" },
890 { 0, BMP_CX, BMP_CX, 21, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 21" },
891 { 85, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 22" },
892 { 170, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 23" },
893 { 255, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 24" }
896 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "total 0");
898 #define add_bitmap(grey) \
899 sprintf(comment, "%d", n++); \
900 hbm = create_bitmap(BMP_CX, BMP_CX, RGB((grey),(grey),(grey)), comment); \
901 ImageList_Add(himl, hbm, NULL); \
902 DeleteObject(hbm);
904 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
906 add_bitmap(td[i].grey);
907 check_iml_data(himl, td[i].cx, td[i].cy, td[i].cur, td[i].max, td[i].grow,
908 td[i].width, td[i].height, td[i].bpp, td[i].comment);
910 #undef add_bitmap
913 static void test_imagelist_storage(void)
915 HIMAGELIST himl;
916 HBITMAP hbm;
917 HICON icon;
918 INT ret;
920 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 1, 1);
921 ok(himl != 0, "ImageList_Create failed\n");
923 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "empty");
925 image_list_init(himl);
926 check_iml_data(himl, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "orig");
928 ret = ImageList_Remove(himl, 4);
929 ok(ret, "ImageList_Remove failed\n");
930 check_iml_data(himl, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "1");
932 ret = ImageList_Remove(himl, 5);
933 ok(ret, "ImageList_Remove failed\n");
934 check_iml_data(himl, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "2");
936 ret = ImageList_Remove(himl, 6);
937 ok(ret, "ImageList_Remove failed\n");
938 check_iml_data(himl, BMP_CX, BMP_CX, 21, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "3");
940 ret = ImageList_Remove(himl, 7);
941 ok(ret, "ImageList_Remove failed\n");
942 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "4");
944 ret = ImageList_Remove(himl, -2);
945 ok(!ret, "ImageList_Remove(-2) should fail\n");
946 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "5");
948 ret = ImageList_Remove(himl, 20);
949 ok(!ret, "ImageList_Remove(20) should fail\n");
950 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "6");
952 ret = ImageList_Remove(himl, -1);
953 ok(ret, "ImageList_Remove(-1) failed\n");
954 check_iml_data(himl, BMP_CX, BMP_CX, 0, 4, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "7");
956 ret = ImageList_Destroy(himl);
957 ok(ret, "ImageList_Destroy failed\n");
959 iml_clear_stream_data();
961 /* test ImageList_Create storage allocation */
963 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 0, 32);
964 ok(himl != 0, "ImageList_Create failed\n");
965 check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 32, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "init 0 grow 32");
966 hbm = create_bitmap(BMP_CX * 9, BMP_CX, 0, "9");
967 ret = ImageList_Add(himl, hbm, NULL);
968 ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
969 check_iml_data(himl, BMP_CX, BMP_CX, 1, 34, 32, BMP_CX * 4, BMP_CX * 9, ILC_COLOR24, "add 1 x 9");
970 DeleteObject(hbm);
971 ret = ImageList_Destroy(himl);
972 ok(ret, "ImageList_Destroy failed\n");
973 iml_clear_stream_data();
975 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 4);
976 ok(himl != 0, "ImageList_Create failed\n");
977 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24, "init 4 grow 4");
978 hbm = create_bitmap(BMP_CX, BMP_CX * 9, 0, "9");
979 ret = ImageList_Add(himl, hbm, NULL);
980 ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
981 check_iml_data(himl, BMP_CX, BMP_CX, 9, 15, 4, BMP_CX * 4, BMP_CX * 4, ILC_COLOR24, "add 9 x 1");
982 ret = ImageList_Add(himl, hbm, NULL);
983 ok(ret == 9, "ImageList_Add returned %d, expected 9\n", ret);
984 check_iml_data(himl, BMP_CX, BMP_CX, 18, 25, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "add 9 x 1");
985 DeleteObject(hbm);
986 ret = ImageList_Destroy(himl);
987 ok(ret, "ImageList_Destroy failed\n");
988 iml_clear_stream_data();
990 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 207, 209);
991 ok(himl != 0, "ImageList_Create failed\n");
992 check_iml_data(himl, BMP_CX, BMP_CX, 0, 208, 212, BMP_CX * 4, BMP_CX * 52, ILC_COLOR24, "init 207 grow 209");
993 ret = ImageList_Destroy(himl);
994 ok(ret, "ImageList_Destroy failed\n");
995 iml_clear_stream_data();
997 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 209, 207);
998 ok(himl != 0, "ImageList_Create failed\n");
999 check_iml_data(himl, BMP_CX, BMP_CX, 0, 210, 208, BMP_CX * 4, BMP_CX * 53, ILC_COLOR24, "init 209 grow 207");
1000 ret = ImageList_Destroy(himl);
1001 ok(ret, "ImageList_Destroy failed\n");
1002 iml_clear_stream_data();
1004 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 14, 4);
1005 ok(himl != 0, "ImageList_Create failed\n");
1006 check_iml_data(himl, BMP_CX, BMP_CX, 0, 15, 4, BMP_CX * 4, BMP_CX * 4, ILC_COLOR24, "init 14 grow 4");
1007 ret = ImageList_Destroy(himl);
1008 ok(ret, "ImageList_Destroy failed\n");
1009 iml_clear_stream_data();
1011 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 5, 9);
1012 ok(himl != 0, "ImageList_Create failed\n");
1013 check_iml_data(himl, BMP_CX, BMP_CX, 0, 6, 12, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24, "init 5 grow 9");
1014 ret = ImageList_Destroy(himl);
1015 ok(ret, "ImageList_Destroy failed\n");
1016 iml_clear_stream_data();
1018 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 9, 5);
1019 ok(himl != 0, "ImageList_Create failed\n");
1020 check_iml_data(himl, BMP_CX, BMP_CX, 0, 10, 8, BMP_CX * 4, BMP_CX * 3, ILC_COLOR24, "init 9 grow 5");
1021 ret = ImageList_Destroy(himl);
1022 ok(ret, "ImageList_Destroy failed\n");
1023 iml_clear_stream_data();
1025 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 2, 4);
1026 ok(himl != 0, "ImageList_Create failed\n");
1027 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "init 2 grow 4");
1028 ret = ImageList_Destroy(himl);
1029 ok(ret, "ImageList_Destroy failed\n");
1030 iml_clear_stream_data();
1032 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 2);
1033 ok(himl != 0, "ImageList_Create failed\n");
1034 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24, "init 4 grow 2");
1035 ret = ImageList_Destroy(himl);
1036 ok(ret, "ImageList_Destroy failed\n");
1037 iml_clear_stream_data();
1039 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR8, 4, 2);
1040 ok(himl != 0, "ImageList_Create failed\n");
1041 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR8, "bpp 8");
1042 ret = ImageList_Destroy(himl);
1043 ok(ret, "ImageList_Destroy failed\n");
1044 iml_clear_stream_data();
1046 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4, 4, 2);
1047 ok(himl != 0, "ImageList_Create failed\n");
1048 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4, "bpp 4");
1049 ret = ImageList_Destroy(himl);
1050 ok(ret, "ImageList_Destroy failed\n");
1051 iml_clear_stream_data();
1053 himl = ImageList_Create(BMP_CX, BMP_CX, 0, 4, 2);
1054 ok(himl != 0, "ImageList_Create failed\n");
1055 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4, "bpp default");
1056 icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1057 ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n");
1058 ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n");
1059 DestroyIcon( icon );
1060 check_iml_data(himl, BMP_CX, BMP_CX, 2, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4, "bpp default");
1061 ret = ImageList_Destroy(himl);
1062 ok(ret, "ImageList_Destroy failed\n");
1063 iml_clear_stream_data();
1065 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24|ILC_MASK, 4, 2);
1066 ok(himl != 0, "ImageList_Create failed\n");
1067 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24|ILC_MASK,
1068 "bpp 24 + mask");
1069 icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1070 ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n");
1071 ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n");
1072 DestroyIcon( icon );
1073 check_iml_data(himl, BMP_CX, BMP_CX, 2, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24|ILC_MASK,
1074 "bpp 24 + mask");
1075 ret = ImageList_Destroy(himl);
1076 ok(ret, "ImageList_Destroy failed\n");
1077 iml_clear_stream_data();
1079 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 4, 2);
1080 ok(himl != 0, "ImageList_Create failed\n");
1081 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4|ILC_MASK,
1082 "bpp 4 + mask");
1083 icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1084 ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n");
1085 ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n");
1086 DestroyIcon( icon );
1087 check_iml_data(himl, BMP_CX, BMP_CX, 2, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4|ILC_MASK,
1088 "bpp 4 + mask");
1089 ret = ImageList_Destroy(himl);
1090 ok(ret, "ImageList_Destroy failed\n");
1091 iml_clear_stream_data();
1093 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 99);
1094 ok(himl != 0, "ImageList_Create failed\n");
1095 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1096 "init 2 grow 99");
1097 icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1098 ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n");
1099 ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n");
1100 check_iml_data(himl, BMP_CX, BMP_CX, 2, 3, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1101 "init 2 grow 99 2 icons");
1102 ok( ImageList_AddIcon(himl, icon) == 2,"failed to add icon\n");
1103 DestroyIcon( icon );
1104 check_iml_data(himl, BMP_CX, BMP_CX, 3, 104, 100, BMP_CX * 4, BMP_CX * 104/4, ILC_COLOR4|ILC_MASK,
1105 "init 2 grow 99 3 icons");
1106 ok( ImageList_Remove(himl, -1) == TRUE,"failed to remove icon\n");
1107 check_iml_data(himl, BMP_CX, BMP_CX, 0, 100, 100, BMP_CX * 4, BMP_CX * 100/4, ILC_COLOR4|ILC_MASK,
1108 "init 2 grow 99 empty");
1109 ok( ImageList_SetImageCount(himl, 22) == TRUE,"failed to set image count\n");
1110 check_iml_data(himl, BMP_CX, BMP_CX, 22, 23, 100, BMP_CX * 4, BMP_CX * 24/4, ILC_COLOR4|ILC_MASK,
1111 "init 2 grow 99 set count 22");
1112 ok( ImageList_SetImageCount(himl, 0) == TRUE,"failed to set image count\n");
1113 check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1114 "init 2 grow 99 set count 0");
1115 ok( ImageList_SetImageCount(himl, 42) == TRUE,"failed to set image count\n");
1116 check_iml_data(himl, BMP_CX, BMP_CX, 42, 43, 100, BMP_CX * 4, BMP_CX * 44/4, ILC_COLOR4|ILC_MASK,
1117 "init 2 grow 99 set count 42");
1118 ret = ImageList_Destroy(himl);
1119 ok(ret, "ImageList_Destroy failed\n");
1120 iml_clear_stream_data();
1122 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 65536+12);
1123 ok(himl != 0, "ImageList_Create failed\n");
1124 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 12, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1125 "init 2 grow 65536+12");
1126 ret = ImageList_Destroy(himl);
1127 ok(ret, "ImageList_Destroy failed\n");
1128 iml_clear_stream_data();
1130 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 65535);
1131 ok(himl != 0, "ImageList_Create failed\n");
1132 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 0, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1133 "init 2 grow 65535");
1134 ret = ImageList_Destroy(himl);
1135 ok(ret, "ImageList_Destroy failed\n");
1136 iml_clear_stream_data();
1138 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, -20);
1139 ok(himl != 0, "ImageList_Create failed\n");
1140 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1141 "init 2 grow -20");
1142 ret = ImageList_Destroy(himl);
1143 ok(ret, "ImageList_Destroy failed\n");
1144 iml_clear_stream_data();
1147 static void test_shell_imagelist(void)
1149 BOOL (WINAPI *pSHGetImageList)(INT, REFIID, void**);
1150 IImageList *iml = NULL;
1151 HMODULE hShell32;
1152 HRESULT hr;
1153 int out = 0;
1154 RECT rect;
1155 int cx, cy;
1157 /* Try to load function from shell32 */
1158 hShell32 = LoadLibrary("shell32.dll");
1159 pSHGetImageList = (void*)GetProcAddress(hShell32, (LPCSTR) 727);
1161 if (!pSHGetImageList)
1163 win_skip("SHGetImageList not available, skipping test\n");
1164 return;
1167 /* Get system image list */
1168 hr = (pSHGetImageList)(SHIL_SYSSMALL, &IID_IImageList, (void**)&iml);
1170 ok(SUCCEEDED(hr), "SHGetImageList failed, hr=%x\n", hr);
1172 if (hr != S_OK)
1173 return;
1175 IImageList_GetImageCount(iml, &out);
1176 ok(out > 0, "IImageList_GetImageCount returned out <= 0\n");
1178 /* Fetch the small icon size */
1179 cx = GetSystemMetrics(SM_CXSMICON);
1180 cy = GetSystemMetrics(SM_CYSMICON);
1182 /* Check icon size matches */
1183 IImageList_GetImageRect(iml, 0, &rect);
1184 ok(((rect.right == cx) && (rect.bottom == cy)),
1185 "IImageList_GetImageRect returned r:%d,b:%d\n",
1186 rect.right, rect.bottom);
1188 IImageList_Release(iml);
1189 FreeLibrary(hShell32);
1192 static HBITMAP create_test_bitmap(HDC hdc, int bpp, UINT32 pixel1, UINT32 pixel2)
1194 HBITMAP hBitmap;
1195 UINT32 *buffer = NULL;
1196 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, bpp, BI_RGB,
1197 0, 0, 0, 0, 0}};
1199 hBitmap = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, NULL, 0);
1200 ok(hBitmap != NULL && buffer != NULL, "CreateDIBSection failed.\n");
1202 if(!hBitmap || !buffer)
1204 DeleteObject(hBitmap);
1205 return NULL;
1208 buffer[0] = pixel1;
1209 buffer[1] = pixel2;
1211 return hBitmap;
1214 static BOOL colour_match(UINT32 x, UINT32 y)
1216 const INT32 tolerance = 8;
1218 const INT32 dr = abs((INT32)(x & 0x000000FF) - (INT32)(y & 0x000000FF));
1219 const INT32 dg = abs((INT32)((x & 0x0000FF00) >> 8) - (INT32)((y & 0x0000FF00) >> 8));
1220 const INT32 db = abs((INT32)((x & 0x00FF0000) >> 16) - (INT32)((y & 0x00FF0000) >> 16));
1222 return (dr <= tolerance && dg <= tolerance && db <= tolerance);
1225 static void check_ImageList_DrawIndirect(IMAGELISTDRAWPARAMS *ildp, UINT32 *bits,
1226 UINT32 expected, int line)
1228 bits[0] = 0x00FFFFFF;
1229 pImageList_DrawIndirect(ildp);
1230 ok(colour_match(bits[0], expected),
1231 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1232 bits[0] & 0x00FFFFFF, expected, line);
1236 static void check_ImageList_DrawIndirect_fStyle(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1237 UINT fStyle, UINT32 expected, int line)
1239 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1240 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, ILS_NORMAL, 0, 0x00000000};
1241 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1244 static void check_ImageList_DrawIndirect_ILD_ROP(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1245 DWORD dwRop, UINT32 expected, int line)
1247 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1248 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_IMAGE | ILD_ROP, dwRop, ILS_NORMAL, 0, 0x00000000};
1249 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1252 static void check_ImageList_DrawIndirect_fState(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i, UINT fStyle,
1253 UINT fState, DWORD Frame, UINT32 expected, int line)
1255 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1256 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1257 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1260 static void check_ImageList_DrawIndirect_broken(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1261 UINT fStyle, UINT fState, DWORD Frame, UINT32 expected,
1262 UINT32 broken_expected, int line)
1264 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1265 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1266 bits[0] = 0x00FFFFFF;
1267 pImageList_DrawIndirect(&ildp);
1268 ok(colour_match(bits[0], expected) ||
1269 broken(colour_match(bits[0], broken_expected)),
1270 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1271 bits[0] & 0x00FFFFFF, expected, line);
1274 static void test_ImageList_DrawIndirect(void)
1276 HIMAGELIST himl = NULL;
1277 int ret;
1278 HDC hdcDst = NULL;
1279 HBITMAP hbmOld = NULL, hbmDst = NULL;
1280 HBITMAP hbmMask = NULL, hbmInverseMask = NULL;
1281 HBITMAP hbmImage = NULL, hbmAlphaImage = NULL, hbmTransparentImage = NULL;
1282 int iImage = -1, iAlphaImage = -1, iTransparentImage = -1;
1283 UINT32 *bits = 0;
1284 UINT32 maskBits = 0x00000000, inverseMaskBits = 0xFFFFFFFF;
1285 int bpp, broken_value;
1287 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB,
1288 0, 0, 0, 0, 0}};
1290 hdcDst = CreateCompatibleDC(0);
1291 ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
1292 if (!hdcDst)
1293 return;
1294 bpp = GetDeviceCaps(hdcDst, BITSPIXEL);
1296 hbmMask = CreateBitmap(2, 1, 1, 1, &maskBits);
1297 ok(hbmMask != 0, "CreateBitmap failed\n");
1298 if(!hbmMask) goto cleanup;
1300 hbmInverseMask = CreateBitmap(2, 1, 1, 1, &inverseMaskBits);
1301 ok(hbmInverseMask != 0, "CreateBitmap failed\n");
1302 if(!hbmInverseMask) goto cleanup;
1304 himl = pImageList_Create(2, 1, ILC_COLOR32, 0, 1);
1305 ok(himl != 0, "ImageList_Create failed\n");
1306 if(!himl) goto cleanup;
1308 /* Add a no-alpha image */
1309 hbmImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x00ABCDEF);
1310 if(!hbmImage) goto cleanup;
1312 iImage = pImageList_Add(himl, hbmImage, hbmMask);
1313 ok(iImage != -1, "ImageList_Add failed\n");
1314 if(iImage == -1) goto cleanup;
1316 /* Add an alpha image */
1317 hbmAlphaImage = create_test_bitmap(hdcDst, 32, 0x89ABCDEF, 0x89ABCDEF);
1318 if(!hbmAlphaImage) goto cleanup;
1320 iAlphaImage = pImageList_Add(himl, hbmAlphaImage, hbmMask);
1321 ok(iAlphaImage != -1, "ImageList_Add failed\n");
1322 if(iAlphaImage == -1) goto cleanup;
1324 /* Add a transparent alpha image */
1325 hbmTransparentImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x89ABCDEF);
1326 if(!hbmTransparentImage) goto cleanup;
1328 iTransparentImage = pImageList_Add(himl, hbmTransparentImage, hbmMask);
1329 ok(iTransparentImage != -1, "ImageList_Add failed\n");
1330 if(iTransparentImage == -1) goto cleanup;
1332 /* 32-bit Tests */
1333 bitmapInfo.bmiHeader.biBitCount = 32;
1334 hbmDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1335 ok (hbmDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1336 if (!hbmDst || !bits)
1337 goto cleanup;
1338 hbmOld = SelectObject(hdcDst, hbmDst);
1340 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_NORMAL, 0x00ABCDEF, __LINE__);
1341 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_TRANSPARENT, 0x00ABCDEF, __LINE__);
1342 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x00D4D9DD, __LINE__);
1343 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1344 else broken_value = 0x00B4BDC4;
1345 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1346 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_MASK, 0x00ABCDEF, __LINE__);
1347 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_IMAGE, 0x00ABCDEF, __LINE__);
1348 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_PRESERVEALPHA, 0x00ABCDEF, __LINE__);
1350 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, 0x00D3E5F7, __LINE__);
1351 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_TRANSPARENT, 0x00D3E5F7, __LINE__);
1353 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1354 else broken_value = 0x009DA8B1;
1355 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1356 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1357 else broken_value = 0x008C99A3;
1358 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1359 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0x00D3E5F7, __LINE__);
1360 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0x00D3E5F7, __LINE__);
1361 todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__);
1363 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__);
1365 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCCOPY, 0x00ABCDEF, __LINE__);
1366 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCINVERT, 0x00543210, __LINE__);
1368 /* ILD_ROP is ignored when the image has an alpha channel */
1369 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCCOPY, 0x00D3E5F7, __LINE__);
1370 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCINVERT, 0x00D3E5F7, __LINE__);
1372 todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00CCCCCC, __LINE__);
1373 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00AFAFAF, 0x00F0F0F0, __LINE__);
1375 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_GLOW, 0, 0x00ABCDEF, __LINE__);
1376 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SHADOW, 0, 0x00ABCDEF, __LINE__);
1378 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00D5E6F7, __LINE__);
1379 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00E9F2FB, 0x00AEB7C0, __LINE__);
1380 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_NORMAL, 127, 0x00E9F2FB, 0x00D3E5F7, __LINE__);
1382 cleanup:
1384 if(hbmOld)
1385 SelectObject(hdcDst, hbmOld);
1386 if(hbmDst)
1387 DeleteObject(hbmDst);
1389 if(hdcDst)
1390 DeleteDC(hdcDst);
1392 if(hbmMask)
1393 DeleteObject(hbmMask);
1394 if(hbmInverseMask)
1395 DeleteObject(hbmInverseMask);
1397 if(hbmImage)
1398 DeleteObject(hbmImage);
1399 if(hbmAlphaImage)
1400 DeleteObject(hbmAlphaImage);
1401 if(hbmTransparentImage)
1402 DeleteObject(hbmTransparentImage);
1404 if(himl)
1406 ret = ImageList_Destroy(himl);
1407 ok(ret, "ImageList_Destroy failed\n");
1411 static void test_iimagelist(void)
1413 IImageList *imgl, *imgl2;
1414 HIMAGELIST himl;
1415 HRESULT hr;
1416 ULONG ret;
1418 if (!pHIMAGELIST_QueryInterface)
1420 win_skip("XP imagelist functions not available\n");
1421 return;
1424 /* test reference counting on destruction */
1425 imgl = (IImageList*)createImageList(32, 32);
1426 ret = IUnknown_AddRef(imgl);
1427 ok(ret == 2, "Expected 2, got %d\n", ret);
1428 ret = ImageList_Destroy((HIMAGELIST)imgl);
1429 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1430 ret = ImageList_Destroy((HIMAGELIST)imgl);
1431 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1432 ret = ImageList_Destroy((HIMAGELIST)imgl);
1433 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1435 imgl = (IImageList*)createImageList(32, 32);
1436 ret = IUnknown_AddRef(imgl);
1437 ok(ret == 2, "Expected 2, got %d\n", ret);
1438 ret = ImageList_Destroy((HIMAGELIST)imgl);
1439 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1440 ret = IImageList_Release(imgl);
1441 ok(ret == 0, "Expected 0, got %d\n", ret);
1442 ret = ImageList_Destroy((HIMAGELIST)imgl);
1443 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1445 /* ref counting, HIMAGELIST_QueryInterface adds a reference */
1446 imgl = (IImageList*)createImageList(32, 32);
1447 hr = pHIMAGELIST_QueryInterface((HIMAGELIST)imgl, &IID_IImageList, (void**)&imgl2);
1448 ok(hr == S_OK, "got 0x%08x\n", hr);
1449 ok(imgl2 == imgl, "got different pointer\n");
1450 ret = IImageList_Release(imgl);
1451 ok(ret == 1, "got %u\n", ret);
1452 IImageList_Release(imgl);
1454 if (!pImageList_CoCreateInstance)
1456 win_skip("Vista imagelist functions not available\n");
1457 return;
1460 hr = pImageList_CoCreateInstance(&CLSID_ImageList, NULL, &IID_IImageList, (void **) &imgl);
1461 ok(SUCCEEDED(hr), "ImageList_CoCreateInstance failed, hr=%x\n", hr);
1463 if (hr == S_OK)
1464 IImageList_Release(imgl);
1466 himl = createImageList(32, 32);
1468 if (!himl)
1469 return;
1471 hr = (pHIMAGELIST_QueryInterface)(himl, &IID_IImageList, (void **) &imgl);
1472 ok(SUCCEEDED(hr), "HIMAGELIST_QueryInterface failed, hr=%x\n", hr);
1474 if (hr == S_OK)
1475 IImageList_Release(imgl);
1477 ImageList_Destroy(himl);
1480 static void test_hotspot_v6(void)
1482 struct hotspot {
1483 int dx;
1484 int dy;
1487 #define SIZEX1 47
1488 #define SIZEY1 31
1489 #define SIZEX2 11
1490 #define SIZEY2 17
1491 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
1492 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
1493 { 10, 7 },
1494 { SIZEX1, SIZEY1 },
1495 { -9, -8 },
1496 { -7, 35 }
1498 int i, j;
1499 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
1500 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
1501 IImageList *imgl1, *imgl2;
1502 HRESULT hr;
1504 /* cast to IImageList */
1505 imgl1 = (IImageList *) himl1;
1506 imgl2 = (IImageList *) himl2;
1508 for (i = 0; i < HOTSPOTS_MAX; i++) {
1509 for (j = 0; j < HOTSPOTS_MAX; j++) {
1510 int dx1 = hotspots[i].dx;
1511 int dy1 = hotspots[i].dy;
1512 int dx2 = hotspots[j].dx;
1513 int dy2 = hotspots[j].dy;
1514 int correctx, correcty, newx, newy;
1515 char loc[256];
1516 IImageList *imglNew;
1517 POINT ppt;
1519 hr = IImageList_BeginDrag(imgl1, 0, dx1, dy1);
1520 ok(SUCCEEDED(hr), "BeginDrag failed for { %d, %d }\n", dx1, dy1);
1521 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
1523 /* check merging the dragged image with a second image */
1524 hr = IImageList_SetDragCursorImage(imgl2, (IUnknown *) imgl2, 0, dx2, dy2);
1525 ok(SUCCEEDED(hr), "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
1526 dx1, dy1, dx2, dy2);
1527 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
1529 /* check new hotspot, it should be the same like the old one */
1530 hr = IImageList_GetDragImage(imgl2, NULL, &ppt, &IID_IImageList, (PVOID *) &imglNew);
1531 ok(SUCCEEDED(hr), "GetDragImage failed\n");
1532 ok(ppt.x == dx1 && ppt.y == dy1,
1533 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
1534 dx1, dy1, ppt.x, ppt.y);
1535 /* check size of new dragged image */
1536 IImageList_GetIconSize(imglNew, &newx, &newy);
1537 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
1538 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
1539 ok(newx == correctx && newy == correcty,
1540 "Expected drag image size [%d,%d] got [%d,%d]\n",
1541 correctx, correcty, newx, newy);
1542 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
1543 IImageList_EndDrag(imgl2);
1546 #undef SIZEX1
1547 #undef SIZEY1
1548 #undef SIZEX2
1549 #undef SIZEY2
1550 #undef HOTSPOTS_MAX
1551 IImageList_Release(imgl2);
1552 IImageList_Release(imgl1);
1555 static void test_IImageList_Add_Remove(void)
1557 IImageList *imgl;
1558 HIMAGELIST himl;
1559 HRESULT hr;
1561 HICON hicon1;
1562 HICON hicon2;
1563 HICON hicon3;
1565 int ret;
1567 /* create an imagelist to play with */
1568 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1569 ok(himl != 0,"failed to create imagelist\n");
1571 imgl = (IImageList *) himl;
1573 /* load the icons to add to the image list */
1574 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1575 ok(hicon1 != 0, "no hicon1\n");
1576 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1577 ok(hicon2 != 0, "no hicon2\n");
1578 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1579 ok(hicon3 != 0, "no hicon3\n");
1581 /* remove when nothing exists */
1582 hr = IImageList_Remove(imgl, 0);
1583 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1585 /* removing everything from an empty imagelist should succeed */
1586 hr = IImageList_Remove(imgl, -1);
1587 ok(hr == S_OK, "removed nonexistent icon\n");
1589 /* add three */
1590 ret = -1;
1591 ok( IImageList_ReplaceIcon(imgl, -1, hicon1, &ret) == S_OK && (ret == 0),"failed to add icon1\n");
1592 ret = -1;
1593 ok( IImageList_ReplaceIcon(imgl, -1, hicon2, &ret) == S_OK && (ret == 1),"failed to add icon2\n");
1594 ret = -1;
1595 ok( IImageList_ReplaceIcon(imgl, -1, hicon3, &ret) == S_OK && (ret == 2),"failed to add icon3\n");
1597 /* remove an index out of range */
1598 ok( IImageList_Remove(imgl, 4711) == E_INVALIDARG, "got 0x%08x\n", hr);
1600 /* remove three */
1601 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1602 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1603 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1605 /* remove one extra */
1606 ok( IImageList_Remove(imgl, 0) == E_INVALIDARG, "got 0x%08x\n", hr);
1608 IImageList_Release(imgl);
1609 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
1610 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
1611 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
1614 static void test_IImageList_Get_SetImageCount(void)
1616 IImageList *imgl;
1617 HIMAGELIST himl;
1618 HRESULT hr;
1619 INT ret;
1621 /* create an imagelist to play with */
1622 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1623 ok(himl != 0,"failed to create imagelist\n");
1625 imgl = (IImageList *) himl;
1627 /* check SetImageCount/GetImageCount */
1628 hr = IImageList_SetImageCount(imgl, 3);
1629 ok(hr == S_OK, "got 0x%08x\n", hr);
1630 ret = 0;
1631 hr = IImageList_GetImageCount(imgl, &ret);
1632 ok(hr == S_OK && ret == 3, "invalid image count after increase\n");
1633 hr = IImageList_SetImageCount(imgl, 1);
1634 ok(hr == S_OK, "got 0x%08x\n", hr);
1635 ret = 0;
1636 hr = IImageList_GetImageCount(imgl, &ret);
1637 ok(hr == S_OK && ret == 1, "invalid image count after decrease to 1\n");
1638 hr = IImageList_SetImageCount(imgl, 0);
1639 ok(hr == S_OK, "got 0x%08x\n", hr);
1640 ret = -1;
1641 hr = IImageList_GetImageCount(imgl, &ret);
1642 ok(hr == S_OK && ret == 0, "invalid image count after decrease to 0\n");
1644 IImageList_Release(imgl);
1647 static void test_IImageList_Draw(void)
1649 IImageList *imgl;
1650 HIMAGELIST himl;
1652 HBITMAP hbm1;
1653 HBITMAP hbm2;
1654 HBITMAP hbm3;
1656 IMAGELISTDRAWPARAMS imldp;
1657 HWND hwndfortest;
1658 HRESULT hr;
1659 HDC hdc;
1660 int ret;
1662 hwndfortest = create_a_window();
1663 hdc = GetDC(hwndfortest);
1664 ok(hdc!=NULL, "couldn't get DC\n");
1666 /* create an imagelist to play with */
1667 himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
1668 ok(himl!=0,"failed to create imagelist\n");
1670 imgl = (IImageList *) himl;
1672 /* load the icons to add to the image list */
1673 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1674 ok(hbm1 != 0, "no bitmap 1\n");
1675 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1676 ok(hbm2 != 0, "no bitmap 2\n");
1677 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1678 ok(hbm3 != 0, "no bitmap 3\n");
1680 /* add three */
1681 ret = -1;
1682 ok( IImageList_Add(imgl, hbm1, 0, &ret) == S_OK && (ret == 0), "failed to add bitmap 1\n");
1683 ret = -1;
1684 ok( IImageList_Add(imgl, hbm2, 0, &ret) == S_OK && (ret == 1), "failed to add bitmap 2\n");
1686 ok( IImageList_SetImageCount(imgl, 3) == S_OK, "Setimage count failed\n");
1687 ok( IImageList_Replace(imgl, 2, hbm3, 0) == S_OK, "failed to replace bitmap 3\n");
1689 if (0)
1691 /* crashes on native */
1692 IImageList_Draw(imgl, NULL);
1695 memset(&imldp, 0, sizeof (imldp));
1696 hr = IImageList_Draw(imgl, &imldp);
1697 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
1699 imldp.cbSize = IMAGELISTDRAWPARAMS_V3_SIZE;
1700 imldp.hdcDst = hdc;
1701 imldp.himl = himl;
1703 REDRAW(hwndfortest);
1704 WAIT;
1706 imldp.fStyle = SRCCOPY;
1707 imldp.rgbBk = CLR_DEFAULT;
1708 imldp.rgbFg = CLR_DEFAULT;
1709 imldp.y = 100;
1710 imldp.x = 100;
1711 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1712 imldp.i ++;
1713 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1714 imldp.i ++;
1715 ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n");
1716 imldp.i ++;
1717 ok( IImageList_Draw(imgl, &imldp) == E_INVALIDARG, "should fail\n");
1719 /* remove three */
1720 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 1st bitmap\n");
1721 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 2nd bitmap\n");
1722 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 3rd bitmap\n");
1724 /* destroy it */
1725 IImageList_Release(imgl);
1727 /* bitmaps should not be deleted by the imagelist */
1728 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
1729 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
1730 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
1732 ReleaseDC(hwndfortest, hdc);
1733 DestroyWindow(hwndfortest);
1736 static void test_IImageList_Merge(void)
1738 HIMAGELIST himl1, himl2;
1739 IImageList *imgl1, *imgl2, *merge;
1740 HICON hicon1;
1741 HWND hwnd = create_a_window();
1742 HRESULT hr;
1743 int ret;
1745 himl1 = ImageList_Create(32,32,0,0,3);
1746 ok(himl1 != NULL,"failed to create himl1\n");
1748 himl2 = ImageList_Create(32,32,0,0,3);
1749 ok(himl2 != NULL,"failed to create himl2\n");
1751 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1752 ok(hicon1 != NULL, "failed to create hicon1\n");
1754 if (!himl1 || !himl2 || !hicon1)
1755 return;
1757 /* cast to IImageList */
1758 imgl1 = (IImageList *) himl1;
1759 imgl2 = (IImageList *) himl2;
1761 ret = -1;
1762 ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (ret == 0),"add icon1 to himl2 failed\n");
1764 if (0)
1766 /* null cases that crash on native */
1767 IImageList_Merge(imgl1, -1, NULL, 0, 0, 0, &IID_IImageList, (void**)&merge);
1768 IImageList_Merge(imgl1, -1, (IUnknown*) imgl2, 0, 0, 0, &IID_IImageList, NULL);
1771 /* If himl1 has no images, merge still succeeds */
1772 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1773 ok(hr == S_OK, "merge himl1,-1 failed\n");
1774 if (hr == S_OK) IImageList_Release(merge);
1776 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1777 ok(hr == S_OK, "merge himl1,0 failed\n");
1778 if (hr == S_OK) IImageList_Release(merge);
1780 /* Same happens if himl2 is empty */
1781 IImageList_Release(imgl2);
1782 himl2 = ImageList_Create(32,32,0,0,3);
1783 ok(himl2 != NULL,"failed to recreate himl2\n");
1785 imgl2 = (IImageList *) himl2;
1787 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, -1, 0, 0, &IID_IImageList, (void **) &merge);
1788 ok(hr == S_OK, "merge himl2,-1 failed\n");
1789 if (hr == S_OK) IImageList_Release(merge);
1791 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1792 ok(hr == S_OK, "merge himl2,0 failed\n");
1793 if (hr == S_OK) IImageList_Release(merge);
1795 /* Now try merging an image with itself */
1796 ret = -1;
1797 ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (ret == 0),"re-add icon1 to himl2 failed\n");
1799 hr = IImageList_Merge(imgl2, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1800 ok(hr == S_OK, "merge himl2 with itself failed\n");
1801 if (hr == S_OK) IImageList_Release(merge);
1803 /* Try merging 2 different image lists */
1804 ret = -1;
1805 ok( IImageList_ReplaceIcon(imgl1, -1, hicon1, &ret) == S_OK && (ret == 0),"add icon1 to himl1 failed\n");
1807 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1808 ok(hr == S_OK, "merge himl1 with himl2 failed\n");
1809 if (hr == S_OK) IImageList_Release(merge);
1811 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 8, 16, &IID_IImageList, (void **) &merge);
1812 ok(hr == S_OK, "merge himl1 with himl2 8,16 failed\n");
1813 if (hr == S_OK) IImageList_Release(merge);
1815 IImageList_Release(imgl1);
1816 IImageList_Release(imgl2);
1818 DestroyIcon(hicon1);
1819 DestroyWindow(hwnd);
1822 static void test_iconsize(void)
1824 HIMAGELIST himl;
1825 INT cx, cy;
1826 BOOL ret;
1828 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1829 /* null pointers, not zero imagelist dimensions */
1830 ret = ImageList_GetIconSize(himl, NULL, NULL);
1831 ok(!ret, "got %d\n", ret);
1833 /* doesn't touch return pointers */
1834 cx = 0x1abe11ed;
1835 ret = ImageList_GetIconSize(himl, &cx, NULL);
1836 ok(!ret, "got %d\n", ret);
1837 ok(cx == 0x1abe11ed, "got %d\n", cx);
1839 cy = 0x1abe11ed;
1840 ret = ImageList_GetIconSize(himl, NULL, &cy);
1841 ok(!ret, "got %d\n", ret);
1842 ok(cy == 0x1abe11ed, "got %d\n", cy);
1844 ImageList_Destroy(himl);
1846 ret = ImageList_GetIconSize((HIMAGELIST)0xdeadbeef, &cx, &cy);
1847 ok(!ret, "got %d\n", ret);
1850 static void test_create_destroy(void)
1852 HIMAGELIST himl;
1853 BOOL rc;
1855 /* list with zero or negative image dimensions */
1856 himl = ImageList_Create(0, 0, ILC_COLOR16, 0, 3);
1857 ok(himl == NULL, "got %p\n", himl);
1859 himl = ImageList_Create(0, 16, ILC_COLOR16, 0, 3);
1860 ok(himl == NULL, "got %p\n", himl);
1862 himl = ImageList_Create(16, 0, ILC_COLOR16, 0, 3);
1863 ok(himl == NULL, "got %p\n", himl);
1865 himl = ImageList_Create(16, -1, ILC_COLOR16, 0, 3);
1866 ok(himl == NULL, "got %p\n", himl);
1868 himl = ImageList_Create(-1, 16, ILC_COLOR16, 0, 3);
1869 ok(himl == NULL, "got %p\n", himl);
1871 rc = ImageList_Destroy((HIMAGELIST)0xdeadbeef);
1872 ok(rc == FALSE, "ImageList_Destroy(0xdeadbeef) should fail and not crash\n");
1875 static void test_IImageList_Clone(void)
1877 IImageList *imgl, *imgl2;
1878 HIMAGELIST himl;
1879 HRESULT hr;
1880 ULONG ref;
1882 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1883 imgl = (IImageList*)himl;
1885 if (0)
1887 /* crashes on native */
1888 IImageList_Clone(imgl, &IID_IImageList, NULL);
1891 hr = IImageList_Clone(imgl, &IID_IImageList, (void**)&imgl2);
1892 ok(hr == S_OK, "got 0x%08x\n", hr);
1893 ref = IImageList_Release(imgl2);
1894 ok(ref == 0, "got %u\n", ref);
1896 IImageList_Release(imgl);
1899 static void test_IImageList_GetBkColor(void)
1901 IImageList *imgl;
1902 HIMAGELIST himl;
1903 COLORREF color;
1904 HRESULT hr;
1906 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1907 imgl = (IImageList*)himl;
1909 if (0)
1911 /* crashes on native */
1912 IImageList_GetBkColor(imgl, NULL);
1915 hr = IImageList_GetBkColor(imgl, &color);
1916 ok(hr == S_OK, "got 0x%08x\n", hr);
1918 IImageList_Release(imgl);
1921 static void test_IImageList_SetBkColor(void)
1923 IImageList *imgl;
1924 HIMAGELIST himl;
1925 COLORREF color;
1926 HRESULT hr;
1928 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1929 imgl = (IImageList*)himl;
1931 if (0)
1933 /* crashes on native */
1934 IImageList_SetBkColor(imgl, RGB(0, 0, 0), NULL);
1937 hr = IImageList_SetBkColor(imgl, CLR_NONE, &color);
1938 ok(hr == S_OK, "got 0x%08x\n", hr);
1940 hr = IImageList_SetBkColor(imgl, CLR_NONE, &color);
1941 ok(hr == S_OK, "got 0x%08x\n", hr);
1943 color = 0xdeadbeef;
1944 hr = IImageList_GetBkColor(imgl, &color);
1945 ok(hr == S_OK, "got 0x%08x\n", hr);
1946 ok(color == CLR_NONE, "got %x\n", color);
1948 IImageList_Release(imgl);
1951 static void test_IImageList_GetImageCount(void)
1953 IImageList *imgl;
1954 HIMAGELIST himl;
1955 int count;
1956 HRESULT hr;
1958 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1959 imgl = (IImageList*)himl;
1961 if (0)
1963 /* crashes on native */
1964 IImageList_GetImageCount(imgl, NULL);
1967 count = -1;
1968 hr = IImageList_GetImageCount(imgl, &count);
1969 ok(hr == S_OK, "got 0x%08x\n", hr);
1970 ok(count == 0, "got %d\n", count);
1972 IImageList_Release(imgl);
1975 static void test_IImageList_GetIconSize(void)
1977 IImageList *imgl;
1978 HIMAGELIST himl;
1979 int cx, cy;
1980 HRESULT hr;
1982 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1983 imgl = (IImageList*)himl;
1985 hr = IImageList_GetIconSize(imgl, NULL, NULL);
1986 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1988 hr = IImageList_GetIconSize(imgl, &cx, NULL);
1989 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1991 hr = IImageList_GetIconSize(imgl, NULL, &cy);
1992 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1994 IImageList_Release(imgl);
1997 START_TEST(imagelist)
1999 ULONG_PTR ctx_cookie;
2000 HANDLE hCtx;
2002 HMODULE hComCtl32 = GetModuleHandle("comctl32.dll");
2003 pImageList_Create = NULL; /* These are not needed for non-v6.0 tests*/
2004 pImageList_Add = NULL;
2005 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
2006 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
2008 hinst = GetModuleHandleA(NULL);
2010 InitCommonControls();
2012 test_create_destroy();
2013 test_hotspot();
2014 test_add_remove();
2015 test_imagecount();
2016 test_DrawIndirect();
2017 test_merge();
2018 test_imagelist_storage();
2019 test_iconsize();
2021 FreeLibrary(hComCtl32);
2023 /* Now perform v6 tests */
2025 if (!load_v6_module(&ctx_cookie, &hCtx))
2026 return;
2028 /* Reload comctl32 */
2029 hComCtl32 = LoadLibraryA("comctl32.dll");
2030 pImageList_Create = (void*)GetProcAddress(hComCtl32, "ImageList_Create");
2031 pImageList_Add = (void*)GetProcAddress(hComCtl32, "ImageList_Add");
2032 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
2033 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
2034 pImageList_CoCreateInstance = (void*)GetProcAddress(hComCtl32, "ImageList_CoCreateInstance");
2035 pHIMAGELIST_QueryInterface = (void*)GetProcAddress(hComCtl32, "HIMAGELIST_QueryInterface");
2037 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
2039 /* Do v6.0 tests */
2040 test_ImageList_DrawIndirect();
2041 test_shell_imagelist();
2042 test_iimagelist();
2044 test_hotspot_v6();
2045 test_IImageList_Add_Remove();
2046 test_IImageList_Get_SetImageCount();
2047 test_IImageList_Draw();
2048 test_IImageList_Merge();
2049 test_IImageList_Clone();
2050 test_IImageList_GetBkColor();
2051 test_IImageList_SetBkColor();
2052 test_IImageList_GetImageCount();
2053 test_IImageList_GetIconSize();
2055 CoUninitialize();
2057 unload_v6_module(ctx_cookie, hCtx);