2 * Unit test suite for imagelist control.
4 * Copyright 2004 Michael Stefaniuc
5 * Copyright 2002 Mike McCormack for CodeWeavers
6 * Copyright 2007 Dmitry Timoshkov
7 * Copyright 2009 Owen Rudge for CodeWeavers
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
36 #include "commctrl.h" /* must be included after objbase.h to get ImageList_Write */
38 #include "commoncontrols.h"
41 #include "wine/test.h"
47 #define WAIT Sleep (1000)
48 #define REDRAW(hwnd) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW)
54 #define IMAGELIST_MAGIC (('L' << 8) | 'I')
57 /* Header used by ImageList_Read() and ImageList_Write() */
58 typedef struct _ILHEAD
73 static HIMAGELIST (WINAPI *pImageList_Create)(int, int, UINT, int, int);
74 static int (WINAPI *pImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
75 static BOOL (WINAPI *pImageList_DrawIndirect)(IMAGELISTDRAWPARAMS*);
76 static BOOL (WINAPI *pImageList_SetImageCount)(HIMAGELIST,UINT);
77 static HRESULT (WINAPI *pImageList_CoCreateInstance)(REFCLSID,const IUnknown *,
79 static HRESULT (WINAPI *pHIMAGELIST_QueryInterface)(HIMAGELIST,REFIID,void **);
81 static HINSTANCE hinst;
83 /* These macros build cursor/bitmap data in 4x4 pixel blocks */
84 #define B(x,y) ((x?0xf0:0)|(y?0xf:0))
85 #define ROW1(a,b,c,d,e,f,g,h) B(a,b),B(c,d),B(e,f),B(g,h)
86 #define ROW32(a,b,c,d,e,f,g,h) ROW1(a,b,c,d,e,f,g,h), ROW1(a,b,c,d,e,f,g,h), \
87 ROW1(a,b,c,d,e,f,g,h), ROW1(a,b,c,d,e,f,g,h)
88 #define ROW2(a,b,c,d,e,f,g,h,i,j,k,l) ROW1(a,b,c,d,e,f,g,h),B(i,j),B(k,l)
89 #define ROW48(a,b,c,d,e,f,g,h,i,j,k,l) ROW2(a,b,c,d,e,f,g,h,i,j,k,l), \
90 ROW2(a,b,c,d,e,f,g,h,i,j,k,l), ROW2(a,b,c,d,e,f,g,h,i,j,k,l), \
91 ROW2(a,b,c,d,e,f,g,h,i,j,k,l)
93 static const BYTE empty_bits[48*48/8];
95 static const BYTE icon_bits[32*32/8] =
97 ROW32(0,0,0,0,0,0,0,0),
98 ROW32(0,0,1,1,1,1,0,0),
99 ROW32(0,1,1,1,1,1,1,0),
100 ROW32(0,1,1,0,0,1,1,0),
101 ROW32(0,1,1,0,0,1,1,0),
102 ROW32(0,1,1,1,1,1,1,0),
103 ROW32(0,0,1,1,1,1,0,0),
104 ROW32(0,0,0,0,0,0,0,0)
107 static const BYTE bitmap_bits[48*48/8] =
109 ROW48(0,0,0,0,0,0,0,0,0,0,0,0),
110 ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
111 ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
112 ROW48(0,1,0,0,0,0,0,0,1,0,1,0),
113 ROW48(0,1,0,0,0,0,0,1,0,0,1,0),
114 ROW48(0,1,0,0,0,0,1,0,0,0,1,0),
115 ROW48(0,1,0,0,0,1,0,0,0,0,1,0),
116 ROW48(0,1,0,0,1,0,0,0,0,0,1,0),
117 ROW48(0,1,0,1,0,0,0,0,0,0,1,0),
118 ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
119 ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
120 ROW48(0,0,0,0,0,0,0,0,0,0,0,0)
123 static HIMAGELIST createImageList(int cx, int cy)
125 /* Create an ImageList and put an image into it */
126 HIMAGELIST himl = ImageList_Create(cx, cy, ILC_COLOR, 1, 1);
127 HBITMAP hbm = CreateBitmap(48, 48, 1, 1, bitmap_bits);
128 ImageList_Add(himl, hbm, NULL);
133 static HWND create_a_window(void)
135 char className[] = "bmwnd";
136 char winName[] = "Test Bitmap";
138 static int registered = 0;
144 cls.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
145 cls.lpfnWndProc = DefWindowProcA;
149 cls.hIcon = LoadIconA (0, IDI_APPLICATION);
150 cls.hCursor = LoadCursorA (0, IDC_ARROW);
151 cls.hbrBackground = GetStockObject (WHITE_BRUSH);
152 cls.lpszMenuName = 0;
153 cls.lpszClassName = className;
155 RegisterClassA (&cls);
160 hWnd = CreateWindowA (className, winName,
161 WS_OVERLAPPEDWINDOW ,
162 CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
166 ShowWindow (hWnd, SW_SHOW);
174 static HDC show_image(HWND hwnd, HIMAGELIST himl, int idx, int size,
175 LPCSTR loc, BOOL clear)
179 if (!himl) return NULL;
181 SetWindowText(hwnd, loc);
183 ImageList_Draw(himl, idx, hdc, 0, 0, ILD_TRANSPARENT);
190 BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
191 ReleaseDC(hwnd, hdc);
198 /* Useful for checking differences */
200 static void dump_bits(const BYTE *p, const BYTE *q, int size)
206 for (i = 0; i < size * 2; i++)
209 for (j = 0; j < size; j++)
210 printf("%c%c", p[j] & 0xf0 ? 'X' : ' ', p[j] & 0xf ? 'X' : ' ');
212 for (j = 0; j < size; j++)
213 printf("%c%c", q[j] & 0xf0 ? 'X' : ' ', q[j] & 0xf ? 'X' : ' ');
222 static void check_bits(HWND hwnd, HIMAGELIST himl, int idx, int size,
223 const BYTE *checkbits, LPCSTR loc)
226 BYTE bits[100*100/8];
233 memset(bits, 0, sizeof(bits));
234 hdc = show_image(hwnd, himl, idx, size, loc, FALSE);
236 c = GetPixel(hdc, 0, 0);
238 for (y = 0; y < size; y ++)
240 for (x = 0; x < size; x++)
243 if (GetPixel(hdc, x, y) != c) bits[i] |= (0x80 >> (x & 0x7));
247 BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
248 ReleaseDC(hwnd, hdc);
250 ok (memcmp(bits, checkbits, (size * size)/8) == 0,
251 "%s: bits different\n", loc);
252 if (memcmp(bits, checkbits, (size * size)/8))
253 dump_bits(bits, checkbits, size);
257 static void testHotspot (void)
268 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
269 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
276 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
277 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
278 HWND hwnd = create_a_window();
281 for (i = 0; i < HOTSPOTS_MAX; i++) {
282 for (j = 0; j < HOTSPOTS_MAX; j++) {
283 int dx1 = hotspots[i].dx;
284 int dy1 = hotspots[i].dy;
285 int dx2 = hotspots[j].dx;
286 int dy2 = hotspots[j].dy;
287 int correctx, correcty, newx, newy;
292 ret = ImageList_BeginDrag(himl1, 0, dx1, dy1);
293 ok(ret != 0, "BeginDrag failed for { %d, %d }\n", dx1, dy1);
294 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
295 show_image(hwnd, himl1, 0, max(SIZEX1, SIZEY1), loc, TRUE);
297 /* check merging the dragged image with a second image */
298 ret = ImageList_SetDragCursorImage(himl2, 0, dx2, dy2);
299 ok(ret != 0, "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
301 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
302 show_image(hwnd, himl2, 0, max(SIZEX2, SIZEY2), loc, TRUE);
304 /* check new hotspot, it should be the same like the old one */
305 himlNew = ImageList_GetDragImage(NULL, &ppt);
306 ok(ppt.x == dx1 && ppt.y == dy1,
307 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
308 dx1, dy1, ppt.x, ppt.y);
309 /* check size of new dragged image */
310 ImageList_GetIconSize(himlNew, &newx, &newy);
311 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
312 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
313 ok(newx == correctx && newy == correcty,
314 "Expected drag image size [%d,%d] got [%d,%d]\n",
315 correctx, correcty, newx, newy);
316 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
317 show_image(hwnd, himlNew, 0, max(correctx, correcty), loc, TRUE);
326 ImageList_Destroy(himl2);
327 ImageList_Destroy(himl1);
331 static BOOL DoTest1(void)
339 /* create an imagelist to play with */
340 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
341 ok(himl!=0,"failed to create imagelist\n");
343 /* load the icons to add to the image list */
344 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
345 ok(hicon1 != 0, "no hicon1\n");
346 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
347 ok(hicon2 != 0, "no hicon2\n");
348 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
349 ok(hicon3 != 0, "no hicon3\n");
351 /* remove when nothing exists */
352 ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
353 /* removing everything from an empty imagelist should succeed */
354 ok(ImageList_RemoveAll(himl),"removed nonexistent icon\n");
357 ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
358 ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
359 ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
361 /* remove an index out of range */
362 ok(!ImageList_Remove(himl,4711),"removed nonexistent icon\n");
365 ok(ImageList_Remove(himl,0),"can't remove 0\n");
366 ok(ImageList_Remove(himl,0),"can't remove 0\n");
367 ok(ImageList_Remove(himl,0),"can't remove 0\n");
369 /* remove one extra */
370 ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
372 /* check SetImageCount/GetImageCount */
373 if (pImageList_SetImageCount)
375 ok(pImageList_SetImageCount(himl, 3), "couldn't increase image count\n");
376 ok(ImageList_GetImageCount(himl) == 3, "invalid image count after increase\n");
377 ok(pImageList_SetImageCount(himl, 1), "couldn't decrease image count\n");
378 ok(ImageList_GetImageCount(himl) == 1, "invalid image count after decrease to 1\n");
379 ok(pImageList_SetImageCount(himl, 0), "couldn't decrease image count\n");
380 ok(ImageList_GetImageCount(himl) == 0, "invalid image count after decrease to 0\n");
384 skip("skipped ImageList_SetImageCount tests\n");
388 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
390 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
391 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
392 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
397 static BOOL DoTest2(void)
405 /* create an imagelist to play with */
406 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
407 ok(himl!=0,"failed to create imagelist\n");
409 /* load the icons to add to the image list */
410 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
411 ok(hicon1 != 0, "no hicon1\n");
412 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
413 ok(hicon2 != 0, "no hicon2\n");
414 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
415 ok(hicon3 != 0, "no hicon3\n");
418 ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
419 ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
420 ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
423 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
425 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
426 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
427 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
432 static BOOL DoTest3(void)
440 IMAGELISTDRAWPARAMS imldp;
444 if (!pImageList_DrawIndirect)
446 win_skip("ImageList_DrawIndirect not available, skipping test\n");
450 hwndfortest = create_a_window();
451 hdc = GetDC(hwndfortest);
452 ok(hdc!=NULL, "couldn't get DC\n");
454 /* create an imagelist to play with */
455 himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
456 ok(himl!=0,"failed to create imagelist\n");
458 /* load the icons to add to the image list */
459 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
460 ok(hbm1 != 0, "no bitmap 1\n");
461 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
462 ok(hbm2 != 0, "no bitmap 2\n");
463 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
464 ok(hbm3 != 0, "no bitmap 3\n");
467 ok(0==ImageList_Add(himl, hbm1, 0),"failed to add bitmap 1\n");
468 ok(1==ImageList_Add(himl, hbm2, 0),"failed to add bitmap 2\n");
470 if (pImageList_SetImageCount)
472 ok(pImageList_SetImageCount(himl,3),"Setimage count failed\n");
473 /*ok(2==ImageList_Add(himl, hbm3, NULL),"failed to add bitmap 3\n"); */
474 ok(ImageList_Replace(himl, 2, hbm3, 0),"failed to replace bitmap 3\n");
477 memset(&imldp, 0, sizeof (imldp));
478 ok(!pImageList_DrawIndirect(&imldp), "zero data succeeded!\n");
479 imldp.cbSize = sizeof (imldp);
480 ok(!pImageList_DrawIndirect(&imldp), "zero hdc succeeded!\n");
482 ok(!pImageList_DrawIndirect(&imldp),"zero himl succeeded!\n");
484 if (!pImageList_DrawIndirect(&imldp))
486 /* Earlier versions of native comctl32 use a smaller structure */
487 imldp.cbSize -= 3 * sizeof(DWORD);
488 ok(pImageList_DrawIndirect(&imldp),"DrawIndirect should succeed\n");
493 imldp.fStyle = SRCCOPY;
494 imldp.rgbBk = CLR_DEFAULT;
495 imldp.rgbFg = CLR_DEFAULT;
498 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
500 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
502 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
504 ok(!pImageList_DrawIndirect(&imldp),"should fail\n");
507 ok(ImageList_Remove(himl, 0), "removing 1st bitmap\n");
508 ok(ImageList_Remove(himl, 0), "removing 2nd bitmap\n");
509 ok(ImageList_Remove(himl, 0), "removing 3rd bitmap\n");
512 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
514 /* bitmaps should not be deleted by the imagelist */
515 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
516 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
517 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
519 ReleaseDC(hwndfortest, hdc);
520 DestroyWindow(hwndfortest);
525 static void testMerge(void)
527 HIMAGELIST himl1, himl2, hmerge;
529 HWND hwnd = create_a_window();
531 himl1 = ImageList_Create(32,32,0,0,3);
532 ok(himl1 != NULL,"failed to create himl1\n");
534 himl2 = ImageList_Create(32,32,0,0,3);
535 ok(himl2 != NULL,"failed to create himl2\n");
537 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
538 ok(hicon1 != NULL, "failed to create hicon1\n");
540 if (!himl1 || !himl2 || !hicon1)
543 ok(0==ImageList_AddIcon(himl2, hicon1),"add icon1 to himl2 failed\n");
544 check_bits(hwnd, himl2, 0, 32, icon_bits, "add icon1 to himl2");
546 /* If himl1 has no images, merge still succeeds */
547 hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
548 ok(hmerge != NULL, "merge himl1,-1 failed\n");
549 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,-1");
550 if (hmerge) ImageList_Destroy(hmerge);
552 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
553 ok(hmerge != NULL,"merge himl1,0 failed\n");
554 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,0");
555 if (hmerge) ImageList_Destroy(hmerge);
557 /* Same happens if himl2 is empty */
558 ImageList_Destroy(himl2);
559 himl2 = ImageList_Create(32,32,0,0,3);
560 ok(himl2 != NULL,"failed to recreate himl2\n");
564 hmerge = ImageList_Merge(himl1, -1, himl2, -1, 0, 0);
565 ok(hmerge != NULL, "merge himl2,-1 failed\n");
566 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,-1");
567 if (hmerge) ImageList_Destroy(hmerge);
569 hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
570 ok(hmerge != NULL, "merge himl2,0 failed\n");
571 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,0");
572 if (hmerge) ImageList_Destroy(hmerge);
574 /* Now try merging an image with itself */
575 ok(0==ImageList_AddIcon(himl2, hicon1),"re-add icon1 to himl2 failed\n");
577 hmerge = ImageList_Merge(himl2, 0, himl2, 0, 0, 0);
578 ok(hmerge != NULL, "merge himl2 with itself failed\n");
579 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2 with itself");
580 if (hmerge) ImageList_Destroy(hmerge);
582 /* Try merging 2 different image lists */
583 ok(0==ImageList_AddIcon(himl1, hicon1),"add icon1 to himl1 failed\n");
585 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
586 ok(hmerge != NULL, "merge himl1 with himl2 failed\n");
587 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2");
588 if (hmerge) ImageList_Destroy(hmerge);
590 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 8, 16);
591 ok(hmerge != NULL, "merge himl1 with himl2 8,16 failed\n");
592 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2, 8,16");
593 if (hmerge) ImageList_Destroy(hmerge);
595 ImageList_Destroy(himl1);
596 ImageList_Destroy(himl2);
601 /*********************** imagelist storage test ***************************/
608 char *iml_data; /* written imagelist data */
612 static HRESULT STDMETHODCALLTYPE Test_Stream_QueryInterface(
621 static ULONG STDMETHODCALLTYPE Test_Stream_AddRef(
628 static ULONG STDMETHODCALLTYPE Test_Stream_Release(
635 static HRESULT STDMETHODCALLTYPE Test_Stream_Read(
645 static BOOL allocate_storage(struct my_IStream *my_is, ULONG add)
647 my_is->iml_data_size += add;
649 if (!my_is->iml_data)
650 my_is->iml_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, my_is->iml_data_size);
652 my_is->iml_data = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, my_is->iml_data, my_is->iml_data_size);
654 return my_is->iml_data ? TRUE : FALSE;
657 static HRESULT STDMETHODCALLTYPE Test_Stream_Write(
663 struct my_IStream *my_is = (struct my_IStream *)This;
664 ULONG current_iml_data_size = my_is->iml_data_size;
666 if (!allocate_storage(my_is, cb)) return E_FAIL;
668 memcpy(my_is->iml_data + current_iml_data_size, pv, cb);
669 if (pcbWritten) *pcbWritten = cb;
674 static HRESULT STDMETHODCALLTYPE Test_Stream_Seek(
676 LARGE_INTEGER dlibMove,
678 ULARGE_INTEGER* plibNewPosition)
684 static HRESULT STDMETHODCALLTYPE Test_Stream_SetSize(
686 ULARGE_INTEGER libNewSize)
692 static HRESULT STDMETHODCALLTYPE Test_Stream_CopyTo(
696 ULARGE_INTEGER* pcbRead,
697 ULARGE_INTEGER* pcbWritten)
703 static HRESULT STDMETHODCALLTYPE Test_Stream_Commit(
705 DWORD grfCommitFlags)
711 static HRESULT STDMETHODCALLTYPE Test_Stream_Revert(
718 static HRESULT STDMETHODCALLTYPE Test_Stream_LockRegion(
720 ULARGE_INTEGER libOffset,
728 static HRESULT STDMETHODCALLTYPE Test_Stream_UnlockRegion(
730 ULARGE_INTEGER libOffset,
738 static HRESULT STDMETHODCALLTYPE Test_Stream_Stat(
747 static HRESULT STDMETHODCALLTYPE Test_Stream_Clone(
755 static const IStreamVtbl Test_Stream_Vtbl =
757 Test_Stream_QueryInterface,
767 Test_Stream_LockRegion,
768 Test_Stream_UnlockRegion,
773 static struct my_IStream Test_Stream = { { &Test_Stream_Vtbl }, 0, 0 };
775 static INT DIB_GetWidthBytes( int width, int bpp )
781 case 1: words = (width + 31) / 32; break;
782 case 4: words = (width + 7) / 8; break;
783 case 8: words = (width + 3) / 4; break;
785 case 16: words = (width + 1) / 2; break;
786 case 24: words = (width * 3 + 3)/4; break;
787 case 32: words = width; break;
791 trace("Unknown depth %d, please report.\n", bpp );
798 static void check_bitmap_data(const char *bm_data, ULONG bm_data_size,
799 INT width, INT height, INT bpp,
802 const BITMAPFILEHEADER *bmfh = (const BITMAPFILEHEADER *)bm_data;
803 const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)(bm_data + sizeof(*bmfh));
804 ULONG hdr_size, image_size;
806 hdr_size = sizeof(*bmfh) + sizeof(*bmih);
807 if (bmih->biBitCount <= 8) hdr_size += (1 << bpp) * sizeof(RGBQUAD);
809 ok(bmfh->bfType == (('M' << 8) | 'B'), "wrong bfType 0x%02x\n", bmfh->bfType);
810 ok(bmfh->bfSize == hdr_size, "wrong bfSize 0x%02x\n", bmfh->bfSize);
811 ok(bmfh->bfReserved1 == 0, "wrong bfReserved1 0x%02x\n", bmfh->bfReserved1);
812 ok(bmfh->bfReserved2 == 0, "wrong bfReserved2 0x%02x\n", bmfh->bfReserved2);
813 ok(bmfh->bfOffBits == hdr_size, "wrong bfOffBits 0x%02x\n", bmfh->bfOffBits);
815 ok(bmih->biSize == sizeof(*bmih), "wrong biSize %d\n", bmih->biSize);
816 ok(bmih->biWidth == width, "wrong biWidth %d (expected %d)\n", bmih->biWidth, width);
817 ok(bmih->biHeight == height, "wrong biHeight %d (expected %d)\n", bmih->biHeight, height);
818 ok(bmih->biPlanes == 1, "wrong biPlanes %d\n", bmih->biPlanes);
819 ok(bmih->biBitCount == bpp, "wrong biBitCount %d\n", bmih->biBitCount);
821 image_size = DIB_GetWidthBytes(bmih->biWidth, bmih->biBitCount) * bmih->biHeight;
822 ok(bmih->biSizeImage == image_size, "wrong biSizeImage %u\n", bmih->biSizeImage);
827 sprintf(fname, "bmp_%s.bmp", comment);
828 f = fopen(fname, "wb");
829 fwrite(bm_data, 1, bm_data_size, f);
835 static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max, INT grow)
837 const ILHEAD *ilh = (const ILHEAD *)ilh_data;
839 ok(ilh->usMagic == IMAGELIST_MAGIC, "wrong usMagic %4x (expected %02x)\n", ilh->usMagic, IMAGELIST_MAGIC);
840 ok(ilh->usVersion == 0x101, "wrong usVersion %x (expected 0x101)\n", ilh->usVersion);
841 ok(ilh->cCurImage == cur, "wrong cCurImage %d (expected %d)\n", ilh->cCurImage, cur);
842 ok(ilh->cMaxImage == max, "wrong cMaxImage %d (expected %d)\n", ilh->cMaxImage, max);
843 ok(ilh->cGrow == grow, "wrong cGrow %d (expected %d)\n", ilh->cGrow, grow);
844 ok(ilh->cx == cx, "wrong cx %d (expected %d)\n", ilh->cx, cx);
845 ok(ilh->cy == cy, "wrong cy %d (expected %d)\n", ilh->cy, cy);
846 ok(ilh->bkcolor == CLR_NONE, "wrong bkcolor %x\n", ilh->bkcolor);
847 ok(ilh->flags == ILC_COLOR24, "wrong flags %04x\n", ilh->flags);
848 ok(ilh->ovls[0] == -1 ||
849 ilh->ovls[0] == 0, /* win95 */
850 "wrong ovls[0] %04x\n", ilh->ovls[0]);
851 ok(ilh->ovls[1] == -1 ||
852 ilh->ovls[1] == 0, /* win95 */
853 "wrong ovls[1] %04x\n", ilh->ovls[1]);
854 ok(ilh->ovls[2] == -1 ||
855 ilh->ovls[2] == 0, /* win95 */
856 "wrong ovls[2] %04x\n", ilh->ovls[2]);
857 ok(ilh->ovls[3] == -1 ||
858 ilh->ovls[3] == 0, /* win95 */
859 "wrong ovls[3] %04x\n", ilh->ovls[3]);
862 static HBITMAP create_bitmap(INT cx, INT cy, COLORREF color, const char *comment)
865 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
866 BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
867 HBITMAP hbmp, hbmp_old;
869 RECT rc = { 0, 0, cx, cy };
871 hdc = CreateCompatibleDC(0);
873 memset(bmi, 0, sizeof(*bmi));
874 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
875 bmi->bmiHeader.biHeight = cx;
876 bmi->bmiHeader.biWidth = cy;
877 bmi->bmiHeader.biBitCount = 24;
878 bmi->bmiHeader.biPlanes = 1;
879 bmi->bmiHeader.biCompression = BI_RGB;
880 hbmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
882 hbmp_old = SelectObject(hdc, hbmp);
884 hbrush = CreateSolidBrush(color);
885 FillRect(hdc, &rc, hbrush);
886 DeleteObject(hbrush);
888 DrawText(hdc, comment, -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
890 SelectObject(hdc, hbmp_old);
896 #define iml_clear_stream_data() \
897 HeapFree(GetProcessHeap(), 0, Test_Stream.iml_data); \
898 Test_Stream.iml_data = NULL; \
899 Test_Stream.iml_data_size = 0;
901 static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max, INT grow,
902 INT width, INT height, INT bpp, const char *comment)
906 trace("%s\n", comment);
908 ret = ImageList_GetImageCount(himl);
909 ok(ret == cur, "expected image count %d got %d\n", cur, ret);
911 ret = ImageList_GetIconSize(himl, &cxx, &cyy);
912 ok(ret, "ImageList_GetIconSize failed\n");
913 ok(cxx == cx, "wrong cx %d (expected %d)\n", cxx, cx);
914 ok(cyy == cy, "wrong cy %d (expected %d)\n", cyy, cy);
916 iml_clear_stream_data();
917 ret = ImageList_Write(himl, &Test_Stream.is);
918 ok(ret, "ImageList_Write failed\n");
920 ok(Test_Stream.iml_data != 0, "ImageList_Write didn't write any data\n");
921 ok(Test_Stream.iml_data_size > sizeof(ILHEAD), "ImageList_Write wrote not enough data\n");
923 check_ilhead_data(Test_Stream.iml_data, cx, cy, cur, max, grow);
924 check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD),
925 Test_Stream.iml_data_size - sizeof(ILHEAD),
926 width, height, bpp, comment);
929 static void image_list_init(HIMAGELIST himl)
934 static const struct test_data
937 INT cx, cy, cur, max, grow, width, height, bpp;
941 { 255, BMP_CX, BMP_CX, 1, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "total 1" },
942 { 170, BMP_CX, BMP_CX, 2, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 2" },
943 { 85, BMP_CX, BMP_CX, 3, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 3" },
944 { 0, BMP_CX, BMP_CX, 4, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 4" },
945 { 0, BMP_CX, BMP_CX, 5, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 5" },
946 { 85, BMP_CX, BMP_CX, 6, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 6" },
947 { 170, BMP_CX, BMP_CX, 7, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 7" },
948 { 255, BMP_CX, BMP_CX, 8, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 8" },
949 { 255, BMP_CX, BMP_CX, 9, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 9" },
950 { 170, BMP_CX, BMP_CX, 10, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 10" },
951 { 85, BMP_CX, BMP_CX, 11, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 11" },
952 { 0, BMP_CX, BMP_CX, 12, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 12" },
953 { 0, BMP_CX, BMP_CX, 13, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 13" },
954 { 85, BMP_CX, BMP_CX, 14, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 14" },
955 { 170, BMP_CX, BMP_CX, 15, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 15" },
956 { 255, BMP_CX, BMP_CX, 16, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 16" },
957 { 255, BMP_CX, BMP_CX, 17, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 17" },
958 { 170, BMP_CX, BMP_CX, 18, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 18" },
959 { 85, BMP_CX, BMP_CX, 19, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 19" },
960 { 0, BMP_CX, BMP_CX, 20, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 20" },
961 { 0, BMP_CX, BMP_CX, 21, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 21" },
962 { 85, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 22" },
963 { 170, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 23" },
964 { 255, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 24" }
967 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "total 0");
969 #define add_bitmap(grey) \
970 sprintf(comment, "%d", n++); \
971 hbm = create_bitmap(BMP_CX, BMP_CX, RGB((grey),(grey),(grey)), comment); \
972 ImageList_Add(himl, hbm, NULL); \
975 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
977 add_bitmap(td[i].grey);
978 check_iml_data(himl, td[i].cx, td[i].cy, td[i].cur, td[i].max, td[i].grow,
979 td[i].width, td[i].height, td[i].bpp, td[i].comment);
984 static void test_imagelist_storage(void)
990 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 1, 1);
991 ok(himl != 0, "ImageList_Create failed\n");
993 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "empty");
995 image_list_init(himl);
996 check_iml_data(himl, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "orig");
998 ret = ImageList_Remove(himl, 4);
999 ok(ret, "ImageList_Remove failed\n");
1000 check_iml_data(himl, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "1");
1002 ret = ImageList_Remove(himl, 5);
1003 ok(ret, "ImageList_Remove failed\n");
1004 check_iml_data(himl, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "2");
1006 ret = ImageList_Remove(himl, 6);
1007 ok(ret, "ImageList_Remove failed\n");
1008 check_iml_data(himl, BMP_CX, BMP_CX, 21, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "3");
1010 ret = ImageList_Remove(himl, 7);
1011 ok(ret, "ImageList_Remove failed\n");
1012 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "4");
1014 ret = ImageList_Remove(himl, -2);
1015 ok(!ret, "ImageList_Remove(-2) should fail\n");
1016 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "5");
1018 ret = ImageList_Remove(himl, 20);
1019 ok(!ret, "ImageList_Remove(20) should fail\n");
1020 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "6");
1022 ret = ImageList_Remove(himl, -1);
1023 ok(ret, "ImageList_Remove(-1) failed\n");
1024 check_iml_data(himl, BMP_CX, BMP_CX, 0, 4, 4, BMP_CX * 4, BMP_CX * 1, 24, "7");
1026 ret = ImageList_Destroy(himl);
1027 ok(ret, "ImageList_Destroy failed\n");
1029 iml_clear_stream_data();
1031 /* test ImageList_Create storage allocation */
1033 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 0, 32);
1034 ok(himl != 0, "ImageList_Create failed\n");
1035 check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 32, BMP_CX * 4, BMP_CX * 1, 24, "init 0 grow 32");
1036 hbm = create_bitmap(BMP_CX * 9, BMP_CX, 0, "9");
1037 ret = ImageList_Add(himl, hbm, NULL);
1038 ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
1039 check_iml_data(himl, BMP_CX, BMP_CX, 1, 34, 32, BMP_CX * 4, BMP_CX * 9, 24, "add 1 x 9");
1041 ret = ImageList_Destroy(himl);
1042 ok(ret, "ImageList_Destroy failed\n");
1043 iml_clear_stream_data();
1045 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 4);
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, 24, "init 4 grow 4");
1048 hbm = create_bitmap(BMP_CX, BMP_CX * 9, 0, "9");
1049 ret = ImageList_Add(himl, hbm, NULL);
1050 ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
1051 check_iml_data(himl, BMP_CX, BMP_CX, 9, 15, 4, BMP_CX * 4, BMP_CX * 4, 24, "add 9 x 1");
1052 ret = ImageList_Add(himl, hbm, NULL);
1053 ok(ret == 9, "ImageList_Add returned %d, expected 9\n", ret);
1054 check_iml_data(himl, BMP_CX, BMP_CX, 18, 25, 4, BMP_CX * 4, BMP_CX * 7, 24, "add 9 x 1");
1056 ret = ImageList_Destroy(himl);
1057 ok(ret, "ImageList_Destroy failed\n");
1058 iml_clear_stream_data();
1060 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 207, 209);
1061 ok(himl != 0, "ImageList_Create failed\n");
1062 check_iml_data(himl, BMP_CX, BMP_CX, 0, 208, 212, BMP_CX * 4, BMP_CX * 52, 24, "init 207 grow 209");
1063 ret = ImageList_Destroy(himl);
1064 ok(ret, "ImageList_Destroy failed\n");
1065 iml_clear_stream_data();
1067 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 209, 207);
1068 ok(himl != 0, "ImageList_Create failed\n");
1069 check_iml_data(himl, BMP_CX, BMP_CX, 0, 210, 208, BMP_CX * 4, BMP_CX * 53, 24, "init 209 grow 207");
1070 ret = ImageList_Destroy(himl);
1071 ok(ret, "ImageList_Destroy failed\n");
1072 iml_clear_stream_data();
1074 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 14, 4);
1075 ok(himl != 0, "ImageList_Create failed\n");
1076 check_iml_data(himl, BMP_CX, BMP_CX, 0, 15, 4, BMP_CX * 4, BMP_CX * 4, 24, "init 14 grow 4");
1077 ret = ImageList_Destroy(himl);
1078 ok(ret, "ImageList_Destroy failed\n");
1079 iml_clear_stream_data();
1081 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 5, 9);
1082 ok(himl != 0, "ImageList_Create failed\n");
1083 check_iml_data(himl, BMP_CX, BMP_CX, 0, 6, 12, BMP_CX * 4, BMP_CX * 2, 24, "init 5 grow 9");
1084 ret = ImageList_Destroy(himl);
1085 ok(ret, "ImageList_Destroy failed\n");
1086 iml_clear_stream_data();
1088 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 9, 5);
1089 ok(himl != 0, "ImageList_Create failed\n");
1090 check_iml_data(himl, BMP_CX, BMP_CX, 0, 10, 8, BMP_CX * 4, BMP_CX * 3, 24, "init 9 grow 5");
1091 ret = ImageList_Destroy(himl);
1092 ok(ret, "ImageList_Destroy failed\n");
1093 iml_clear_stream_data();
1095 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 2, 4);
1096 ok(himl != 0, "ImageList_Create failed\n");
1097 check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX * 1, 24, "init 2 grow 4");
1098 ret = ImageList_Destroy(himl);
1099 ok(ret, "ImageList_Destroy failed\n");
1100 iml_clear_stream_data();
1102 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 2);
1103 ok(himl != 0, "ImageList_Create failed\n");
1104 check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, 24, "init 4 grow 2");
1105 ret = ImageList_Destroy(himl);
1106 ok(ret, "ImageList_Destroy failed\n");
1107 iml_clear_stream_data();
1110 static void test_shell_imagelist(void)
1112 BOOL (WINAPI *pSHGetImageList)(INT, REFIID, void**);
1113 IImageList *iml = NULL;
1120 /* Try to load function from shell32 */
1121 hShell32 = LoadLibrary("shell32.dll");
1122 pSHGetImageList = (void*)GetProcAddress(hShell32, (LPCSTR) 727);
1124 if (!pSHGetImageList)
1126 win_skip("SHGetImageList not available, skipping test\n");
1130 /* Get system image list */
1131 hr = (pSHGetImageList)(SHIL_SYSSMALL, &IID_IImageList, (void**)&iml);
1133 ok(SUCCEEDED(hr), "SHGetImageList failed, hr=%x\n", hr);
1138 IImageList_GetImageCount(iml, &out);
1139 ok(out > 0, "IImageList_GetImageCount returned out <= 0\n");
1141 /* Fetch the small icon size */
1142 cx = GetSystemMetrics(SM_CXSMICON);
1143 cy = GetSystemMetrics(SM_CYSMICON);
1145 /* Check icon size matches */
1146 IImageList_GetImageRect(iml, 0, &rect);
1147 ok(((rect.right == cx) && (rect.bottom == cy)),
1148 "IImageList_GetImageRect returned r:%d,b:%d\n",
1149 rect.right, rect.bottom);
1151 IImageList_Release(iml);
1152 FreeLibrary(hShell32);
1155 static HBITMAP create_test_bitmap(HDC hdc, int bpp, UINT32 pixel1, UINT32 pixel2)
1158 UINT32 *buffer = NULL;
1159 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, bpp, BI_RGB,
1162 hBitmap = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, NULL, 0);
1163 ok(hBitmap != NULL && buffer != NULL, "CreateDIBSection failed.\n");
1165 if(!hBitmap || !buffer)
1167 DeleteObject(hBitmap);
1177 static BOOL colour_match(UINT32 x, UINT32 y)
1179 const INT32 tolerance = 8;
1181 const INT32 dr = abs((INT32)(x & 0x000000FF) - (INT32)(y & 0x000000FF));
1182 const INT32 dg = abs((INT32)((x & 0x0000FF00) >> 8) - (INT32)((y & 0x0000FF00) >> 8));
1183 const INT32 db = abs((INT32)((x & 0x00FF0000) >> 16) - (INT32)((y & 0x00FF0000) >> 16));
1185 return (dr <= tolerance && dg <= tolerance && db <= tolerance);
1188 static void check_ImageList_DrawIndirect(IMAGELISTDRAWPARAMS *ildp, UINT32 *bits,
1189 UINT32 expected, int line)
1191 bits[0] = 0x00FFFFFF;
1192 pImageList_DrawIndirect(ildp);
1193 ok(colour_match(bits[0], expected),
1194 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1195 bits[0] & 0x00FFFFFF, expected, line);
1199 static void check_ImageList_DrawIndirect_fStyle(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1200 UINT fStyle, UINT32 expected, int line)
1202 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1203 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, ILS_NORMAL, 0, 0x00000000};
1204 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1207 static void check_ImageList_DrawIndirect_ILD_ROP(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1208 DWORD dwRop, UINT32 expected, int line)
1210 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1211 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_IMAGE | ILD_ROP, dwRop, ILS_NORMAL, 0, 0x00000000};
1212 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1215 static void check_ImageList_DrawIndirect_fState(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i, UINT fStyle,
1216 UINT fState, DWORD Frame, UINT32 expected, int line)
1218 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1219 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1220 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1223 static void check_ImageList_DrawIndirect_broken(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1224 UINT fStyle, UINT fState, DWORD Frame, UINT32 expected,
1225 UINT32 broken_expected, int line)
1227 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1228 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1229 bits[0] = 0x00FFFFFF;
1230 pImageList_DrawIndirect(&ildp);
1231 ok(colour_match(bits[0], expected) ||
1232 broken(colour_match(bits[0], broken_expected)),
1233 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1234 bits[0] & 0x00FFFFFF, expected, line);
1237 static void test_ImageList_DrawIndirect(void)
1239 HIMAGELIST himl = NULL;
1242 HBITMAP hbmOld = NULL, hbmDst = NULL;
1243 HBITMAP hbmMask = NULL, hbmInverseMask = NULL;
1244 HBITMAP hbmImage = NULL, hbmAlphaImage = NULL, hbmTransparentImage = NULL;
1245 int iImage = -1, iAlphaImage = -1, iTransparentImage = -1;
1247 UINT32 maskBits = 0x00000000, inverseMaskBits = 0xFFFFFFFF;
1249 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB,
1252 hdcDst = CreateCompatibleDC(0);
1253 ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
1257 hbmMask = CreateBitmap(2, 1, 1, 1, &maskBits);
1258 ok(hbmMask != 0, "CreateBitmap failed\n");
1259 if(!hbmMask) goto cleanup;
1261 hbmInverseMask = CreateBitmap(2, 1, 1, 1, &inverseMaskBits);
1262 ok(hbmInverseMask != 0, "CreateBitmap failed\n");
1263 if(!hbmInverseMask) goto cleanup;
1265 himl = pImageList_Create(2, 1, ILC_COLOR32, 0, 1);
1266 ok(himl != 0, "ImageList_Create failed\n");
1267 if(!himl) goto cleanup;
1269 /* Add a no-alpha image */
1270 hbmImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x00ABCDEF);
1271 if(!hbmImage) goto cleanup;
1273 iImage = pImageList_Add(himl, hbmImage, hbmMask);
1274 ok(iImage != -1, "ImageList_Add failed\n");
1275 if(iImage == -1) goto cleanup;
1277 /* Add an alpha image */
1278 hbmAlphaImage = create_test_bitmap(hdcDst, 32, 0x89ABCDEF, 0x89ABCDEF);
1279 if(!hbmAlphaImage) goto cleanup;
1281 iAlphaImage = pImageList_Add(himl, hbmAlphaImage, hbmMask);
1282 ok(iAlphaImage != -1, "ImageList_Add failed\n");
1283 if(iAlphaImage == -1) goto cleanup;
1285 /* Add a transparent alpha image */
1286 hbmTransparentImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x89ABCDEF);
1287 if(!hbmTransparentImage) goto cleanup;
1289 iTransparentImage = pImageList_Add(himl, hbmTransparentImage, hbmMask);
1290 ok(iTransparentImage != -1, "ImageList_Add failed\n");
1291 if(iTransparentImage == -1) goto cleanup;
1294 bitmapInfo.bmiHeader.biBitCount = 32;
1295 hbmDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1296 ok (hbmDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1297 if (!hbmDst || !bits)
1299 hbmOld = SelectObject(hdcDst, hbmDst);
1301 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_NORMAL, 0x00ABCDEF, __LINE__);
1302 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_TRANSPARENT, 0x00ABCDEF, __LINE__);
1303 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x00D4D9DD, __LINE__);
1304 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, 0x00B4BDC4, __LINE__);
1305 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_MASK, 0x00ABCDEF, __LINE__);
1306 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_IMAGE, 0x00ABCDEF, __LINE__);
1307 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_PRESERVEALPHA, 0x00ABCDEF, __LINE__);
1309 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, 0x00D3E5F7, __LINE__);
1310 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_TRANSPARENT, 0x00D3E5F7, __LINE__);
1313 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x009DA8B1, __LINE__);
1314 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, 0x008C99A3, __LINE__);
1317 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0x00D3E5F7, __LINE__);
1318 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0x00D3E5F7, __LINE__);
1319 todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__);
1321 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__);
1323 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCCOPY, 0x00ABCDEF, __LINE__);
1324 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCINVERT, 0x00543210, __LINE__);
1326 /* ILD_ROP is ignored when the image has an alpha channel */
1327 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCCOPY, 0x00D3E5F7, __LINE__);
1328 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCINVERT, 0x00D3E5F7, __LINE__);
1330 todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00CCCCCC, __LINE__);
1331 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00AFAFAF, 0x00F0F0F0, __LINE__);
1333 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_GLOW, 0, 0x00ABCDEF, __LINE__);
1334 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SHADOW, 0, 0x00ABCDEF, __LINE__);
1336 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00D5E6F7, __LINE__);
1337 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00E9F2FB, 0x00AEB7C0, __LINE__);
1338 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_NORMAL, 127, 0x00E9F2FB, 0x00D3E5F7, __LINE__);
1343 SelectObject(hdcDst, hbmOld);
1345 DeleteObject(hbmDst);
1351 DeleteObject(hbmMask);
1353 DeleteObject(hbmInverseMask);
1356 DeleteObject(hbmImage);
1358 DeleteObject(hbmAlphaImage);
1359 if(hbmTransparentImage)
1360 DeleteObject(hbmTransparentImage);
1364 ret = ImageList_Destroy(himl);
1365 ok(ret, "ImageList_Destroy failed\n");
1369 static void test_iimagelist(void)
1376 if (!pHIMAGELIST_QueryInterface)
1378 win_skip("XP imagelist functions not available\n");
1382 /* test reference counting on destruction */
1383 imgl = (IImageList*)createImageList(32, 32);
1384 ret = IUnknown_AddRef(imgl);
1385 ok(ret == 2, "Expected 2, got %d\n", ret);
1386 ret = ImageList_Destroy((HIMAGELIST)imgl);
1387 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1388 ret = ImageList_Destroy((HIMAGELIST)imgl);
1389 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1390 ret = ImageList_Destroy((HIMAGELIST)imgl);
1391 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1393 imgl = (IImageList*)createImageList(32, 32);
1394 ret = IUnknown_AddRef(imgl);
1395 ok(ret == 2, "Expected 2, got %d\n", ret);
1396 ret = ImageList_Destroy((HIMAGELIST)imgl);
1397 ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
1398 ret = IImageList_Release(imgl);
1399 ok(ret == 0, "Expected 0, got %d\n", ret);
1400 ret = ImageList_Destroy((HIMAGELIST)imgl);
1401 ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
1403 if (!pImageList_CoCreateInstance)
1405 win_skip("Vista imagelist functions not available\n");
1409 hr = pImageList_CoCreateInstance(&CLSID_ImageList, NULL, &IID_IImageList, (void **) &imgl);
1410 ok(SUCCEEDED(hr), "ImageList_CoCreateInstance failed, hr=%x\n", hr);
1413 IImageList_Release(imgl);
1415 himl = createImageList(32, 32);
1420 hr = (pHIMAGELIST_QueryInterface)(himl, &IID_IImageList, (void **) &imgl);
1421 ok(SUCCEEDED(hr), "HIMAGELIST_QueryInterface failed, hr=%x\n", hr);
1424 IImageList_Release(imgl);
1426 ImageList_Destroy(himl);
1429 static void testHotspot_v6(void)
1440 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
1441 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
1448 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
1449 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
1450 IImageList *imgl1, *imgl2;
1453 /* cast to IImageList */
1454 imgl1 = (IImageList *) himl1;
1455 imgl2 = (IImageList *) himl2;
1457 for (i = 0; i < HOTSPOTS_MAX; i++) {
1458 for (j = 0; j < HOTSPOTS_MAX; j++) {
1459 int dx1 = hotspots[i].dx;
1460 int dy1 = hotspots[i].dy;
1461 int dx2 = hotspots[j].dx;
1462 int dy2 = hotspots[j].dy;
1463 int correctx, correcty, newx, newy;
1465 IImageList *imglNew;
1468 hr = IImageList_BeginDrag(imgl1, 0, dx1, dy1);
1469 ok(SUCCEEDED(hr), "BeginDrag failed for { %d, %d }\n", dx1, dy1);
1470 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
1472 /* check merging the dragged image with a second image */
1473 hr = IImageList_SetDragCursorImage(imgl2, (IUnknown *) imgl2, 0, dx2, dy2);
1474 ok(SUCCEEDED(hr), "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
1475 dx1, dy1, dx2, dy2);
1476 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
1478 /* check new hotspot, it should be the same like the old one */
1479 hr = IImageList_GetDragImage(imgl2, NULL, &ppt, &IID_IImageList, (PVOID *) &imglNew);
1480 ok(SUCCEEDED(hr), "GetDragImage failed\n");
1481 ok(ppt.x == dx1 && ppt.y == dy1,
1482 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
1483 dx1, dy1, ppt.x, ppt.y);
1484 /* check size of new dragged image */
1485 IImageList_GetIconSize(imglNew, &newx, &newy);
1486 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
1487 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
1488 ok(newx == correctx && newy == correcty,
1489 "Expected drag image size [%d,%d] got [%d,%d]\n",
1490 correctx, correcty, newx, newy);
1491 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
1492 IImageList_EndDrag(imgl2);
1500 IImageList_Release(imgl2);
1501 IImageList_Release(imgl1);
1504 static void DoTest1_v6(void)
1516 /* create an imagelist to play with */
1517 himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
1518 ok(himl != 0,"failed to create imagelist\n");
1520 imgl = (IImageList *) himl;
1522 /* load the icons to add to the image list */
1523 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1524 ok(hicon1 != 0, "no hicon1\n");
1525 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1526 ok(hicon2 != 0, "no hicon2\n");
1527 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1528 ok(hicon3 != 0, "no hicon3\n");
1530 /* remove when nothing exists */
1531 hr = IImageList_Remove(imgl, 0);
1532 ok(!(SUCCEEDED(hr)), "removed nonexistent icon\n");
1534 /* removing everything from an empty imagelist should succeed */
1535 hr = IImageList_Remove(imgl, -1);
1536 ok(SUCCEEDED(hr), "removed nonexistent icon\n");
1539 ok(SUCCEEDED(IImageList_ReplaceIcon(imgl, -1, hicon1, &ret)) && (ret == 0),"failed to add icon1\n");
1540 ok(SUCCEEDED(IImageList_ReplaceIcon(imgl, -1, hicon2, &ret)) && (ret == 1),"failed to add icon2\n");
1541 ok(SUCCEEDED(IImageList_ReplaceIcon(imgl, -1, hicon3, &ret)) && (ret == 2),"failed to add icon3\n");
1543 /* remove an index out of range */
1544 ok(FAILED(IImageList_Remove(imgl, 4711)),"removed nonexistent icon\n");
1547 ok(SUCCEEDED(IImageList_Remove(imgl,0)),"can't remove 0\n");
1548 ok(SUCCEEDED(IImageList_Remove(imgl,0)),"can't remove 0\n");
1549 ok(SUCCEEDED(IImageList_Remove(imgl,0)),"can't remove 0\n");
1551 /* remove one extra */
1552 ok(FAILED(IImageList_Remove(imgl, 0)),"removed nonexistent icon\n");
1554 /* check SetImageCount/GetImageCount */
1555 ok(SUCCEEDED(IImageList_SetImageCount(imgl, 3)), "couldn't increase image count\n");
1556 ok(SUCCEEDED(IImageList_GetImageCount(imgl, &ret)) && (ret == 3), "invalid image count after increase\n");
1557 ok(SUCCEEDED(IImageList_SetImageCount(imgl, 1)), "couldn't decrease image count\n");
1558 ok(SUCCEEDED(IImageList_GetImageCount(imgl, &ret)) && (ret == 1), "invalid image count after decrease to 1\n");
1559 ok(SUCCEEDED(IImageList_SetImageCount(imgl, 0)), "couldn't decrease image count\n");
1560 ok(SUCCEEDED(IImageList_GetImageCount(imgl, &ret)) && (ret == 0), "invalid image count after decrease to 0\n");
1563 ok(SUCCEEDED(IImageList_Release(imgl)),"release imagelist failed\n");
1565 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
1566 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
1567 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
1570 static void DoTest3_v6(void)
1579 IMAGELISTDRAWPARAMS imldp;
1584 hwndfortest = create_a_window();
1585 hdc = GetDC(hwndfortest);
1586 ok(hdc!=NULL, "couldn't get DC\n");
1588 /* create an imagelist to play with */
1589 himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
1590 ok(himl!=0,"failed to create imagelist\n");
1592 imgl = (IImageList *) himl;
1594 /* load the icons to add to the image list */
1595 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1596 ok(hbm1 != 0, "no bitmap 1\n");
1597 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1598 ok(hbm2 != 0, "no bitmap 2\n");
1599 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
1600 ok(hbm3 != 0, "no bitmap 3\n");
1603 ok(SUCCEEDED(IImageList_Add(imgl, hbm1, 0, &ret)) && (ret == 0), "failed to add bitmap 1\n");
1604 ok(SUCCEEDED(IImageList_Add(imgl, hbm2, 0, &ret)) && (ret == 1), "failed to add bitmap 2\n");
1606 ok(SUCCEEDED(IImageList_SetImageCount(imgl, 3)), "Setimage count failed\n");
1607 ok(SUCCEEDED(IImageList_Replace(imgl, 2, hbm3, 0)), "failed to replace bitmap 3\n");
1609 memset(&imldp, 0, sizeof (imldp));
1610 ok(FAILED(IImageList_Draw(imgl, &imldp)), "zero data succeeded!\n");
1612 imldp.cbSize = sizeof (imldp);
1616 if (FAILED(IImageList_Draw(imgl, &imldp)))
1618 /* Earlier versions of native comctl32 use a smaller structure */
1619 imldp.cbSize -= 3 * sizeof(DWORD);
1620 ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n");
1623 REDRAW(hwndfortest);
1626 imldp.fStyle = SRCCOPY;
1627 imldp.rgbBk = CLR_DEFAULT;
1628 imldp.rgbFg = CLR_DEFAULT;
1631 ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n");
1633 ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n");
1635 ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n");
1637 ok(FAILED(IImageList_Draw(imgl, &imldp)), "should fail\n");
1640 ok(SUCCEEDED(IImageList_Remove(imgl, 0)), "removing 1st bitmap\n");
1641 ok(SUCCEEDED(IImageList_Remove(imgl, 0)), "removing 2nd bitmap\n");
1642 ok(SUCCEEDED(IImageList_Remove(imgl, 0)), "removing 3rd bitmap\n");
1645 ok(SUCCEEDED(IImageList_Release(imgl)), "release imagelist failed\n");
1647 /* bitmaps should not be deleted by the imagelist */
1648 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
1649 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
1650 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
1652 ReleaseDC(hwndfortest, hdc);
1653 DestroyWindow(hwndfortest);
1656 static void testMerge_v6(void)
1658 HIMAGELIST himl1, himl2;
1659 IImageList *imgl1, *imgl2, *merge;
1661 HWND hwnd = create_a_window();
1665 himl1 = ImageList_Create(32,32,0,0,3);
1666 ok(himl1 != NULL,"failed to create himl1\n");
1668 himl2 = ImageList_Create(32,32,0,0,3);
1669 ok(himl2 != NULL,"failed to create himl2\n");
1671 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
1672 ok(hicon1 != NULL, "failed to create hicon1\n");
1674 if (!himl1 || !himl2 || !hicon1)
1677 /* cast to IImageList */
1678 imgl1 = (IImageList *) himl1;
1679 imgl2 = (IImageList *) himl2;
1681 ok(SUCCEEDED(IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret)) && (ret == 0),"add icon1 to himl2 failed\n");
1683 /* If himl1 has no images, merge still succeeds */
1684 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1685 ok(SUCCEEDED(hr), "merge himl1,-1 failed\n");
1686 if (SUCCEEDED(hr)) IImageList_Release(merge);
1688 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1689 ok(SUCCEEDED(hr), "merge himl1,0 failed\n");
1690 if (SUCCEEDED(hr)) IImageList_Release(merge);
1692 /* Same happens if himl2 is empty */
1693 IImageList_Release(imgl2);
1694 himl2 = ImageList_Create(32,32,0,0,3);
1695 ok(himl2 != NULL,"failed to recreate himl2\n");
1697 imgl2 = (IImageList *) himl2;
1699 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, -1, 0, 0, &IID_IImageList, (void **) &merge);
1700 ok(SUCCEEDED(hr), "merge himl2,-1 failed\n");
1701 if (SUCCEEDED(hr)) IImageList_Release(merge);
1703 hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1704 ok(SUCCEEDED(hr), "merge himl2,0 failed\n");
1705 if (SUCCEEDED(hr)) IImageList_Release(merge);
1707 /* Now try merging an image with itself */
1708 ok(SUCCEEDED(IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret)) && (ret == 0),"re-add icon1 to himl2 failed\n");
1710 hr = IImageList_Merge(imgl2, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1711 ok(SUCCEEDED(hr), "merge himl2 with itself failed\n");
1712 if (SUCCEEDED(hr)) IImageList_Release(merge);
1714 /* Try merging 2 different image lists */
1715 ok(SUCCEEDED(IImageList_ReplaceIcon(imgl1, -1, hicon1, &ret)) && (ret == 0),"add icon1 to himl1 failed\n");
1717 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
1718 ok(SUCCEEDED(hr), "merge himl1 with himl2 failed\n");
1719 if (SUCCEEDED(hr)) IImageList_Release(merge);
1721 hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 8, 16, &IID_IImageList, (void **) &merge);
1722 ok(SUCCEEDED(hr), "merge himl1 with himl2 8,16 failed\n");
1723 if (SUCCEEDED(hr)) IImageList_Release(merge);
1725 IImageList_Release(imgl1);
1726 IImageList_Release(imgl2);
1728 DestroyIcon(hicon1);
1729 DestroyWindow(hwnd);
1732 START_TEST(imagelist)
1734 ULONG_PTR ctx_cookie;
1737 HMODULE hComCtl32 = GetModuleHandle("comctl32.dll");
1738 pImageList_Create = NULL; /* These are not needed for non-v6.0 tests*/
1739 pImageList_Add = NULL;
1740 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
1741 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
1743 hinst = GetModuleHandleA(NULL);
1745 InitCommonControls();
1752 test_imagelist_storage();
1754 FreeLibrary(hComCtl32);
1756 /* Now perform v6 tests */
1758 if (!load_v6_module(&ctx_cookie, &hCtx))
1761 /* Reload comctl32 */
1762 hComCtl32 = LoadLibraryA("comctl32.dll");
1763 pImageList_Create = (void*)GetProcAddress(hComCtl32, "ImageList_Create");
1764 pImageList_Add = (void*)GetProcAddress(hComCtl32, "ImageList_Add");
1765 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
1766 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
1767 pImageList_CoCreateInstance = (void*)GetProcAddress(hComCtl32, "ImageList_CoCreateInstance");
1768 pHIMAGELIST_QueryInterface = (void*)GetProcAddress(hComCtl32, "HIMAGELIST_QueryInterface");
1770 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1773 test_ImageList_DrawIndirect();
1774 test_shell_imagelist();
1784 unload_v6_module(ctx_cookie, hCtx);