usp10: Free default_language items when freeing script cache.
[wine.git] / dlls / comctl32 / tests / imagelist.c
blob19d24379517153af1b249525c18b334743ec13be
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 != NULL;
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 BITMAPINFO bmi;
786 HBITMAP hbmp, hbmp_old;
787 HBRUSH hbrush;
788 RECT rc = { 0, 0, cx, cy };
790 hdc = CreateCompatibleDC(0);
792 memset(&bmi, 0, sizeof(bmi));
793 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
794 bmi.bmiHeader.biHeight = cx;
795 bmi.bmiHeader.biWidth = cy;
796 bmi.bmiHeader.biBitCount = 24;
797 bmi.bmiHeader.biPlanes = 1;
798 bmi.bmiHeader.biCompression = BI_RGB;
799 hbmp = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
801 hbmp_old = SelectObject(hdc, hbmp);
803 hbrush = CreateSolidBrush(color);
804 FillRect(hdc, &rc, hbrush);
805 DeleteObject(hbrush);
807 DrawText(hdc, comment, -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
809 SelectObject(hdc, hbmp_old);
810 DeleteDC(hdc);
812 return hbmp;
815 #define iml_clear_stream_data() \
816 HeapFree(GetProcessHeap(), 0, Test_Stream.iml_data); \
817 Test_Stream.iml_data = NULL; \
818 Test_Stream.iml_data_size = 0;
820 static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max, INT grow,
821 INT width, INT height, INT flags, const char *comment)
823 INT ret, cxx, cyy, size;
825 trace("%s\n", comment);
827 ret = ImageList_GetImageCount(himl);
828 ok(ret == cur, "expected image count %d got %d\n", cur, ret);
830 ret = ImageList_GetIconSize(himl, &cxx, &cyy);
831 ok(ret, "ImageList_GetIconSize failed\n");
832 ok(cxx == cx, "wrong cx %d (expected %d)\n", cxx, cx);
833 ok(cyy == cy, "wrong cy %d (expected %d)\n", cyy, cy);
835 iml_clear_stream_data();
836 ret = ImageList_Write(himl, &Test_Stream.IStream_iface);
837 ok(ret, "ImageList_Write failed\n");
839 ok(Test_Stream.iml_data != 0, "ImageList_Write didn't write any data\n");
840 ok(Test_Stream.iml_data_size > sizeof(ILHEAD), "ImageList_Write wrote not enough data\n");
842 check_ilhead_data(Test_Stream.iml_data, cx, cy, cur, max, grow, flags);
843 size = check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD),
844 Test_Stream.iml_data_size - sizeof(ILHEAD),
845 width, height, flags & 0xfe, comment);
846 if (size < Test_Stream.iml_data_size - sizeof(ILHEAD)) /* mask is present */
848 ok( flags & ILC_MASK, "extra data %u/%u but mask not expected\n",
849 Test_Stream.iml_data_size, size );
850 check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD) + size,
851 Test_Stream.iml_data_size - sizeof(ILHEAD) - size,
852 width, height, 1, comment);
856 static void image_list_init(HIMAGELIST himl)
858 HBITMAP hbm;
859 char comment[16];
860 INT n = 1;
861 DWORD i;
862 static const struct test_data
864 BYTE grey;
865 INT cx, cy, cur, max, grow, width, height, bpp;
866 const char *comment;
867 } td[] =
869 { 255, BMP_CX, BMP_CX, 1, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "total 1" },
870 { 170, BMP_CX, BMP_CX, 2, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 2" },
871 { 85, BMP_CX, BMP_CX, 3, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 3" },
872 { 0, BMP_CX, BMP_CX, 4, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 4" },
873 { 0, BMP_CX, BMP_CX, 5, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 5" },
874 { 85, BMP_CX, BMP_CX, 6, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 6" },
875 { 170, BMP_CX, BMP_CX, 7, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 7" },
876 { 255, BMP_CX, BMP_CX, 8, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 8" },
877 { 255, BMP_CX, BMP_CX, 9, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 9" },
878 { 170, BMP_CX, BMP_CX, 10, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 10" },
879 { 85, BMP_CX, BMP_CX, 11, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 11" },
880 { 0, BMP_CX, BMP_CX, 12, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 12" },
881 { 0, BMP_CX, BMP_CX, 13, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 13" },
882 { 85, BMP_CX, BMP_CX, 14, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 14" },
883 { 170, BMP_CX, BMP_CX, 15, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 15" },
884 { 255, BMP_CX, BMP_CX, 16, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 16" },
885 { 255, BMP_CX, BMP_CX, 17, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 17" },
886 { 170, BMP_CX, BMP_CX, 18, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 18" },
887 { 85, BMP_CX, BMP_CX, 19, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 19" },
888 { 0, BMP_CX, BMP_CX, 20, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 20" },
889 { 0, BMP_CX, BMP_CX, 21, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 21" },
890 { 85, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 22" },
891 { 170, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 23" },
892 { 255, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 24" }
895 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "total 0");
897 #define add_bitmap(grey) \
898 sprintf(comment, "%d", n++); \
899 hbm = create_bitmap(BMP_CX, BMP_CX, RGB((grey),(grey),(grey)), comment); \
900 ImageList_Add(himl, hbm, NULL); \
901 DeleteObject(hbm);
903 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
905 add_bitmap(td[i].grey);
906 check_iml_data(himl, td[i].cx, td[i].cy, td[i].cur, td[i].max, td[i].grow,
907 td[i].width, td[i].height, td[i].bpp, td[i].comment);
909 #undef add_bitmap
912 static void test_imagelist_storage(void)
914 HIMAGELIST himl;
915 HBITMAP hbm;
916 HICON icon;
917 INT ret;
919 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 1, 1);
920 ok(himl != 0, "ImageList_Create failed\n");
922 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "empty");
924 image_list_init(himl);
925 check_iml_data(himl, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "orig");
927 ret = ImageList_Remove(himl, 4);
928 ok(ret, "ImageList_Remove failed\n");
929 check_iml_data(himl, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "1");
931 ret = ImageList_Remove(himl, 5);
932 ok(ret, "ImageList_Remove failed\n");
933 check_iml_data(himl, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "2");
935 ret = ImageList_Remove(himl, 6);
936 ok(ret, "ImageList_Remove failed\n");
937 check_iml_data(himl, BMP_CX, BMP_CX, 21, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "3");
939 ret = ImageList_Remove(himl, 7);
940 ok(ret, "ImageList_Remove failed\n");
941 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "4");
943 ret = ImageList_Remove(himl, -2);
944 ok(!ret, "ImageList_Remove(-2) should fail\n");
945 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "5");
947 ret = ImageList_Remove(himl, 20);
948 ok(!ret, "ImageList_Remove(20) should fail\n");
949 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "6");
951 ret = ImageList_Remove(himl, -1);
952 ok(ret, "ImageList_Remove(-1) failed\n");
953 check_iml_data(himl, BMP_CX, BMP_CX, 0, 4, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "7");
955 ret = ImageList_Destroy(himl);
956 ok(ret, "ImageList_Destroy failed\n");
958 iml_clear_stream_data();
960 /* test ImageList_Create storage allocation */
962 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 0, 32);
963 ok(himl != 0, "ImageList_Create failed\n");
964 check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 32, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "init 0 grow 32");
965 hbm = create_bitmap(BMP_CX * 9, BMP_CX, 0, "9");
966 ret = ImageList_Add(himl, hbm, NULL);
967 ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
968 check_iml_data(himl, BMP_CX, BMP_CX, 1, 34, 32, BMP_CX * 4, BMP_CX * 9, ILC_COLOR24, "add 1 x 9");
969 DeleteObject(hbm);
970 ret = ImageList_Destroy(himl);
971 ok(ret, "ImageList_Destroy failed\n");
972 iml_clear_stream_data();
974 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 4);
975 ok(himl != 0, "ImageList_Create failed\n");
976 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24, "init 4 grow 4");
977 hbm = create_bitmap(BMP_CX, BMP_CX * 9, 0, "9");
978 ret = ImageList_Add(himl, hbm, NULL);
979 ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
980 check_iml_data(himl, BMP_CX, BMP_CX, 9, 15, 4, BMP_CX * 4, BMP_CX * 4, ILC_COLOR24, "add 9 x 1");
981 ret = ImageList_Add(himl, hbm, NULL);
982 ok(ret == 9, "ImageList_Add returned %d, expected 9\n", ret);
983 check_iml_data(himl, BMP_CX, BMP_CX, 18, 25, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "add 9 x 1");
984 DeleteObject(hbm);
985 ret = ImageList_Destroy(himl);
986 ok(ret, "ImageList_Destroy failed\n");
987 iml_clear_stream_data();
989 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 207, 209);
990 ok(himl != 0, "ImageList_Create failed\n");
991 check_iml_data(himl, BMP_CX, BMP_CX, 0, 208, 212, BMP_CX * 4, BMP_CX * 52, ILC_COLOR24, "init 207 grow 209");
992 ret = ImageList_Destroy(himl);
993 ok(ret, "ImageList_Destroy failed\n");
994 iml_clear_stream_data();
996 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 209, 207);
997 ok(himl != 0, "ImageList_Create failed\n");
998 check_iml_data(himl, BMP_CX, BMP_CX, 0, 210, 208, BMP_CX * 4, BMP_CX * 53, ILC_COLOR24, "init 209 grow 207");
999 ret = ImageList_Destroy(himl);
1000 ok(ret, "ImageList_Destroy failed\n");
1001 iml_clear_stream_data();
1003 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 14, 4);
1004 ok(himl != 0, "ImageList_Create failed\n");
1005 check_iml_data(himl, BMP_CX, BMP_CX, 0, 15, 4, BMP_CX * 4, BMP_CX * 4, ILC_COLOR24, "init 14 grow 4");
1006 ret = ImageList_Destroy(himl);
1007 ok(ret, "ImageList_Destroy failed\n");
1008 iml_clear_stream_data();
1010 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 5, 9);
1011 ok(himl != 0, "ImageList_Create failed\n");
1012 check_iml_data(himl, BMP_CX, BMP_CX, 0, 6, 12, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24, "init 5 grow 9");
1013 ret = ImageList_Destroy(himl);
1014 ok(ret, "ImageList_Destroy failed\n");
1015 iml_clear_stream_data();
1017 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 9, 5);
1018 ok(himl != 0, "ImageList_Create failed\n");
1019 check_iml_data(himl, BMP_CX, BMP_CX, 0, 10, 8, BMP_CX * 4, BMP_CX * 3, ILC_COLOR24, "init 9 grow 5");
1020 ret = ImageList_Destroy(himl);
1021 ok(ret, "ImageList_Destroy failed\n");
1022 iml_clear_stream_data();
1024 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 2, 4);
1025 ok(himl != 0, "ImageList_Create failed\n");
1026 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "init 2 grow 4");
1027 ret = ImageList_Destroy(himl);
1028 ok(ret, "ImageList_Destroy failed\n");
1029 iml_clear_stream_data();
1031 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 2);
1032 ok(himl != 0, "ImageList_Create failed\n");
1033 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24, "init 4 grow 2");
1034 ret = ImageList_Destroy(himl);
1035 ok(ret, "ImageList_Destroy failed\n");
1036 iml_clear_stream_data();
1038 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR8, 4, 2);
1039 ok(himl != 0, "ImageList_Create failed\n");
1040 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR8, "bpp 8");
1041 ret = ImageList_Destroy(himl);
1042 ok(ret, "ImageList_Destroy failed\n");
1043 iml_clear_stream_data();
1045 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4, 4, 2);
1046 ok(himl != 0, "ImageList_Create failed\n");
1047 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4, "bpp 4");
1048 ret = ImageList_Destroy(himl);
1049 ok(ret, "ImageList_Destroy failed\n");
1050 iml_clear_stream_data();
1052 himl = ImageList_Create(BMP_CX, BMP_CX, 0, 4, 2);
1053 ok(himl != 0, "ImageList_Create failed\n");
1054 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4, "bpp default");
1055 icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1056 ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n");
1057 ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n");
1058 DestroyIcon( icon );
1059 check_iml_data(himl, BMP_CX, BMP_CX, 2, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4, "bpp default");
1060 ret = ImageList_Destroy(himl);
1061 ok(ret, "ImageList_Destroy failed\n");
1062 iml_clear_stream_data();
1064 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24|ILC_MASK, 4, 2);
1065 ok(himl != 0, "ImageList_Create failed\n");
1066 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24|ILC_MASK,
1067 "bpp 24 + mask");
1068 icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1069 ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n");
1070 ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n");
1071 DestroyIcon( icon );
1072 check_iml_data(himl, BMP_CX, BMP_CX, 2, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24|ILC_MASK,
1073 "bpp 24 + mask");
1074 ret = ImageList_Destroy(himl);
1075 ok(ret, "ImageList_Destroy failed\n");
1076 iml_clear_stream_data();
1078 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 4, 2);
1079 ok(himl != 0, "ImageList_Create failed\n");
1080 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4|ILC_MASK,
1081 "bpp 4 + mask");
1082 icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1083 ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n");
1084 ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n");
1085 DestroyIcon( icon );
1086 check_iml_data(himl, BMP_CX, BMP_CX, 2, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4|ILC_MASK,
1087 "bpp 4 + mask");
1088 ret = ImageList_Destroy(himl);
1089 ok(ret, "ImageList_Destroy failed\n");
1090 iml_clear_stream_data();
1092 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 99);
1093 ok(himl != 0, "ImageList_Create failed\n");
1094 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1095 "init 2 grow 99");
1096 icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1097 ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n");
1098 ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n");
1099 check_iml_data(himl, BMP_CX, BMP_CX, 2, 3, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1100 "init 2 grow 99 2 icons");
1101 ok( ImageList_AddIcon(himl, icon) == 2,"failed to add icon\n");
1102 DestroyIcon( icon );
1103 check_iml_data(himl, BMP_CX, BMP_CX, 3, 104, 100, BMP_CX * 4, BMP_CX * 104/4, ILC_COLOR4|ILC_MASK,
1104 "init 2 grow 99 3 icons");
1105 ok( ImageList_Remove(himl, -1) == TRUE,"failed to remove icon\n");
1106 check_iml_data(himl, BMP_CX, BMP_CX, 0, 100, 100, BMP_CX * 4, BMP_CX * 100/4, ILC_COLOR4|ILC_MASK,
1107 "init 2 grow 99 empty");
1108 ok( ImageList_SetImageCount(himl, 22) == TRUE,"failed to set image count\n");
1109 check_iml_data(himl, BMP_CX, BMP_CX, 22, 23, 100, BMP_CX * 4, BMP_CX * 24/4, ILC_COLOR4|ILC_MASK,
1110 "init 2 grow 99 set count 22");
1111 ok( ImageList_SetImageCount(himl, 0) == TRUE,"failed to set image count\n");
1112 check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1113 "init 2 grow 99 set count 0");
1114 ok( ImageList_SetImageCount(himl, 42) == TRUE,"failed to set image count\n");
1115 check_iml_data(himl, BMP_CX, BMP_CX, 42, 43, 100, BMP_CX * 4, BMP_CX * 44/4, ILC_COLOR4|ILC_MASK,
1116 "init 2 grow 99 set count 42");
1117 ret = ImageList_Destroy(himl);
1118 ok(ret, "ImageList_Destroy failed\n");
1119 iml_clear_stream_data();
1121 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 65536+12);
1122 ok(himl != 0, "ImageList_Create failed\n");
1123 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 12, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1124 "init 2 grow 65536+12");
1125 ret = ImageList_Destroy(himl);
1126 ok(ret, "ImageList_Destroy failed\n");
1127 iml_clear_stream_data();
1129 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 65535);
1130 ok(himl != 0, "ImageList_Create failed\n");
1131 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 0, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1132 "init 2 grow 65535");
1133 ret = ImageList_Destroy(himl);
1134 ok(ret, "ImageList_Destroy failed\n");
1135 iml_clear_stream_data();
1137 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, -20);
1138 ok(himl != 0, "ImageList_Create failed\n");
1139 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK,
1140 "init 2 grow -20");
1141 ret = ImageList_Destroy(himl);
1142 ok(ret, "ImageList_Destroy failed\n");
1143 iml_clear_stream_data();
1146 static void test_shell_imagelist(void)
1148 BOOL (WINAPI *pSHGetImageList)(INT, REFIID, void**);
1149 IImageList *iml = NULL;
1150 HMODULE hShell32;
1151 HRESULT hr;
1152 int out = 0;
1153 RECT rect;
1154 int cx, cy;
1156 /* Try to load function from shell32 */
1157 hShell32 = LoadLibrary("shell32.dll");
1158 pSHGetImageList = (void*)GetProcAddress(hShell32, (LPCSTR) 727);
1160 if (!pSHGetImageList)
1162 win_skip("SHGetImageList not available, skipping test\n");
1163 FreeLibrary(hShell32);
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 FreeLibrary(hShell32);
1174 return;
1177 IImageList_GetImageCount(iml, &out);
1178 ok(out > 0, "IImageList_GetImageCount returned out <= 0\n");
1180 /* Fetch the small icon size */
1181 cx = GetSystemMetrics(SM_CXSMICON);
1182 cy = GetSystemMetrics(SM_CYSMICON);
1184 /* Check icon size matches */
1185 IImageList_GetImageRect(iml, 0, &rect);
1186 ok(((rect.right == cx) && (rect.bottom == cy)),
1187 "IImageList_GetImageRect returned r:%d,b:%d\n",
1188 rect.right, rect.bottom);
1190 IImageList_Release(iml);
1191 FreeLibrary(hShell32);
1194 static HBITMAP create_test_bitmap(HDC hdc, int bpp, UINT32 pixel1, UINT32 pixel2)
1196 HBITMAP hBitmap;
1197 UINT32 *buffer = NULL;
1198 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, bpp, BI_RGB,
1199 0, 0, 0, 0, 0}};
1201 hBitmap = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, NULL, 0);
1202 ok(hBitmap != NULL && buffer != NULL, "CreateDIBSection failed.\n");
1204 if(!hBitmap || !buffer)
1206 DeleteObject(hBitmap);
1207 return NULL;
1210 buffer[0] = pixel1;
1211 buffer[1] = pixel2;
1213 return hBitmap;
1216 static BOOL colour_match(UINT32 x, UINT32 y)
1218 const INT32 tolerance = 8;
1220 const INT32 dr = abs((INT32)(x & 0x000000FF) - (INT32)(y & 0x000000FF));
1221 const INT32 dg = abs((INT32)((x & 0x0000FF00) >> 8) - (INT32)((y & 0x0000FF00) >> 8));
1222 const INT32 db = abs((INT32)((x & 0x00FF0000) >> 16) - (INT32)((y & 0x00FF0000) >> 16));
1224 return (dr <= tolerance && dg <= tolerance && db <= tolerance);
1227 static void check_ImageList_DrawIndirect(IMAGELISTDRAWPARAMS *ildp, UINT32 *bits,
1228 UINT32 expected, int line)
1230 bits[0] = 0x00FFFFFF;
1231 pImageList_DrawIndirect(ildp);
1232 ok(colour_match(bits[0], expected),
1233 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1234 bits[0] & 0x00FFFFFF, expected, line);
1238 static void check_ImageList_DrawIndirect_fStyle(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1239 UINT fStyle, UINT32 expected, int line)
1241 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1242 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, ILS_NORMAL, 0, 0x00000000};
1243 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1246 static void check_ImageList_DrawIndirect_ILD_ROP(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1247 DWORD dwRop, UINT32 expected, int line)
1249 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1250 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_IMAGE | ILD_ROP, dwRop, ILS_NORMAL, 0, 0x00000000};
1251 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1254 static void check_ImageList_DrawIndirect_fState(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i, UINT fStyle,
1255 UINT fState, DWORD Frame, UINT32 expected, int line)
1257 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1258 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1259 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1262 static void check_ImageList_DrawIndirect_broken(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1263 UINT fStyle, UINT fState, DWORD Frame, UINT32 expected,
1264 UINT32 broken_expected, int line)
1266 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1267 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1268 bits[0] = 0x00FFFFFF;
1269 pImageList_DrawIndirect(&ildp);
1270 ok(colour_match(bits[0], expected) ||
1271 broken(colour_match(bits[0], broken_expected)),
1272 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1273 bits[0] & 0x00FFFFFF, expected, line);
1276 static void test_ImageList_DrawIndirect(void)
1278 HIMAGELIST himl = NULL;
1279 int ret;
1280 HDC hdcDst = NULL;
1281 HBITMAP hbmOld = NULL, hbmDst = NULL;
1282 HBITMAP hbmMask = NULL, hbmInverseMask = NULL;
1283 HBITMAP hbmImage = NULL, hbmAlphaImage = NULL, hbmTransparentImage = NULL;
1284 int iImage = -1, iAlphaImage = -1, iTransparentImage = -1;
1285 UINT32 *bits = 0;
1286 UINT32 maskBits = 0x00000000, inverseMaskBits = 0xFFFFFFFF;
1287 int bpp, broken_value;
1289 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB,
1290 0, 0, 0, 0, 0}};
1292 hdcDst = CreateCompatibleDC(0);
1293 ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
1294 if (!hdcDst)
1295 return;
1296 bpp = GetDeviceCaps(hdcDst, BITSPIXEL);
1298 hbmMask = CreateBitmap(2, 1, 1, 1, &maskBits);
1299 ok(hbmMask != 0, "CreateBitmap failed\n");
1300 if(!hbmMask) goto cleanup;
1302 hbmInverseMask = CreateBitmap(2, 1, 1, 1, &inverseMaskBits);
1303 ok(hbmInverseMask != 0, "CreateBitmap failed\n");
1304 if(!hbmInverseMask) goto cleanup;
1306 himl = pImageList_Create(2, 1, ILC_COLOR32, 0, 1);
1307 ok(himl != 0, "ImageList_Create failed\n");
1308 if(!himl) goto cleanup;
1310 /* Add a no-alpha image */
1311 hbmImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x00ABCDEF);
1312 if(!hbmImage) goto cleanup;
1314 iImage = pImageList_Add(himl, hbmImage, hbmMask);
1315 ok(iImage != -1, "ImageList_Add failed\n");
1316 if(iImage == -1) goto cleanup;
1318 /* Add an alpha image */
1319 hbmAlphaImage = create_test_bitmap(hdcDst, 32, 0x89ABCDEF, 0x89ABCDEF);
1320 if(!hbmAlphaImage) goto cleanup;
1322 iAlphaImage = pImageList_Add(himl, hbmAlphaImage, hbmMask);
1323 ok(iAlphaImage != -1, "ImageList_Add failed\n");
1324 if(iAlphaImage == -1) goto cleanup;
1326 /* Add a transparent alpha image */
1327 hbmTransparentImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x89ABCDEF);
1328 if(!hbmTransparentImage) goto cleanup;
1330 iTransparentImage = pImageList_Add(himl, hbmTransparentImage, hbmMask);
1331 ok(iTransparentImage != -1, "ImageList_Add failed\n");
1332 if(iTransparentImage == -1) goto cleanup;
1334 /* 32-bit Tests */
1335 bitmapInfo.bmiHeader.biBitCount = 32;
1336 hbmDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1337 ok (hbmDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1338 if (!hbmDst || !bits)
1339 goto cleanup;
1340 hbmOld = SelectObject(hdcDst, hbmDst);
1342 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_NORMAL, 0x00ABCDEF, __LINE__);
1343 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_TRANSPARENT, 0x00ABCDEF, __LINE__);
1344 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x00D4D9DD, __LINE__);
1345 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1346 else broken_value = 0x00B4BDC4;
1347 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1348 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_MASK, 0x00ABCDEF, __LINE__);
1349 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_IMAGE, 0x00ABCDEF, __LINE__);
1350 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_PRESERVEALPHA, 0x00ABCDEF, __LINE__);
1352 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, 0x00D3E5F7, __LINE__);
1353 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_TRANSPARENT, 0x00D3E5F7, __LINE__);
1355 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1356 else broken_value = 0x009DA8B1;
1357 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1358 if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD;
1359 else broken_value = 0x008C99A3;
1360 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__);
1361 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0x00D3E5F7, __LINE__);
1362 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0x00D3E5F7, __LINE__);
1363 todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__);
1365 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__);
1367 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCCOPY, 0x00ABCDEF, __LINE__);
1368 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCINVERT, 0x00543210, __LINE__);
1370 /* ILD_ROP is ignored when the image has an alpha channel */
1371 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCCOPY, 0x00D3E5F7, __LINE__);
1372 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCINVERT, 0x00D3E5F7, __LINE__);
1374 todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00CCCCCC, __LINE__);
1375 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00AFAFAF, 0x00F0F0F0, __LINE__);
1377 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_GLOW, 0, 0x00ABCDEF, __LINE__);
1378 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SHADOW, 0, 0x00ABCDEF, __LINE__);
1380 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00D5E6F7, __LINE__);
1381 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00E9F2FB, 0x00AEB7C0, __LINE__);
1382 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_NORMAL, 127, 0x00E9F2FB, 0x00D3E5F7, __LINE__);
1384 cleanup:
1386 if(hbmOld)
1387 SelectObject(hdcDst, hbmOld);
1388 if(hbmDst)
1389 DeleteObject(hbmDst);
1391 if(hdcDst)
1392 DeleteDC(hdcDst);
1394 if(hbmMask)
1395 DeleteObject(hbmMask);
1396 if(hbmInverseMask)
1397 DeleteObject(hbmInverseMask);
1399 if(hbmImage)
1400 DeleteObject(hbmImage);
1401 if(hbmAlphaImage)
1402 DeleteObject(hbmAlphaImage);
1403 if(hbmTransparentImage)
1404 DeleteObject(hbmTransparentImage);
1406 if(himl)
1408 ret = ImageList_Destroy(himl);
1409 ok(ret, "ImageList_Destroy failed\n");
1413 static void test_iimagelist(void)
1415 IImageList *imgl, *imgl2;
1416 HIMAGELIST himl;
1417 HRESULT hr;
1418 ULONG ret;
1420 if (!pHIMAGELIST_QueryInterface)
1422 win_skip("XP imagelist functions not available\n");
1423 return;
1426 /* test reference counting on destruction */
1427 imgl = (IImageList*)createImageList(32, 32);
1428 ret = IImageList_AddRef(imgl);
1429 ok(ret == 2, "Expected 2, 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 == TRUE, "Expected TRUE, got %d\n", ret);
1434 ret = ImageList_Destroy((HIMAGELIST)imgl);
1435 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1437 imgl = (IImageList*)createImageList(32, 32);
1438 ret = IImageList_AddRef(imgl);
1439 ok(ret == 2, "Expected 2, got %d\n", ret);
1440 ret = ImageList_Destroy((HIMAGELIST)imgl);
1441 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1442 ret = IImageList_Release(imgl);
1443 ok(ret == 0, "Expected 0, got %d\n", ret);
1444 ret = ImageList_Destroy((HIMAGELIST)imgl);
1445 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1447 /* ref counting, HIMAGELIST_QueryInterface adds a reference */
1448 imgl = (IImageList*)createImageList(32, 32);
1449 hr = pHIMAGELIST_QueryInterface((HIMAGELIST)imgl, &IID_IImageList, (void**)&imgl2);
1450 ok(hr == S_OK, "got 0x%08x\n", hr);
1451 ok(imgl2 == imgl, "got different pointer\n");
1452 ret = IImageList_Release(imgl);
1453 ok(ret == 1, "got %u\n", ret);
1454 IImageList_Release(imgl);
1456 if (!pImageList_CoCreateInstance)
1458 win_skip("Vista imagelist functions not available\n");
1459 return;
1462 hr = pImageList_CoCreateInstance(&CLSID_ImageList, NULL, &IID_IImageList, (void **) &imgl);
1463 ok(SUCCEEDED(hr), "ImageList_CoCreateInstance failed, hr=%x\n", hr);
1465 if (hr == S_OK)
1466 IImageList_Release(imgl);
1468 himl = createImageList(32, 32);
1470 if (!himl)
1471 return;
1473 hr = (pHIMAGELIST_QueryInterface)(himl, &IID_IImageList, (void **) &imgl);
1474 ok(SUCCEEDED(hr), "HIMAGELIST_QueryInterface failed, hr=%x\n", hr);
1476 if (hr == S_OK)
1477 IImageList_Release(imgl);
1479 ImageList_Destroy(himl);
1482 static void test_hotspot_v6(void)
1484 struct hotspot {
1485 int dx;
1486 int dy;
1489 #define SIZEX1 47
1490 #define SIZEY1 31
1491 #define SIZEX2 11
1492 #define SIZEY2 17
1493 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
1494 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
1495 { 10, 7 },
1496 { SIZEX1, SIZEY1 },
1497 { -9, -8 },
1498 { -7, 35 }
1500 int i, j;
1501 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
1502 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
1503 IImageList *imgl1, *imgl2;
1504 HRESULT hr;
1506 /* cast to IImageList */
1507 imgl1 = (IImageList *) himl1;
1508 imgl2 = (IImageList *) himl2;
1510 for (i = 0; i < HOTSPOTS_MAX; i++) {
1511 for (j = 0; j < HOTSPOTS_MAX; j++) {
1512 int dx1 = hotspots[i].dx;
1513 int dy1 = hotspots[i].dy;
1514 int dx2 = hotspots[j].dx;
1515 int dy2 = hotspots[j].dy;
1516 int correctx, correcty, newx, newy;
1517 char loc[256];
1518 IImageList *imglNew;
1519 POINT ppt;
1521 hr = IImageList_BeginDrag(imgl1, 0, dx1, dy1);
1522 ok(SUCCEEDED(hr), "BeginDrag failed for { %d, %d }\n", dx1, dy1);
1523 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
1525 /* check merging the dragged image with a second image */
1526 hr = IImageList_SetDragCursorImage(imgl2, (IUnknown *) imgl2, 0, dx2, dy2);
1527 ok(SUCCEEDED(hr), "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
1528 dx1, dy1, dx2, dy2);
1529 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
1531 /* check new hotspot, it should be the same like the old one */
1532 hr = IImageList_GetDragImage(imgl2, NULL, &ppt, &IID_IImageList, (PVOID *) &imglNew);
1533 ok(SUCCEEDED(hr), "GetDragImage failed\n");
1534 ok(ppt.x == dx1 && ppt.y == dy1,
1535 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
1536 dx1, dy1, ppt.x, ppt.y);
1537 /* check size of new dragged image */
1538 IImageList_GetIconSize(imglNew, &newx, &newy);
1539 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
1540 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
1541 ok(newx == correctx && newy == correcty,
1542 "Expected drag image size [%d,%d] got [%d,%d]\n",
1543 correctx, correcty, newx, newy);
1544 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
1545 IImageList_EndDrag(imgl2);
1548 #undef SIZEX1
1549 #undef SIZEY1
1550 #undef SIZEX2
1551 #undef SIZEY2
1552 #undef HOTSPOTS_MAX
1553 IImageList_Release(imgl2);
1554 IImageList_Release(imgl1);
1557 static void test_IImageList_Add_Remove(void)
1559 IImageList *imgl;
1560 HIMAGELIST himl;
1561 HRESULT hr;
1563 HICON hicon1;
1564 HICON hicon2;
1565 HICON hicon3;
1567 int ret;
1569 /* create an imagelist to play with */
1570 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1571 ok(himl != 0,"failed to create imagelist\n");
1573 imgl = (IImageList *) himl;
1575 /* load the icons to add to the image list */
1576 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1577 ok(hicon1 != 0, "no hicon1\n");
1578 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1579 ok(hicon2 != 0, "no hicon2\n");
1580 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1581 ok(hicon3 != 0, "no hicon3\n");
1583 /* remove when nothing exists */
1584 hr = IImageList_Remove(imgl, 0);
1585 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1587 /* removing everything from an empty imagelist should succeed */
1588 hr = IImageList_Remove(imgl, -1);
1589 ok(hr == S_OK, "removed nonexistent icon\n");
1591 /* add three */
1592 ret = -1;
1593 ok( IImageList_ReplaceIcon(imgl, -1, hicon1, &ret) == S_OK && (ret == 0),"failed to add icon1\n");
1594 ret = -1;
1595 ok( IImageList_ReplaceIcon(imgl, -1, hicon2, &ret) == S_OK && (ret == 1),"failed to add icon2\n");
1596 ret = -1;
1597 ok( IImageList_ReplaceIcon(imgl, -1, hicon3, &ret) == S_OK && (ret == 2),"failed to add icon3\n");
1599 /* remove an index out of range */
1600 ok( IImageList_Remove(imgl, 4711) == E_INVALIDARG, "got 0x%08x\n", hr);
1602 /* remove three */
1603 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1604 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1605 ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n");
1607 /* remove one extra */
1608 ok( IImageList_Remove(imgl, 0) == E_INVALIDARG, "got 0x%08x\n", hr);
1610 IImageList_Release(imgl);
1611 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
1612 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
1613 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
1616 static void test_IImageList_Get_SetImageCount(void)
1618 IImageList *imgl;
1619 HIMAGELIST himl;
1620 HRESULT hr;
1621 INT ret;
1623 /* create an imagelist to play with */
1624 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1625 ok(himl != 0,"failed to create imagelist\n");
1627 imgl = (IImageList *) himl;
1629 /* check SetImageCount/GetImageCount */
1630 hr = IImageList_SetImageCount(imgl, 3);
1631 ok(hr == S_OK, "got 0x%08x\n", hr);
1632 ret = 0;
1633 hr = IImageList_GetImageCount(imgl, &ret);
1634 ok(hr == S_OK && ret == 3, "invalid image count after increase\n");
1635 hr = IImageList_SetImageCount(imgl, 1);
1636 ok(hr == S_OK, "got 0x%08x\n", hr);
1637 ret = 0;
1638 hr = IImageList_GetImageCount(imgl, &ret);
1639 ok(hr == S_OK && ret == 1, "invalid image count after decrease to 1\n");
1640 hr = IImageList_SetImageCount(imgl, 0);
1641 ok(hr == S_OK, "got 0x%08x\n", hr);
1642 ret = -1;
1643 hr = IImageList_GetImageCount(imgl, &ret);
1644 ok(hr == S_OK && ret == 0, "invalid image count after decrease to 0\n");
1646 IImageList_Release(imgl);
1649 static void test_IImageList_Draw(void)
1651 IImageList *imgl;
1652 HIMAGELIST himl;
1654 HBITMAP hbm1;
1655 HBITMAP hbm2;
1656 HBITMAP hbm3;
1658 IMAGELISTDRAWPARAMS imldp;
1659 HWND hwndfortest;
1660 HRESULT hr;
1661 HDC hdc;
1662 int ret;
1664 hwndfortest = create_a_window();
1665 hdc = GetDC(hwndfortest);
1666 ok(hdc!=NULL, "couldn't get DC\n");
1668 /* create an imagelist to play with */
1669 himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
1670 ok(himl!=0,"failed to create imagelist\n");
1672 imgl = (IImageList *) himl;
1674 /* load the icons to add to the image list */
1675 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1676 ok(hbm1 != 0, "no bitmap 1\n");
1677 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1678 ok(hbm2 != 0, "no bitmap 2\n");
1679 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1680 ok(hbm3 != 0, "no bitmap 3\n");
1682 /* add three */
1683 ret = -1;
1684 ok( IImageList_Add(imgl, hbm1, 0, &ret) == S_OK && (ret == 0), "failed to add bitmap 1\n");
1685 ret = -1;
1686 ok( IImageList_Add(imgl, hbm2, 0, &ret) == S_OK && (ret == 1), "failed to add bitmap 2\n");
1688 ok( IImageList_SetImageCount(imgl, 3) == S_OK, "Setimage count failed\n");
1689 ok( IImageList_Replace(imgl, 2, hbm3, 0) == S_OK, "failed to replace bitmap 3\n");
1691 if (0)
1693 /* crashes on native */
1694 IImageList_Draw(imgl, NULL);
1697 memset(&imldp, 0, sizeof (imldp));
1698 hr = IImageList_Draw(imgl, &imldp);
1699 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
1701 imldp.cbSize = IMAGELISTDRAWPARAMS_V3_SIZE;
1702 imldp.hdcDst = hdc;
1703 imldp.himl = himl;
1705 REDRAW(hwndfortest);
1706 WAIT;
1708 imldp.fStyle = SRCCOPY;
1709 imldp.rgbBk = CLR_DEFAULT;
1710 imldp.rgbFg = CLR_DEFAULT;
1711 imldp.y = 100;
1712 imldp.x = 100;
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) == S_OK, "should succeed\n");
1718 imldp.i ++;
1719 ok( IImageList_Draw(imgl, &imldp) == E_INVALIDARG, "should fail\n");
1721 /* remove three */
1722 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 1st bitmap\n");
1723 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 2nd bitmap\n");
1724 ok( IImageList_Remove(imgl, 0) == S_OK, "removing 3rd bitmap\n");
1726 /* destroy it */
1727 IImageList_Release(imgl);
1729 /* bitmaps should not be deleted by the imagelist */
1730 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
1731 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
1732 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
1734 ReleaseDC(hwndfortest, hdc);
1735 DestroyWindow(hwndfortest);
1738 static void test_IImageList_Merge(void)
1740 HIMAGELIST himl1, himl2;
1741 IImageList *imgl1, *imgl2, *merge;
1742 HICON hicon1;
1743 HWND hwnd = create_a_window();
1744 HRESULT hr;
1745 int ret;
1747 himl1 = ImageList_Create(32,32,0,0,3);
1748 ok(himl1 != NULL,"failed to create himl1\n");
1750 himl2 = ImageList_Create(32,32,0,0,3);
1751 ok(himl2 != NULL,"failed to create himl2\n");
1753 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1754 ok(hicon1 != NULL, "failed to create hicon1\n");
1756 if (!himl1 || !himl2 || !hicon1)
1757 return;
1759 /* cast to IImageList */
1760 imgl1 = (IImageList *) himl1;
1761 imgl2 = (IImageList *) himl2;
1763 ret = -1;
1764 ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (ret == 0),"add icon1 to himl2 failed\n");
1766 if (0)
1768 /* null cases that crash on native */
1769 IImageList_Merge(imgl1, -1, NULL, 0, 0, 0, &IID_IImageList, (void**)&merge);
1770 IImageList_Merge(imgl1, -1, (IUnknown*) imgl2, 0, 0, 0, &IID_IImageList, NULL);
1773 /* If himl1 has no images, merge still succeeds */
1774 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1775 ok(hr == S_OK, "merge himl1,-1 failed\n");
1776 if (hr == S_OK) IImageList_Release(merge);
1778 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1779 ok(hr == S_OK, "merge himl1,0 failed\n");
1780 if (hr == S_OK) IImageList_Release(merge);
1782 /* Same happens if himl2 is empty */
1783 IImageList_Release(imgl2);
1784 himl2 = ImageList_Create(32,32,0,0,3);
1785 ok(himl2 != NULL,"failed to recreate himl2\n");
1787 imgl2 = (IImageList *) himl2;
1789 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, -1, 0, 0, &IID_IImageList, (void **) &merge);
1790 ok(hr == S_OK, "merge himl2,-1 failed\n");
1791 if (hr == S_OK) IImageList_Release(merge);
1793 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1794 ok(hr == S_OK, "merge himl2,0 failed\n");
1795 if (hr == S_OK) IImageList_Release(merge);
1797 /* Now try merging an image with itself */
1798 ret = -1;
1799 ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (ret == 0),"re-add icon1 to himl2 failed\n");
1801 hr = IImageList_Merge(imgl2, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1802 ok(hr == S_OK, "merge himl2 with itself failed\n");
1803 if (hr == S_OK) IImageList_Release(merge);
1805 /* Try merging 2 different image lists */
1806 ret = -1;
1807 ok( IImageList_ReplaceIcon(imgl1, -1, hicon1, &ret) == S_OK && (ret == 0),"add icon1 to himl1 failed\n");
1809 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1810 ok(hr == S_OK, "merge himl1 with himl2 failed\n");
1811 if (hr == S_OK) IImageList_Release(merge);
1813 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 8, 16, &IID_IImageList, (void **) &merge);
1814 ok(hr == S_OK, "merge himl1 with himl2 8,16 failed\n");
1815 if (hr == S_OK) IImageList_Release(merge);
1817 IImageList_Release(imgl1);
1818 IImageList_Release(imgl2);
1820 DestroyIcon(hicon1);
1821 DestroyWindow(hwnd);
1824 static void test_iconsize(void)
1826 HIMAGELIST himl;
1827 INT cx, cy;
1828 BOOL ret;
1830 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1831 /* null pointers, not zero imagelist dimensions */
1832 ret = ImageList_GetIconSize(himl, NULL, NULL);
1833 ok(!ret, "got %d\n", ret);
1835 /* doesn't touch return pointers */
1836 cx = 0x1abe11ed;
1837 ret = ImageList_GetIconSize(himl, &cx, NULL);
1838 ok(!ret, "got %d\n", ret);
1839 ok(cx == 0x1abe11ed, "got %d\n", cx);
1841 cy = 0x1abe11ed;
1842 ret = ImageList_GetIconSize(himl, NULL, &cy);
1843 ok(!ret, "got %d\n", ret);
1844 ok(cy == 0x1abe11ed, "got %d\n", cy);
1846 ImageList_Destroy(himl);
1848 ret = ImageList_GetIconSize((HIMAGELIST)0xdeadbeef, &cx, &cy);
1849 ok(!ret, "got %d\n", ret);
1852 static void test_create_destroy(void)
1854 HIMAGELIST himl;
1855 BOOL rc;
1857 /* list with zero or negative image dimensions */
1858 himl = ImageList_Create(0, 0, ILC_COLOR16, 0, 3);
1859 ok(himl == NULL, "got %p\n", himl);
1861 himl = ImageList_Create(0, 16, ILC_COLOR16, 0, 3);
1862 ok(himl == NULL, "got %p\n", himl);
1864 himl = ImageList_Create(16, 0, ILC_COLOR16, 0, 3);
1865 ok(himl == NULL, "got %p\n", himl);
1867 himl = ImageList_Create(16, -1, ILC_COLOR16, 0, 3);
1868 ok(himl == NULL, "got %p\n", himl);
1870 himl = ImageList_Create(-1, 16, ILC_COLOR16, 0, 3);
1871 ok(himl == NULL, "got %p\n", himl);
1873 rc = ImageList_Destroy((HIMAGELIST)0xdeadbeef);
1874 ok(rc == FALSE, "ImageList_Destroy(0xdeadbeef) should fail and not crash\n");
1877 static void test_IImageList_Clone(void)
1879 IImageList *imgl, *imgl2;
1880 HIMAGELIST himl;
1881 HRESULT hr;
1882 ULONG ref;
1884 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1885 imgl = (IImageList*)himl;
1887 if (0)
1889 /* crashes on native */
1890 IImageList_Clone(imgl, &IID_IImageList, NULL);
1893 hr = IImageList_Clone(imgl, &IID_IImageList, (void**)&imgl2);
1894 ok(hr == S_OK, "got 0x%08x\n", hr);
1895 ref = IImageList_Release(imgl2);
1896 ok(ref == 0, "got %u\n", ref);
1898 IImageList_Release(imgl);
1901 static void test_IImageList_GetBkColor(void)
1903 IImageList *imgl;
1904 HIMAGELIST himl;
1905 COLORREF color;
1906 HRESULT hr;
1908 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1909 imgl = (IImageList*)himl;
1911 if (0)
1913 /* crashes on native */
1914 IImageList_GetBkColor(imgl, NULL);
1917 hr = IImageList_GetBkColor(imgl, &color);
1918 ok(hr == S_OK, "got 0x%08x\n", hr);
1920 IImageList_Release(imgl);
1923 static void test_IImageList_SetBkColor(void)
1925 IImageList *imgl;
1926 HIMAGELIST himl;
1927 COLORREF color;
1928 HRESULT hr;
1930 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1931 imgl = (IImageList*)himl;
1933 if (0)
1935 /* crashes on native */
1936 IImageList_SetBkColor(imgl, RGB(0, 0, 0), NULL);
1939 hr = IImageList_SetBkColor(imgl, CLR_NONE, &color);
1940 ok(hr == S_OK, "got 0x%08x\n", hr);
1942 hr = IImageList_SetBkColor(imgl, CLR_NONE, &color);
1943 ok(hr == S_OK, "got 0x%08x\n", hr);
1945 color = 0xdeadbeef;
1946 hr = IImageList_GetBkColor(imgl, &color);
1947 ok(hr == S_OK, "got 0x%08x\n", hr);
1948 ok(color == CLR_NONE, "got %x\n", color);
1950 IImageList_Release(imgl);
1953 static void test_IImageList_GetImageCount(void)
1955 IImageList *imgl;
1956 HIMAGELIST himl;
1957 int count;
1958 HRESULT hr;
1960 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1961 imgl = (IImageList*)himl;
1963 if (0)
1965 /* crashes on native */
1966 IImageList_GetImageCount(imgl, NULL);
1969 count = -1;
1970 hr = IImageList_GetImageCount(imgl, &count);
1971 ok(hr == S_OK, "got 0x%08x\n", hr);
1972 ok(count == 0, "got %d\n", count);
1974 IImageList_Release(imgl);
1977 static void test_IImageList_GetIconSize(void)
1979 IImageList *imgl;
1980 HIMAGELIST himl;
1981 int cx, cy;
1982 HRESULT hr;
1984 himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3);
1985 imgl = (IImageList*)himl;
1987 hr = IImageList_GetIconSize(imgl, NULL, NULL);
1988 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1990 hr = IImageList_GetIconSize(imgl, &cx, NULL);
1991 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1993 hr = IImageList_GetIconSize(imgl, NULL, &cy);
1994 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1996 IImageList_Release(imgl);
1999 START_TEST(imagelist)
2001 ULONG_PTR ctx_cookie;
2002 HANDLE hCtx;
2004 HMODULE hComCtl32 = GetModuleHandle("comctl32.dll");
2005 pImageList_Create = NULL; /* These are not needed for non-v6.0 tests*/
2006 pImageList_Add = NULL;
2007 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
2008 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
2010 hinst = GetModuleHandleA(NULL);
2012 InitCommonControls();
2014 test_create_destroy();
2015 test_hotspot();
2016 test_add_remove();
2017 test_imagecount();
2018 test_DrawIndirect();
2019 test_merge();
2020 test_imagelist_storage();
2021 test_iconsize();
2023 FreeLibrary(hComCtl32);
2025 /* Now perform v6 tests */
2027 if (!load_v6_module(&ctx_cookie, &hCtx))
2028 return;
2030 /* Reload comctl32 */
2031 hComCtl32 = LoadLibraryA("comctl32.dll");
2032 pImageList_Create = (void*)GetProcAddress(hComCtl32, "ImageList_Create");
2033 pImageList_Add = (void*)GetProcAddress(hComCtl32, "ImageList_Add");
2034 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
2035 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
2036 pImageList_CoCreateInstance = (void*)GetProcAddress(hComCtl32, "ImageList_CoCreateInstance");
2037 pHIMAGELIST_QueryInterface = (void*)GetProcAddress(hComCtl32, "HIMAGELIST_QueryInterface");
2039 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
2041 /* Do v6.0 tests */
2042 test_ImageList_DrawIndirect();
2043 test_shell_imagelist();
2044 test_iimagelist();
2046 test_hotspot_v6();
2047 test_IImageList_Add_Remove();
2048 test_IImageList_Get_SetImageCount();
2049 test_IImageList_Draw();
2050 test_IImageList_Merge();
2051 test_IImageList_Clone();
2052 test_IImageList_GetBkColor();
2053 test_IImageList_SetBkColor();
2054 test_IImageList_GetImageCount();
2055 test_IImageList_GetIconSize();
2057 CoUninitialize();
2059 unload_v6_module(ctx_cookie, hCtx);