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
35 #include "commctrl.h" /* must be included after objbase.h to get ImageList_Write */
37 #include "commoncontrols.h"
40 #include "wine/test.h"
42 #include "resources.h"
44 #define IMAGELIST_MAGIC (('L' << 8) | 'I')
47 /* Header used by ImageList_Read() and ImageList_Write() */
48 typedef struct _ILHEAD
63 static HIMAGELIST (WINAPI
*pImageList_Create
)(int, int, UINT
, int, int);
64 static BOOL (WINAPI
*pImageList_Destroy
)(HIMAGELIST
);
65 static int (WINAPI
*pImageList_Add
)(HIMAGELIST
, HBITMAP
, HBITMAP
);
66 static int (WINAPI
*pImageList_AddMasked
)(HIMAGELIST
, HBITMAP
, COLORREF
);
67 static BOOL (WINAPI
*pImageList_DrawIndirect
)(IMAGELISTDRAWPARAMS
*);
68 static BOOL (WINAPI
*pImageList_SetImageCount
)(HIMAGELIST
,UINT
);
69 static HRESULT (WINAPI
*pImageList_CoCreateInstance
)(REFCLSID
,const IUnknown
*,
71 static HRESULT (WINAPI
*pHIMAGELIST_QueryInterface
)(HIMAGELIST
,REFIID
,void **);
72 static int (WINAPI
*pImageList_SetColorTable
)(HIMAGELIST
,int,int,RGBQUAD
*);
73 static DWORD (WINAPI
*pImageList_GetFlags
)(HIMAGELIST
);
74 static BOOL (WINAPI
*pImageList_BeginDrag
)(HIMAGELIST
, int, int, int);
75 static HIMAGELIST (WINAPI
*pImageList_GetDragImage
)(POINT
*, POINT
*);
76 static void (WINAPI
*pImageList_EndDrag
)(void);
77 static INT (WINAPI
*pImageList_GetImageCount
)(HIMAGELIST
);
78 static BOOL (WINAPI
*pImageList_SetDragCursorImage
)(HIMAGELIST
, int, int, int);
79 static BOOL (WINAPI
*pImageList_GetIconSize
)(HIMAGELIST
, int *, int *);
80 static BOOL (WINAPI
*pImageList_SetIconSize
)(HIMAGELIST
, INT
, INT
);
81 static BOOL (WINAPI
*pImageList_Remove
)(HIMAGELIST
, int);
82 static INT (WINAPI
*pImageList_ReplaceIcon
)(HIMAGELIST
, int, HICON
);
83 static BOOL (WINAPI
*pImageList_Replace
)(HIMAGELIST
, int, HBITMAP
, HBITMAP
);
84 static HIMAGELIST (WINAPI
*pImageList_Merge
)(HIMAGELIST
, int, HIMAGELIST
, int, int, int);
85 static BOOL (WINAPI
*pImageList_GetImageInfo
)(HIMAGELIST
, int, IMAGEINFO
*);
86 static BOOL (WINAPI
*pImageList_Write
)(HIMAGELIST
, IStream
*);
87 static HIMAGELIST (WINAPI
*pImageList_Read
)(IStream
*);
88 static BOOL (WINAPI
*pImageList_Copy
)(HIMAGELIST
, int, HIMAGELIST
, int, UINT
);
89 static HIMAGELIST (WINAPI
*pImageList_LoadImageW
)(HINSTANCE
, LPCWSTR
, int, int, COLORREF
, UINT
, UINT
);
90 static BOOL (WINAPI
*pImageList_Draw
)(HIMAGELIST
,INT
,HDC
,INT
,INT
,UINT
);
92 static HINSTANCE hinst
;
94 /* only used in interactive mode */
95 static void force_redraw(HWND hwnd
)
97 if (!winetest_interactive
)
100 RedrawWindow(hwnd
, NULL
, 0, RDW_UPDATENOW
);
104 static BOOL
is_v6_test(void)
106 return pHIMAGELIST_QueryInterface
!= NULL
;
109 /* These macros build cursor/bitmap data in 4x4 pixel blocks */
110 #define B(x,y) ((x?0xf0:0)|(y?0xf:0))
111 #define ROW1(a,b,c,d,e,f,g,h) B(a,b),B(c,d),B(e,f),B(g,h)
112 #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), \
113 ROW1(a,b,c,d,e,f,g,h), ROW1(a,b,c,d,e,f,g,h)
114 #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)
115 #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), \
116 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), \
117 ROW2(a,b,c,d,e,f,g,h,i,j,k,l)
119 static const BYTE empty_bits
[48*48/8];
121 static const BYTE icon_bits
[32*32/8] =
123 ROW32(0,0,0,0,0,0,0,0),
124 ROW32(0,0,1,1,1,1,0,0),
125 ROW32(0,1,1,1,1,1,1,0),
126 ROW32(0,1,1,0,0,1,1,0),
127 ROW32(0,1,1,0,0,1,1,0),
128 ROW32(0,1,1,1,1,1,1,0),
129 ROW32(0,0,1,1,1,1,0,0),
130 ROW32(0,0,0,0,0,0,0,0)
133 static const BYTE bitmap_bits
[48*48/8] =
135 ROW48(0,0,0,0,0,0,0,0,0,0,0,0),
136 ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
137 ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
138 ROW48(0,1,0,0,0,0,0,0,1,0,1,0),
139 ROW48(0,1,0,0,0,0,0,1,0,0,1,0),
140 ROW48(0,1,0,0,0,0,1,0,0,0,1,0),
141 ROW48(0,1,0,0,0,1,0,0,0,0,1,0),
142 ROW48(0,1,0,0,1,0,0,0,0,0,1,0),
143 ROW48(0,1,0,1,0,0,0,0,0,0,1,0),
144 ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
145 ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
146 ROW48(0,0,0,0,0,0,0,0,0,0,0,0)
149 static HIMAGELIST
createImageList(int cx
, int cy
)
151 /* Create an ImageList and put an image into it */
152 HIMAGELIST himl
= pImageList_Create(cx
, cy
, ILC_COLOR
, 1, 1);
153 HBITMAP hbm
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
155 ok(himl
!= NULL
, "Failed to create image list, %d x %d.\n", cx
, cy
);
156 pImageList_Add(himl
, hbm
, NULL
);
161 static HWND
create_window(void)
163 char className
[] = "bmwnd";
164 char winName
[] = "Test Bitmap";
166 static BOOL registered
= FALSE
;
172 cls
.style
= CS_HREDRAW
| CS_VREDRAW
| CS_GLOBALCLASS
;
173 cls
.lpfnWndProc
= DefWindowProcA
;
177 cls
.hIcon
= LoadIconA(0, (LPCSTR
)IDI_APPLICATION
);
178 cls
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
179 cls
.hbrBackground
= GetStockObject (WHITE_BRUSH
);
180 cls
.lpszMenuName
= 0;
181 cls
.lpszClassName
= className
;
183 RegisterClassA (&cls
);
188 hWnd
= CreateWindowA (className
, winName
,
189 WS_OVERLAPPEDWINDOW
,
190 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
193 if (winetest_interactive
)
195 ShowWindow (hWnd
, SW_SHOW
);
202 static HDC
show_image(HWND hwnd
, HIMAGELIST himl
, int idx
, int size
,
203 LPCSTR loc
, BOOL clear
)
207 if (!winetest_interactive
|| !himl
) return NULL
;
209 SetWindowTextA(hwnd
, loc
);
211 pImageList_Draw(himl
, idx
, hdc
, 0, 0, ILD_TRANSPARENT
);
217 BitBlt(hdc
, 0, 0, size
, size
, hdc
, size
+1, size
+1, SRCCOPY
);
218 ReleaseDC(hwnd
, hdc
);
225 /* Useful for checking differences */
226 static void dump_bits(const BYTE
*p
, const BYTE
*q
, int size
)
232 for (i
= 0; i
< size
* 2; i
++)
235 for (j
= 0; j
< size
; j
++)
236 printf("%c%c", p
[j
] & 0xf0 ? 'X' : ' ', p
[j
] & 0xf ? 'X' : ' ');
238 for (j
= 0; j
< size
; j
++)
239 printf("%c%c", q
[j
] & 0xf0 ? 'X' : ' ', q
[j
] & 0xf ? 'X' : ' ');
247 static void check_bits(HWND hwnd
, HIMAGELIST himl
, int idx
, int size
,
248 const BYTE
*checkbits
, LPCSTR loc
)
250 BYTE bits
[100*100/8];
255 if (!winetest_interactive
|| !himl
) return;
257 memset(bits
, 0, sizeof(bits
));
258 hdc
= show_image(hwnd
, himl
, idx
, size
, loc
, FALSE
);
260 c
= GetPixel(hdc
, 0, 0);
262 for (y
= 0; y
< size
; y
++)
264 for (x
= 0; x
< size
; x
++)
267 if (GetPixel(hdc
, x
, y
) != c
) bits
[i
] |= (0x80 >> (x
& 0x7));
271 BitBlt(hdc
, 0, 0, size
, size
, hdc
, size
+1, size
+1, SRCCOPY
);
272 ReleaseDC(hwnd
, hdc
);
274 ok (memcmp(bits
, checkbits
, (size
* size
)/8) == 0,
275 "%s: bits different\n", loc
);
276 if (memcmp(bits
, checkbits
, (size
* size
)/8))
277 dump_bits(bits
, checkbits
, size
);
280 static void test_begindrag(void)
282 HIMAGELIST himl
= createImageList(7,13);
288 count
= pImageList_GetImageCount(himl
);
289 ok(count
> 2, "Tests need an ImageList with more than 2 images\n");
291 /* Two BeginDrag() without EndDrag() in between */
292 ret
= pImageList_BeginDrag(himl
, 1, 0, 0);
293 drag
= pImageList_GetDragImage(NULL
, NULL
);
294 ok(ret
&& drag
, "ImageList_BeginDrag() failed\n");
295 ret
= pImageList_BeginDrag(himl
, 0, 3, 5);
296 ok(!ret
, "ImageList_BeginDrag() returned TRUE\n");
297 drag
= pImageList_GetDragImage(NULL
, &hotspot
);
298 ok(!!drag
, "No active ImageList drag left\n");
299 ok(hotspot
.x
== 0 && hotspot
.y
== 0, "New ImageList drag was created\n");
300 pImageList_EndDrag();
301 drag
= pImageList_GetDragImage(NULL
, NULL
);
302 ok(!drag
, "ImageList drag was not destroyed\n");
304 /* Invalid image index */
305 pImageList_BeginDrag(himl
, 0, 0, 0);
306 ret
= pImageList_BeginDrag(himl
, count
, 3, 5);
307 ok(!ret
, "ImageList_BeginDrag() returned TRUE\n");
308 drag
= pImageList_GetDragImage(NULL
, &hotspot
);
309 ok(drag
&& hotspot
.x
== 0 && hotspot
.y
== 0, "Active drag should not have been canceled\n");
310 pImageList_EndDrag();
311 drag
= pImageList_GetDragImage(NULL
, NULL
);
312 ok(!drag
, "ImageList drag was not destroyed\n");
313 /* Invalid negative image indexes succeed */
314 ret
= pImageList_BeginDrag(himl
, -17, 0, 0);
315 drag
= pImageList_GetDragImage(NULL
, NULL
);
316 ok(ret
&& drag
, "ImageList drag was created\n");
317 pImageList_EndDrag();
318 ret
= pImageList_BeginDrag(himl
, -1, 0, 0);
319 drag
= pImageList_GetDragImage(NULL
, NULL
);
320 ok(ret
&& drag
, "ImageList drag was created\n");
321 pImageList_EndDrag();
322 pImageList_Destroy(himl
);
325 static void test_hotspot(void)
336 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
337 static const struct hotspot hotspots
[HOTSPOTS_MAX
] = {
344 HIMAGELIST himl1
= createImageList(SIZEX1
, SIZEY1
);
345 HIMAGELIST himl2
= createImageList(SIZEX2
, SIZEY2
);
346 HWND hwnd
= create_window();
349 for (i
= 0; i
< HOTSPOTS_MAX
; i
++) {
350 for (j
= 0; j
< HOTSPOTS_MAX
; j
++) {
351 int dx1
= hotspots
[i
].dx
;
352 int dy1
= hotspots
[i
].dy
;
353 int dx2
= hotspots
[j
].dx
;
354 int dy2
= hotspots
[j
].dy
;
355 int correctx
, correcty
, newx
, newy
;
360 ret
= pImageList_BeginDrag(himl1
, 0, dx1
, dy1
);
361 ok(ret
!= 0, "BeginDrag failed for { %d, %d }\n", dx1
, dy1
);
362 sprintf(loc
, "BeginDrag (%d,%d)\n", i
, j
);
363 show_image(hwnd
, himl1
, 0, max(SIZEX1
, SIZEY1
), loc
, TRUE
);
365 /* check merging the dragged image with a second image */
366 ret
= pImageList_SetDragCursorImage(himl2
, 0, dx2
, dy2
);
367 ok(ret
!= 0, "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
369 sprintf(loc
, "SetDragCursorImage (%d,%d)\n", i
, j
);
370 show_image(hwnd
, himl2
, 0, max(SIZEX2
, SIZEY2
), loc
, TRUE
);
372 /* check new hotspot, it should be the same like the old one */
373 himlNew
= pImageList_GetDragImage(NULL
, &ppt
);
374 ok(ppt
.x
== dx1
&& ppt
.y
== dy1
,
375 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
376 dx1
, dy1
, ppt
.x
, ppt
.y
);
377 /* check size of new dragged image */
378 pImageList_GetIconSize(himlNew
, &newx
, &newy
);
379 correctx
= max(SIZEX1
, max(SIZEX2
+ dx2
, SIZEX1
- dx2
));
380 correcty
= max(SIZEY1
, max(SIZEY2
+ dy2
, SIZEY1
- dy2
));
381 ok(newx
== correctx
&& newy
== correcty
,
382 "Expected drag image size [%d,%d] got [%d,%d]\n",
383 correctx
, correcty
, newx
, newy
);
384 sprintf(loc
, "GetDragImage (%d,%d)\n", i
, j
);
385 show_image(hwnd
, himlNew
, 0, max(correctx
, correcty
), loc
, TRUE
);
386 pImageList_EndDrag();
394 pImageList_Destroy(himl2
);
395 pImageList_Destroy(himl1
);
399 static void test_add_remove(void)
407 /* create an imagelist to play with */
408 himl
= pImageList_Create(84, 84, ILC_COLOR16
, 0, 3);
409 ok(himl
!=0,"failed to create imagelist\n");
411 /* load the icons to add to the image list */
412 hicon1
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
413 ok(hicon1
!= 0, "no hicon1\n");
414 hicon2
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
415 ok(hicon2
!= 0, "no hicon2\n");
416 hicon3
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
417 ok(hicon3
!= 0, "no hicon3\n");
419 /* remove when nothing exists */
420 ok(!pImageList_Remove(himl
, 0), "Removed nonexistent icon.\n");
421 /* removing everything from an empty imagelist should succeed */
422 ok(pImageList_Remove(himl
, -1), "Removed nonexistent icon\n");
425 ok(0 == pImageList_ReplaceIcon(himl
, -1, hicon1
), "Failed to add icon1.\n");
426 ok(1 == pImageList_ReplaceIcon(himl
, -1, hicon2
), "Failed to add icon2.\n");
427 ok(2 == pImageList_ReplaceIcon(himl
, -1, hicon3
), "Failed to add icon3.\n");
429 /* remove an index out of range */
430 ok(!pImageList_Remove(himl
, 4711), "removed nonexistent icon\n");
433 ok(pImageList_Remove(himl
, 0), "Can't remove 0\n");
434 ok(pImageList_Remove(himl
, 0), "Can't remove 0\n");
435 ok(pImageList_Remove(himl
, 0), "Can't remove 0\n");
437 /* remove one extra */
438 ok(!pImageList_Remove(himl
, 0), "Removed nonexistent icon.\n");
441 ok(pImageList_Destroy(himl
), "Failed to destroy imagelist.\n");
443 ok(-1 == pImageList_ReplaceIcon((HIMAGELIST
)0xdeadbeef, -1, hicon1
), "Don't crash on bad handle\n");
445 ok(DestroyIcon(hicon1
), "Failed to destroy icon 1.\n");
446 ok(DestroyIcon(hicon2
), "Failed to destroy icon 2.\n");
447 ok(DestroyIcon(hicon3
), "Failed to destroy icon 3.\n");
450 static void test_imagecount(void)
454 ok(0 == pImageList_GetImageCount((HIMAGELIST
)0xdeadbeef), "don't crash on bad handle\n");
456 if (!pImageList_SetImageCount
)
458 win_skip("ImageList_SetImageCount not available\n");
462 himl
= pImageList_Create(84, 84, ILC_COLOR16
, 0, 3);
463 ok(himl
!= 0, "Failed to create imagelist.\n");
465 ok(pImageList_SetImageCount(himl
, 3), "couldn't increase image count\n");
466 ok(pImageList_GetImageCount(himl
) == 3, "invalid image count after increase\n");
467 ok(pImageList_SetImageCount(himl
, 1), "couldn't decrease image count\n");
468 ok(pImageList_GetImageCount(himl
) == 1, "invalid image count after decrease to 1\n");
469 ok(pImageList_SetImageCount(himl
, 0), "couldn't decrease image count\n");
470 ok(pImageList_GetImageCount(himl
) == 0, "invalid image count after decrease to 0\n");
472 ok(pImageList_Destroy(himl
), "Failed to destroy imagelist.\n");
475 static void test_DrawIndirect(void)
483 IMAGELISTDRAWPARAMS imldp
;
487 if (!pImageList_DrawIndirect
)
489 win_skip("ImageList_DrawIndirect not available, skipping test\n");
493 hwndfortest
= create_window();
494 hdc
= GetDC(hwndfortest
);
495 ok(hdc
!=NULL
, "couldn't get DC\n");
497 /* create an imagelist to play with */
498 himl
= pImageList_Create(48, 48, ILC_COLOR16
, 0, 3);
499 ok(himl
!= 0, "Failed to create imagelist.\n");
501 /* load the icons to add to the image list */
502 hbm1
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
503 ok(hbm1
!= 0, "no bitmap 1\n");
504 hbm2
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
505 ok(hbm2
!= 0, "no bitmap 2\n");
506 hbm3
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
507 ok(hbm3
!= 0, "no bitmap 3\n");
510 ok(0 == pImageList_Add(himl
, hbm1
, 0),"failed to add bitmap 1\n");
511 ok(1 == pImageList_Add(himl
, hbm2
, 0),"failed to add bitmap 2\n");
513 if (pImageList_SetImageCount
)
515 ok(pImageList_SetImageCount(himl
,3),"Setimage count failed\n");
516 /*ok(2==ImageList_Add(himl, hbm3, NULL),"failed to add bitmap 3\n"); */
517 ok(pImageList_Replace(himl
, 2, hbm3
, 0),"failed to replace bitmap 3\n");
520 memset(&imldp
, 0, sizeof (imldp
));
521 ok(!pImageList_DrawIndirect(&imldp
), "zero data succeeded!\n");
522 imldp
.cbSize
= IMAGELISTDRAWPARAMS_V3_SIZE
;
523 ok(!pImageList_DrawIndirect(&imldp
), "zero hdc succeeded!\n");
525 ok(!pImageList_DrawIndirect(&imldp
),"zero himl succeeded!\n");
526 imldp
.himl
= (HIMAGELIST
)0xdeadbeef;
527 ok(!pImageList_DrawIndirect(&imldp
),"bad himl succeeded!\n");
530 force_redraw(hwndfortest
);
532 imldp
.fStyle
= SRCCOPY
;
533 imldp
.rgbBk
= CLR_DEFAULT
;
534 imldp
.rgbFg
= CLR_DEFAULT
;
537 ok(pImageList_DrawIndirect(&imldp
),"should succeed\n");
539 ok(pImageList_DrawIndirect(&imldp
),"should succeed\n");
541 ok(pImageList_DrawIndirect(&imldp
),"should succeed\n");
543 ok(!pImageList_DrawIndirect(&imldp
),"should fail\n");
546 ok(pImageList_Remove(himl
, 0), "removing 1st bitmap\n");
547 ok(pImageList_Remove(himl
, 0), "removing 2nd bitmap\n");
548 ok(pImageList_Remove(himl
, 0), "removing 3rd bitmap\n");
551 ok(pImageList_Destroy(himl
), "Failed to destroy imagelist.\n");
553 /* bitmaps should not be deleted by the imagelist */
554 ok(DeleteObject(hbm1
),"bitmap 1 can't be deleted\n");
555 ok(DeleteObject(hbm2
),"bitmap 2 can't be deleted\n");
556 ok(DeleteObject(hbm3
),"bitmap 3 can't be deleted\n");
558 ReleaseDC(hwndfortest
, hdc
);
559 DestroyWindow(hwndfortest
);
562 static int get_color_format(HBITMAP bmp
)
565 HDC hdc
= CreateCompatibleDC(0);
566 HBITMAP hOldBmp
= SelectObject(hdc
, bmp
);
569 memset(&bmi
, 0, sizeof(bmi
));
570 bmi
.bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
571 ret
= GetDIBits(hdc
, bmp
, 0, 0, 0, &bmi
, DIB_RGB_COLORS
);
572 ok(ret
, "GetDIBits failed\n");
574 SelectObject(hdc
, hOldBmp
);
576 return bmi
.bmiHeader
.biBitCount
;
579 static void test_merge_colors(void)
581 HIMAGELIST himl
[8], hmerge
;
582 int sizes
[] = { ILC_COLOR
, ILC_COLOR
| ILC_MASK
, ILC_COLOR4
, ILC_COLOR8
, ILC_COLOR16
, ILC_COLOR24
, ILC_COLOR32
, ILC_COLORDDB
};
587 hicon1
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
588 ok(hicon1
!= NULL
, "failed to create hicon1\n");
590 for (i
= 0; i
< 8; i
++)
592 himl
[i
] = pImageList_Create(32, 32, sizes
[i
], 0, 3);
593 ok(himl
[i
] != NULL
, "failed to create himl[%d]\n", i
);
594 ok(0 == pImageList_ReplaceIcon(himl
[i
], -1, hicon1
), "Failed to add icon1 to himl[%d].\n", i
);
595 if (i
== 0 || i
== 1 || i
== 7)
597 pImageList_GetImageInfo(himl
[i
], 0, &info
);
598 sizes
[i
] = get_color_format(info
.hbmImage
);
602 for (i
= 0; i
< 8; i
++)
603 for (j
= 0; j
< 8; j
++)
605 hmerge
= pImageList_Merge(himl
[i
], 0, himl
[j
], 0, 0, 0);
606 ok(hmerge
!= NULL
, "merge himl[%d], himl[%d] failed\n", i
, j
);
608 pImageList_GetImageInfo(hmerge
, 0, &info
);
609 bpp
= get_color_format(info
.hbmImage
);
610 /* ILC_COLOR[X] is defined as [X] */
611 if (i
== 4 && j
== 7)
612 ok(bpp
== 16, /* merging ILC_COLOR16 with ILC_COLORDDB seems to be a special case */
613 "wrong biBitCount %d when merging lists %d (%d) and %d (%d)\n", bpp
, i
, sizes
[i
], j
, sizes
[j
]);
615 ok(bpp
== (i
> j
? sizes
[i
] : sizes
[j
]),
616 "wrong biBitCount %d when merging lists %d (%d) and %d (%d)\n", bpp
, i
, sizes
[i
], j
, sizes
[j
]);
617 ok(info
.hbmMask
!= 0, "Imagelist merged from %d and %d had no mask\n", i
, j
);
619 pImageList_Destroy(hmerge
);
622 for (i
= 0; i
< 8; i
++)
623 pImageList_Destroy(himl
[i
]);
626 static void test_merge(void)
628 HIMAGELIST himl1
, himl2
, hmerge
;
630 HWND hwnd
= create_window();
632 himl1
= pImageList_Create(32, 32, 0, 0, 3);
633 ok(himl1
!= NULL
,"failed to create himl1\n");
635 himl2
= pImageList_Create(32, 32, 0, 0, 3);
636 ok(himl2
!= NULL
,"failed to create himl2\n");
638 hicon1
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
639 ok(hicon1
!= NULL
, "failed to create hicon1\n");
641 if (!himl1
|| !himl2
|| !hicon1
)
644 ok(0 == pImageList_ReplaceIcon(himl2
, -1, hicon1
), "Failed to add icon1 to himl2.\n");
645 check_bits(hwnd
, himl2
, 0, 32, icon_bits
, "add icon1 to himl2");
647 /* If himl1 has no images, merge still succeeds */
648 hmerge
= pImageList_Merge(himl1
, -1, himl2
, 0, 0, 0);
649 ok(hmerge
!= NULL
, "merge himl1,-1 failed\n");
650 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl1,-1");
651 pImageList_Destroy(hmerge
);
653 hmerge
= pImageList_Merge(himl1
, 0, himl2
, 0, 0, 0);
654 ok(hmerge
!= NULL
,"merge himl1,0 failed\n");
655 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl1,0");
656 pImageList_Destroy(hmerge
);
658 /* Same happens if himl2 is empty */
659 pImageList_Destroy(himl2
);
660 himl2
= pImageList_Create(32, 32, 0, 0, 3);
661 ok(himl2
!= NULL
,"failed to recreate himl2\n");
665 hmerge
= pImageList_Merge(himl1
, -1, himl2
, -1, 0, 0);
666 ok(hmerge
!= NULL
, "merge himl2,-1 failed\n");
667 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl2,-1");
668 pImageList_Destroy(hmerge
);
670 hmerge
= pImageList_Merge(himl1
, -1, himl2
, 0, 0, 0);
671 ok(hmerge
!= NULL
, "merge himl2,0 failed\n");
672 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl2,0");
673 pImageList_Destroy(hmerge
);
675 /* Now try merging an image with itself */
676 ok(0 == pImageList_ReplaceIcon(himl2
, -1, hicon1
), "Failed to re-add icon1 to himl2.\n");
678 hmerge
= pImageList_Merge(himl2
, 0, himl2
, 0, 0, 0);
679 ok(hmerge
!= NULL
, "merge himl2 with itself failed\n");
680 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl2 with itself");
681 pImageList_Destroy(hmerge
);
683 /* Try merging 2 different image lists */
684 ok(0 == pImageList_ReplaceIcon(himl1
, -1, hicon1
), "Failed to add icon1 to himl1.\n");
686 hmerge
= pImageList_Merge(himl1
, 0, himl2
, 0, 0, 0);
687 ok(hmerge
!= NULL
, "merge himl1 with himl2 failed\n");
688 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl1 with himl2");
689 pImageList_Destroy(hmerge
);
691 hmerge
= pImageList_Merge(himl1
, 0, himl2
, 0, 8, 16);
692 ok(hmerge
!= NULL
, "merge himl1 with himl2 8,16 failed\n");
693 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl1 with himl2, 8,16");
694 pImageList_Destroy(hmerge
);
696 pImageList_Destroy(himl1
);
697 pImageList_Destroy(himl2
);
702 /*********************** imagelist storage test ***************************/
708 IStream IStream_iface
;
712 static struct memstream
*impl_from_IStream(IStream
*iface
)
714 return CONTAINING_RECORD(iface
, struct memstream
, IStream_iface
);
717 static HRESULT STDMETHODCALLTYPE
Test_Stream_QueryInterface(IStream
*iface
, REFIID riid
,
720 ok(0, "unexpected call\n");
724 static ULONG STDMETHODCALLTYPE
Test_Stream_AddRef(IStream
*iface
)
726 ok(0, "unexpected call\n");
730 static ULONG STDMETHODCALLTYPE
Test_Stream_Release(IStream
*iface
)
732 ok(0, "unexpected call\n");
736 static HRESULT STDMETHODCALLTYPE
Test_Stream_Read(IStream
*iface
, void *pv
, ULONG cb
,
739 struct memstream
*stream
= impl_from_IStream(iface
);
740 return IStream_Read(stream
->stream
, pv
, cb
, pcbRead
);
743 static HRESULT STDMETHODCALLTYPE
Test_Stream_Write(IStream
*iface
, const void *pv
, ULONG cb
,
746 struct memstream
*stream
= impl_from_IStream(iface
);
747 return IStream_Write(stream
->stream
, pv
, cb
, pcbWritten
);
750 static HRESULT STDMETHODCALLTYPE
Test_Stream_Seek(IStream
*iface
, LARGE_INTEGER offset
, DWORD origin
,
751 ULARGE_INTEGER
*new_pos
)
753 struct memstream
*stream
= impl_from_IStream(iface
);
757 ok(origin
== STREAM_SEEK_CUR
, "Unexpected origin %d.\n", origin
);
758 ok(offset
.QuadPart
== 0, "Unexpected offset %s.\n", wine_dbgstr_longlong(offset
.QuadPart
));
759 ok(new_pos
!= NULL
, "Unexpected out position pointer.\n");
760 return IStream_Seek(stream
->stream
, offset
, origin
, new_pos
);
764 ok(0, "unexpected call\n");
769 static HRESULT STDMETHODCALLTYPE
Test_Stream_SetSize(IStream
*iface
, ULARGE_INTEGER libNewSize
)
771 ok(0, "unexpected call\n");
775 static HRESULT STDMETHODCALLTYPE
Test_Stream_CopyTo(IStream
*iface
, IStream
*pstm
,
776 ULARGE_INTEGER cb
, ULARGE_INTEGER
*pcbRead
,
777 ULARGE_INTEGER
*pcbWritten
)
779 ok(0, "unexpected call\n");
783 static HRESULT STDMETHODCALLTYPE
Test_Stream_Commit(IStream
*iface
, DWORD grfCommitFlags
)
785 ok(0, "unexpected call\n");
789 static HRESULT STDMETHODCALLTYPE
Test_Stream_Revert(IStream
*iface
)
791 ok(0, "unexpected call\n");
795 static HRESULT STDMETHODCALLTYPE
Test_Stream_LockRegion(IStream
*iface
, ULARGE_INTEGER libOffset
,
796 ULARGE_INTEGER cb
, DWORD dwLockType
)
798 ok(0, "unexpected call\n");
802 static HRESULT STDMETHODCALLTYPE
Test_Stream_UnlockRegion(IStream
*iface
, ULARGE_INTEGER libOffset
,
803 ULARGE_INTEGER cb
, DWORD dwLockType
)
805 ok(0, "unexpected call\n");
809 static HRESULT STDMETHODCALLTYPE
Test_Stream_Stat(IStream
*iface
, STATSTG
*pstatstg
,
812 ok(0, "unexpected call\n");
816 static HRESULT STDMETHODCALLTYPE
Test_Stream_Clone(IStream
*iface
, IStream
**ppstm
)
818 ok(0, "unexpected call\n");
822 static const IStreamVtbl Test_Stream_Vtbl
=
824 Test_Stream_QueryInterface
,
834 Test_Stream_LockRegion
,
835 Test_Stream_UnlockRegion
,
840 static void init_memstream(struct memstream
*stream
)
844 stream
->IStream_iface
.lpVtbl
= &Test_Stream_Vtbl
;
845 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
->stream
);
846 ok(hr
== S_OK
, "Failed to create a stream, hr %#x.\n", hr
);
849 static void cleanup_memstream(struct memstream
*stream
)
851 IStream_Release(stream
->stream
);
854 static INT
DIB_GetWidthBytes( int width
, int bpp
)
856 return ((width
* bpp
+ 31) / 8) & ~3;
859 static ULONG
check_bitmap_data(const ILHEAD
*header
, const char *bm_data
,
860 ULONG bm_data_size
, const SIZE
*bmpsize
, INT bpp
, const char *comment
)
862 const BITMAPFILEHEADER
*bmfh
= (const BITMAPFILEHEADER
*)bm_data
;
863 const BITMAPINFOHEADER
*bmih
= (const BITMAPINFOHEADER
*)(bm_data
+ sizeof(*bmfh
));
864 ULONG hdr_size
, image_size
;
866 hdr_size
= sizeof(*bmfh
) + sizeof(*bmih
);
867 if (bmih
->biBitCount
<= 8) hdr_size
+= (1 << bpp
) * sizeof(RGBQUAD
);
869 ok(bmfh
->bfType
== (('M' << 8) | 'B'), "wrong bfType 0x%02x\n", bmfh
->bfType
);
870 ok(bmfh
->bfSize
== hdr_size
, "wrong bfSize 0x%02x\n", bmfh
->bfSize
);
871 ok(bmfh
->bfReserved1
== 0, "wrong bfReserved1 0x%02x\n", bmfh
->bfReserved1
);
872 ok(bmfh
->bfReserved2
== 0, "wrong bfReserved2 0x%02x\n", bmfh
->bfReserved2
);
873 ok(bmfh
->bfOffBits
== hdr_size
, "wrong bfOffBits 0x%02x\n", bmfh
->bfOffBits
);
875 ok(bmih
->biSize
== sizeof(*bmih
), "wrong biSize %d\n", bmih
->biSize
);
876 ok(bmih
->biPlanes
== 1, "wrong biPlanes %d\n", bmih
->biPlanes
);
877 ok(bmih
->biBitCount
== bpp
, "wrong biBitCount %d\n", bmih
->biBitCount
);
879 image_size
= DIB_GetWidthBytes(bmih
->biWidth
, bmih
->biBitCount
) * bmih
->biHeight
;
880 ok(bmih
->biSizeImage
== image_size
, "wrong biSizeImage %u\n", bmih
->biSizeImage
);
881 ok(bmih
->biWidth
== bmpsize
->cx
&& bmih
->biHeight
== bmpsize
->cy
, "Unexpected bitmap size %d x %d, "
882 "expected %d x %d\n", bmih
->biWidth
, bmih
->biHeight
, bmpsize
->cx
, bmpsize
->cy
);
888 sprintf(fname
, "bmp_%s.bmp", comment
);
889 f
= fopen(fname
, "wb");
890 fwrite(bm_data
, 1, bm_data_size
, f
);
894 return hdr_size
+ image_size
;
897 static BOOL
is_v6_header(const ILHEAD
*header
)
899 return (header
->usVersion
& 0xff00) == 0x600;
902 static void check_ilhead_data(const ILHEAD
*ilh
, INT cx
, INT cy
, INT cur
, INT max
, INT grow
, INT flags
)
906 ok(ilh
->usMagic
== IMAGELIST_MAGIC
, "wrong usMagic %4x (expected %02x)\n", ilh
->usMagic
, IMAGELIST_MAGIC
);
907 ok(ilh
->usVersion
== 0x101 ||
908 ilh
->usVersion
== 0x600 || /* WinXP/W2k3 */
909 ilh
->usVersion
== 0x620, "Unknown usVersion %#x.\n", ilh
->usVersion
);
910 ok(ilh
->cCurImage
== cur
, "wrong cCurImage %d (expected %d)\n", ilh
->cCurImage
, cur
);
913 grow_aligned
= (WORD
)(grow
+ 3) & ~3;
915 if (is_v6_header(ilh
))
917 grow
= (WORD
)(grow
+ 2 + 3) & ~3;
918 ok(ilh
->cGrow
== grow
|| broken(ilh
->cGrow
== grow_aligned
) /* XP/Vista */,
919 "Unexpected cGrow %d, expected %d\n", ilh
->cGrow
, grow
);
923 ok(ilh
->cMaxImage
== max
, "wrong cMaxImage %d (expected %d)\n", ilh
->cMaxImage
, max
);
924 ok(ilh
->cGrow
== grow_aligned
, "Unexpected cGrow %d, expected %d\n", ilh
->cGrow
, grow_aligned
);
927 ok(ilh
->cx
== cx
, "wrong cx %d (expected %d)\n", ilh
->cx
, cx
);
928 ok(ilh
->cy
== cy
, "wrong cy %d (expected %d)\n", ilh
->cy
, cy
);
929 ok(ilh
->bkcolor
== CLR_NONE
, "wrong bkcolor %x\n", ilh
->bkcolor
);
930 ok(ilh
->flags
== flags
|| broken(!(ilh
->flags
& 0xfe) && (flags
& 0xfe) == ILC_COLOR4
), /* <= w2k */
931 "wrong flags %04x\n", ilh
->flags
);
932 ok(ilh
->ovls
[0] == -1, "wrong ovls[0] %04x\n", ilh
->ovls
[0]);
933 ok(ilh
->ovls
[1] == -1, "wrong ovls[1] %04x\n", ilh
->ovls
[1]);
934 ok(ilh
->ovls
[2] == -1, "wrong ovls[2] %04x\n", ilh
->ovls
[2]);
935 ok(ilh
->ovls
[3] == -1, "wrong ovls[3] %04x\n", ilh
->ovls
[3]);
938 static HBITMAP
create_bitmap(INT cx
, INT cy
, COLORREF color
, const char *comment
)
942 HBITMAP hbmp
, hbmp_old
;
944 RECT rc
= { 0, 0, cx
, cy
};
946 hdc
= CreateCompatibleDC(0);
948 memset(&bmi
, 0, sizeof(bmi
));
949 bmi
.bmiHeader
.biSize
= sizeof(bmi
.bmiHeader
);
950 bmi
.bmiHeader
.biHeight
= cx
;
951 bmi
.bmiHeader
.biWidth
= cy
;
952 bmi
.bmiHeader
.biBitCount
= 24;
953 bmi
.bmiHeader
.biPlanes
= 1;
954 bmi
.bmiHeader
.biCompression
= BI_RGB
;
955 hbmp
= CreateDIBSection(hdc
, &bmi
, DIB_RGB_COLORS
, NULL
, NULL
, 0);
957 hbmp_old
= SelectObject(hdc
, hbmp
);
959 hbrush
= CreateSolidBrush(color
);
960 FillRect(hdc
, &rc
, hbrush
);
961 DeleteObject(hbrush
);
963 DrawTextA(hdc
, comment
, -1, &rc
, DT_CENTER
| DT_VCENTER
| DT_SINGLELINE
);
965 SelectObject(hdc
, hbmp_old
);
971 static inline void imagelist_get_bitmap_size(const ILHEAD
*header
, SIZE
*sz
)
973 const int tile_count
= 4;
975 if (is_v6_header(header
))
978 sz
->cy
= header
->cMaxImage
* header
->cy
;
982 sz
->cx
= header
->cx
* tile_count
;
983 sz
->cy
= ((header
->cMaxImage
+ tile_count
- 1) / tile_count
) * header
->cy
;
987 /* Grow argument matches what was used when imagelist was created. */
988 static void check_iml_data(HIMAGELIST himl
, INT cx
, INT cy
, INT cur
, INT max
, INT grow
,
989 INT flags
, const char *comment
)
991 INT ret
, cxx
, cyy
, size
;
992 struct memstream stream
;
993 const ILHEAD
*header
;
1003 ret
= pImageList_GetImageCount(himl
);
1004 ok(ret
== cur
, "%s: expected image count %d got %d\n", comment
, cur
, ret
);
1006 ret
= pImageList_GetIconSize(himl
, &cxx
, &cyy
);
1007 ok(ret
, "ImageList_GetIconSize failed\n");
1008 ok(cxx
== cx
, "%s: wrong cx %d (expected %d)\n", comment
, cxx
, cx
);
1009 ok(cyy
== cy
, "%s: wrong cy %d (expected %d)\n", comment
, cyy
, cy
);
1011 init_memstream(&stream
);
1012 b
= pImageList_Write(himl
, &stream
.IStream_iface
);
1013 ok(b
, "%s: ImageList_Write failed\n", comment
);
1015 hr
= GetHGlobalFromStream(stream
.stream
, &hglobal
);
1016 ok(hr
== S_OK
, "%s: Failed to get hglobal, %#x\n", comment
, hr
);
1018 hr
= IStream_Stat(stream
.stream
, &stat
, STATFLAG_NONAME
);
1019 ok(hr
== S_OK
, "Stat() failed, hr %#x.\n", hr
);
1021 data
= GlobalLock(hglobal
);
1023 ok(data
!= 0, "%s: ImageList_Write didn't write any data\n", comment
);
1024 ok(stat
.cbSize
.LowPart
> sizeof(ILHEAD
), "%s: ImageList_Write wrote not enough data\n", comment
);
1026 header
= (const ILHEAD
*)data
;
1027 check_ilhead_data(header
, cx
, cy
, cur
, max
, grow
, flags
);
1028 imagelist_get_bitmap_size(header
, &bmpsize
);
1029 size
= check_bitmap_data(header
, data
+ sizeof(ILHEAD
), stat
.cbSize
.LowPart
- sizeof(ILHEAD
),
1030 &bmpsize
, flags
& 0xfe, comment
);
1031 if (!is_v6_header(header
) && size
< stat
.cbSize
.LowPart
- sizeof(ILHEAD
)) /* mask is present */
1033 ok( flags
& ILC_MASK
, "%s: extra data %u/%u but mask not expected\n", comment
, stat
.cbSize
.LowPart
, size
);
1034 check_bitmap_data(header
, data
+ sizeof(ILHEAD
) + size
, stat
.cbSize
.LowPart
- sizeof(ILHEAD
) - size
,
1035 &bmpsize
, 1, comment
);
1038 /* rewind and reconstruct from stream */
1040 IStream_Seek(stream
.stream
, mv
, STREAM_SEEK_SET
, NULL
);
1041 himl2
= pImageList_Read(&stream
.IStream_iface
);
1042 ok(himl2
!= NULL
, "%s: Failed to deserialize imagelist\n", comment
);
1043 pImageList_Destroy(himl2
);
1045 GlobalUnlock(hglobal
);
1046 cleanup_memstream(&stream
);
1049 static void image_list_add_bitmap(HIMAGELIST himl
, BYTE grey
, int i
)
1055 sprintf(comment
, "%d", i
);
1056 hbm
= create_bitmap(BMP_CX
, BMP_CX
, RGB(grey
, grey
, grey
), comment
);
1057 ret
= pImageList_Add(himl
, hbm
, NULL
);
1058 ok(ret
!= -1, "Failed to add image to imagelist.\n");
1062 static void image_list_init(HIMAGELIST himl
, INT grow
)
1065 static const struct test_data
1068 INT cx
, cy
, cur
, max
, bpp
;
1069 const char *comment
;
1072 { 255, BMP_CX
, BMP_CX
, 1, 2, 24, "total 1" },
1073 { 170, BMP_CX
, BMP_CX
, 2, 7, 24, "total 2" },
1074 { 85, BMP_CX
, BMP_CX
, 3, 7, 24, "total 3" },
1075 { 0, BMP_CX
, BMP_CX
, 4, 7, 24, "total 4" },
1076 { 0, BMP_CX
, BMP_CX
, 5, 7, 24, "total 5" },
1077 { 85, BMP_CX
, BMP_CX
, 6, 7, 24, "total 6" },
1078 { 170, BMP_CX
, BMP_CX
, 7, 12, 24, "total 7" },
1079 { 255, BMP_CX
, BMP_CX
, 8, 12, 24, "total 8" },
1080 { 255, BMP_CX
, BMP_CX
, 9, 12, 24, "total 9" },
1081 { 170, BMP_CX
, BMP_CX
, 10, 12, 24, "total 10" },
1082 { 85, BMP_CX
, BMP_CX
, 11, 12, 24, "total 11" },
1083 { 0, BMP_CX
, BMP_CX
, 12, 17, 24, "total 12" },
1084 { 0, BMP_CX
, BMP_CX
, 13, 17, 24, "total 13" },
1085 { 85, BMP_CX
, BMP_CX
, 14, 17, 24, "total 14" },
1086 { 170, BMP_CX
, BMP_CX
, 15, 17, 24, "total 15" },
1087 { 255, BMP_CX
, BMP_CX
, 16, 17, 24, "total 16" },
1088 { 255, BMP_CX
, BMP_CX
, 17, 22, 24, "total 17" },
1089 { 170, BMP_CX
, BMP_CX
, 18, 22, 24, "total 18" },
1090 { 85, BMP_CX
, BMP_CX
, 19, 22, 24, "total 19" },
1091 { 0, BMP_CX
, BMP_CX
, 20, 22, 24, "total 20" },
1092 { 0, BMP_CX
, BMP_CX
, 21, 22, 24, "total 21" },
1093 { 85, BMP_CX
, BMP_CX
, 22, 27, 24, "total 22" },
1094 { 170, BMP_CX
, BMP_CX
, 23, 27, 24, "total 23" },
1095 { 255, BMP_CX
, BMP_CX
, 24, 27, 24, "total 24" }
1098 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 2, grow
, ILC_COLOR24
, "total 0");
1100 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
1102 image_list_add_bitmap(himl
, td
[i
].grey
, i
+ 1);
1103 check_iml_data(himl
, td
[i
].cx
, td
[i
].cy
, td
[i
].cur
, td
[i
].max
, grow
, td
[i
].bpp
, td
[i
].comment
);
1107 static void test_imagelist_storage(void)
1114 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 1, 1);
1115 ok(himl
!= 0, "ImageList_Create failed\n");
1117 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 2, 1, ILC_COLOR24
, "empty");
1119 image_list_init(himl
, 1);
1120 check_iml_data(himl
, BMP_CX
, BMP_CX
, 24, 27, 1, ILC_COLOR24
, "orig");
1122 ret
= pImageList_Remove(himl
, 4);
1123 ok(ret
, "ImageList_Remove failed\n");
1124 check_iml_data(himl
, BMP_CX
, BMP_CX
, 23, 27, 1, ILC_COLOR24
, "1");
1126 ret
= pImageList_Remove(himl
, 5);
1127 ok(ret
, "ImageList_Remove failed\n");
1128 check_iml_data(himl
, BMP_CX
, BMP_CX
, 22, 27, 1, ILC_COLOR24
, "2");
1130 ret
= pImageList_Remove(himl
, 6);
1131 ok(ret
, "ImageList_Remove failed\n");
1132 check_iml_data(himl
, BMP_CX
, BMP_CX
, 21, 27, 1, ILC_COLOR24
, "3");
1134 ret
= pImageList_Remove(himl
, 7);
1135 ok(ret
, "ImageList_Remove failed\n");
1136 check_iml_data(himl
, BMP_CX
, BMP_CX
, 20, 27, 1, ILC_COLOR24
, "4");
1138 ret
= pImageList_Remove(himl
, -2);
1139 ok(!ret
, "ImageList_Remove(-2) should fail\n");
1140 check_iml_data(himl
, BMP_CX
, BMP_CX
, 20, 27, 1, ILC_COLOR24
, "5");
1142 ret
= pImageList_Remove(himl
, 20);
1143 ok(!ret
, "ImageList_Remove(20) should fail\n");
1144 check_iml_data(himl
, BMP_CX
, BMP_CX
, 20, 27, 1, ILC_COLOR24
, "6");
1146 ret
= pImageList_Remove(himl
, -1);
1147 ok(ret
, "ImageList_Remove(-1) failed\n");
1148 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 4, 1, ILC_COLOR24
, "7");
1150 ret
= pImageList_Destroy(himl
);
1151 ok(ret
, "ImageList_Destroy failed\n");
1153 /* test ImageList_Create storage allocation */
1155 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 0, 32);
1156 ok(himl
!= 0, "ImageList_Create failed\n");
1157 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 1, 32, ILC_COLOR24
, "init 0 grow 32");
1158 hbm
= create_bitmap(BMP_CX
* 9, BMP_CX
, 0, "9");
1159 ret
= pImageList_Add(himl
, hbm
, NULL
);
1160 ok(ret
== 0, "ImageList_Add returned %d, expected 0\n", ret
);
1161 check_iml_data(himl
, BMP_CX
, BMP_CX
, 1, 34, 32, ILC_COLOR24
, "add 1 x 9");
1163 ret
= pImageList_Destroy(himl
);
1164 ok(ret
, "ImageList_Destroy failed\n");
1166 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 4, 4);
1167 ok(himl
!= 0, "ImageList_Create failed\n");
1168 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 4, ILC_COLOR24
, "init 4 grow 4");
1169 hbm
= create_bitmap(BMP_CX
, BMP_CX
* 9, 0, "9");
1170 ret
= pImageList_Add(himl
, hbm
, NULL
);
1171 ok(ret
== 0, "ImageList_Add returned %d, expected 0\n", ret
);
1172 check_iml_data(himl
, BMP_CX
, BMP_CX
, 9, 15, 4, ILC_COLOR24
, "add 9 x 1");
1173 ret
= pImageList_Add(himl
, hbm
, NULL
);
1174 ok(ret
== 9, "ImageList_Add returned %d, expected 9\n", ret
);
1175 check_iml_data(himl
, BMP_CX
, BMP_CX
, 18, 25, 4, ILC_COLOR24
, "add 9 x 1");
1177 ret
= pImageList_Destroy(himl
);
1178 ok(ret
, "ImageList_Destroy failed\n");
1180 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 207, 209);
1181 ok(himl
!= 0, "ImageList_Create failed\n");
1182 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 208, 209, ILC_COLOR24
, "init 207 grow 209");
1183 ret
= pImageList_Destroy(himl
);
1184 ok(ret
, "ImageList_Destroy failed\n");
1186 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 209, 207);
1187 ok(himl
!= 0, "ImageList_Create failed\n");
1188 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 210, 207, ILC_COLOR24
, "init 209 grow 207");
1189 ret
= pImageList_Destroy(himl
);
1190 ok(ret
, "ImageList_Destroy failed\n");
1192 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 14, 4);
1193 ok(himl
!= 0, "ImageList_Create failed\n");
1194 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 15, 4, ILC_COLOR24
, "init 14 grow 4");
1195 ret
= pImageList_Destroy(himl
);
1196 ok(ret
, "ImageList_Destroy failed\n");
1198 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 5, 9);
1199 ok(himl
!= 0, "ImageList_Create failed\n");
1200 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 6, 9, ILC_COLOR24
, "init 5 grow 9");
1201 ret
= pImageList_Destroy(himl
);
1202 ok(ret
, "ImageList_Destroy failed\n");
1204 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 9, 5);
1205 ok(himl
!= 0, "ImageList_Create failed\n");
1206 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 10, 5, ILC_COLOR24
, "init 9 grow 5");
1207 ret
= pImageList_Destroy(himl
);
1208 ok(ret
, "ImageList_Destroy failed\n");
1210 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 2, 4);
1211 ok(himl
!= 0, "ImageList_Create failed\n");
1212 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 3, 4, ILC_COLOR24
, "init 2 grow 4");
1213 ret
= pImageList_Destroy(himl
);
1214 ok(ret
, "ImageList_Destroy failed\n");
1216 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 4, 2);
1217 ok(himl
!= 0, "ImageList_Create failed\n");
1218 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 2, ILC_COLOR24
, "init 4 grow 2");
1219 ret
= pImageList_Destroy(himl
);
1220 ok(ret
, "ImageList_Destroy failed\n");
1222 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR8
, 4, 2);
1223 ok(himl
!= 0, "ImageList_Create failed\n");
1224 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 2, ILC_COLOR8
, "bpp 8");
1225 ret
= pImageList_Destroy(himl
);
1226 ok(ret
, "ImageList_Destroy failed\n");
1228 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
, 4, 2);
1229 ok(himl
!= 0, "ImageList_Create failed\n");
1230 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 2, ILC_COLOR4
, "bpp 4");
1231 ret
= pImageList_Destroy(himl
);
1232 ok(ret
, "ImageList_Destroy failed\n");
1234 himl
= pImageList_Create(BMP_CX
, BMP_CX
, 0, 4, 2);
1235 ok(himl
!= 0, "ImageList_Create failed\n");
1236 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 2, ILC_COLOR4
, "bpp default");
1237 icon
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1238 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 0, "Failed to add icon.\n");
1239 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 1, "Failed to add icon.\n");
1240 DestroyIcon( icon
);
1241 check_iml_data(himl
, BMP_CX
, BMP_CX
, 2, 5, 2, ILC_COLOR4
, "bpp default");
1242 ret
= pImageList_Destroy(himl
);
1243 ok(ret
, "ImageList_Destroy failed\n");
1245 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
|ILC_MASK
, 4, 2);
1246 ok(himl
!= 0, "ImageList_Create failed\n");
1247 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 2, ILC_COLOR24
|ILC_MASK
, "bpp 24 + mask");
1248 icon
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1249 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 0, "Failed to add icon.\n");
1250 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 1, "Failed to add icon.\n");
1251 DestroyIcon( icon
);
1252 check_iml_data(himl
, BMP_CX
, BMP_CX
, 2, 5, 2, ILC_COLOR24
|ILC_MASK
, "bpp 24 + mask");
1253 ret
= pImageList_Destroy(himl
);
1254 ok(ret
, "ImageList_Destroy failed\n");
1256 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
|ILC_MASK
, 4, 2);
1257 ok(himl
!= 0, "ImageList_Create failed\n");
1258 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 2, ILC_COLOR4
|ILC_MASK
, "bpp 4 + mask");
1259 icon
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1260 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 0, "Failed to add icon.\n");
1261 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 1, "Failed to add icon.\n");
1262 DestroyIcon( icon
);
1263 check_iml_data(himl
, BMP_CX
, BMP_CX
, 2, 5, 2, ILC_COLOR4
|ILC_MASK
, "bpp 4 + mask");
1264 ret
= pImageList_Destroy(himl
);
1265 ok(ret
, "ImageList_Destroy failed\n");
1267 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
|ILC_MASK
, 2, 99);
1268 ok(himl
!= 0, "ImageList_Create failed\n");
1269 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 3, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99");
1270 icon
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1271 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 0, "Failed to add icon.\n");
1272 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 1, "Failed to add icon.\n");
1273 check_iml_data(himl
, BMP_CX
, BMP_CX
, 2, 3, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99 2 icons");
1274 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 2, "Failed to add icon\n");
1275 DestroyIcon( icon
);
1276 check_iml_data(himl
, BMP_CX
, BMP_CX
, 3, 104, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99 3 icons");
1277 ok( pImageList_Remove(himl
, -1) == TRUE
, "Failed to remove icon.\n");
1278 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 100, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99 empty");
1279 ok( pImageList_SetImageCount(himl
, 22) == TRUE
, "Failed to set image count.\n");
1280 check_iml_data(himl
, BMP_CX
, BMP_CX
, 22, 23, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99 set count 22");
1281 ok( pImageList_SetImageCount(himl
, 0) == TRUE
, "Failed to set image count.\n");
1282 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 1, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99 set count 0");
1283 ok( pImageList_SetImageCount(himl
, 42) == TRUE
, "Failed to set image count.\n");
1284 check_iml_data(himl
, BMP_CX
, BMP_CX
, 42, 43, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99 set count 42");
1285 ret
= pImageList_Destroy(himl
);
1286 ok(ret
, "ImageList_Destroy failed\n");
1288 for (grow
= 1; grow
<= 16; grow
++)
1290 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
|ILC_MASK
, 2, grow
);
1291 ok(himl
!= 0, "ImageList_Create failed\n");
1292 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 3, grow
, ILC_COLOR4
|ILC_MASK
, "grow test");
1293 ret
= pImageList_Destroy(himl
);
1294 ok(ret
, "ImageList_Destroy failed\n");
1297 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
|ILC_MASK
, 2, -20);
1298 ok(himl
!= 0, "ImageList_Create failed\n");
1299 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 3, -20, ILC_COLOR4
|ILC_MASK
, "init 2 grow -20");
1300 ret
= pImageList_Destroy(himl
);
1301 ok(ret
, "ImageList_Destroy failed\n");
1303 /* Version 6 implementation hangs on large grow values. */
1306 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
|ILC_MASK
, 2, 65536+12);
1307 ok(himl
!= 0, "ImageList_Create failed\n");
1308 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 3, 65536+12, ILC_COLOR4
|ILC_MASK
, "init 2 grow 65536+12");
1309 ret
= pImageList_Destroy(himl
);
1310 ok(ret
, "ImageList_Destroy failed\n");
1312 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
|ILC_MASK
, 2, 65535);
1313 ok(himl
!= 0, "ImageList_Create failed\n");
1314 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 3, 65535, ILC_COLOR4
|ILC_MASK
, "init 2 grow 65535");
1315 ret
= pImageList_Destroy(himl
);
1316 ok(ret
, "ImageList_Destroy failed\n");
1320 static void test_shell_imagelist(void)
1322 HRESULT (WINAPI
*pSHGetImageList
)(INT
, REFIID
, void**);
1323 IImageList
*iml
= NULL
;
1330 /* Try to load function from shell32 */
1331 hShell32
= LoadLibraryA("shell32.dll");
1332 pSHGetImageList
= (void*)GetProcAddress(hShell32
, (LPCSTR
) 727);
1334 if (!pSHGetImageList
)
1336 win_skip("SHGetImageList not available, skipping test\n");
1337 FreeLibrary(hShell32
);
1341 /* Get system image list */
1342 hr
= pSHGetImageList(SHIL_SYSSMALL
, &IID_IImageList
, (void**)&iml
);
1343 ok(SUCCEEDED(hr
), "SHGetImageList failed, hr=%x\n", hr
);
1346 FreeLibrary(hShell32
);
1350 IImageList_GetImageCount(iml
, &out
);
1351 ok(out
> 0, "IImageList_GetImageCount returned out <= 0\n");
1353 /* Fetch the small icon size */
1354 cx
= GetSystemMetrics(SM_CXSMICON
);
1355 cy
= GetSystemMetrics(SM_CYSMICON
);
1357 /* Check icon size matches */
1358 IImageList_GetImageRect(iml
, 0, &rect
);
1359 ok(((rect
.right
== cx
) && (rect
.bottom
== cy
)),
1360 "IImageList_GetImageRect returned r:%d,b:%d\n",
1361 rect
.right
, rect
.bottom
);
1363 IImageList_Release(iml
);
1364 FreeLibrary(hShell32
);
1367 static HBITMAP
create_test_bitmap(HDC hdc
, UINT width
, UINT height
, WORD bpp
, const UINT32
*bits
)
1370 UINT32
*buffer
= NULL
;
1371 UINT stride
= ((width
* bpp
+ 31) >> 3) & ~3;
1372 BITMAPINFO bitmapInfo
= { { sizeof(BITMAPINFOHEADER
), width
, - height
, 1, bpp
, BI_RGB
, 0, 0, 0, 0, 0 } };
1374 hBitmap
= CreateDIBSection(hdc
, &bitmapInfo
, DIB_RGB_COLORS
, (void**)&buffer
, NULL
, 0);
1375 ok(hBitmap
!= NULL
&& buffer
!= NULL
, "CreateDIBSection failed.\n");
1377 if(!hBitmap
|| !buffer
)
1379 DeleteObject(hBitmap
);
1383 memcpy(buffer
, bits
, stride
* height
);
1388 static BOOL
colour_match(UINT32 x
, UINT32 y
)
1390 const INT32 tolerance
= 8;
1392 const INT32 dr
= abs((INT32
)(x
& 0x000000FF) - (INT32
)(y
& 0x000000FF));
1393 const INT32 dg
= abs((INT32
)((x
& 0x0000FF00) >> 8) - (INT32
)((y
& 0x0000FF00) >> 8));
1394 const INT32 db
= abs((INT32
)((x
& 0x00FF0000) >> 16) - (INT32
)((y
& 0x00FF0000) >> 16));
1395 const INT32 da
= abs((INT32
)((x
& 0xFF000000) >> 24) - (INT32
)((y
& 0xFF000000) >> 24));
1397 return (dr
<= tolerance
&& dg
<= tolerance
&& db
<= tolerance
&& da
<= tolerance
);
1400 static void check_ImageList_DrawIndirect(IMAGELISTDRAWPARAMS
*ildp
, UINT32
*bits
,
1401 UINT32 expected
, int line
)
1403 bits
[0] = 0xFFFFFFFF;
1404 pImageList_DrawIndirect(ildp
);
1405 ok(colour_match(bits
[0], expected
),
1406 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1407 bits
[0], expected
, line
);
1411 static void check_ImageList_DrawIndirect_fStyle(HDC hdc
, HIMAGELIST himl
, UINT32
*bits
, int i
,
1412 UINT fStyle
, UINT32 expected
, int line
)
1414 IMAGELISTDRAWPARAMS ildp
= {sizeof(IMAGELISTDRAWPARAMS
), himl
, i
, hdc
,
1415 0, 0, 0, 0, 0, 0, CLR_NONE
, CLR_NONE
, fStyle
, 0, ILS_NORMAL
, 0, 0x00000000};
1416 check_ImageList_DrawIndirect(&ildp
, bits
, expected
, line
);
1419 static void check_ImageList_DrawIndirect_ILD_ROP(HDC hdc
, HIMAGELIST himl
, UINT32
*bits
, int i
,
1420 DWORD dwRop
, UINT32 expected
, int line
)
1422 IMAGELISTDRAWPARAMS ildp
= {sizeof(IMAGELISTDRAWPARAMS
), himl
, i
, hdc
,
1423 0, 0, 0, 0, 0, 0, CLR_NONE
, CLR_NONE
, ILD_IMAGE
| ILD_ROP
, dwRop
, ILS_NORMAL
, 0, 0x00000000};
1424 check_ImageList_DrawIndirect(&ildp
, bits
, expected
, line
);
1427 static void check_ImageList_DrawIndirect_fState(HDC hdc
, HIMAGELIST himl
, UINT32
*bits
, int i
, UINT fStyle
,
1428 UINT fState
, DWORD Frame
, UINT32 expected
, int line
)
1430 IMAGELISTDRAWPARAMS ildp
= {sizeof(IMAGELISTDRAWPARAMS
), himl
, i
, hdc
,
1431 0, 0, 0, 0, 0, 0, CLR_NONE
, CLR_NONE
, fStyle
, 0, fState
, Frame
, 0x00000000};
1432 check_ImageList_DrawIndirect(&ildp
, bits
, expected
, line
);
1435 static void check_ImageList_DrawIndirect_broken(HDC hdc
, HIMAGELIST himl
, UINT32
*bits
, int i
,
1436 UINT fStyle
, UINT fState
, DWORD Frame
, UINT32 expected
,
1437 UINT32 broken_expected
, int line
)
1439 IMAGELISTDRAWPARAMS ildp
= {sizeof(IMAGELISTDRAWPARAMS
), himl
, i
, hdc
,
1440 0, 0, 0, 0, 0, 0, CLR_NONE
, CLR_NONE
, fStyle
, 0, fState
, Frame
, 0x00000000};
1441 bits
[0] = 0xFFFFFFFF;
1442 pImageList_DrawIndirect(&ildp
);
1443 ok(colour_match(bits
[0], expected
) ||
1444 broken(colour_match(bits
[0], broken_expected
)),
1445 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1446 bits
[0], expected
, line
);
1449 static void check_ImageList_DrawIndirect_grayscale(HDC hdc
, HIMAGELIST himl
, UINT32
*dst_bits
, const UINT32
*bitmap_bits
,
1450 int index
, UINT width
, UINT height
, int line
)
1453 BOOL has_alpha
= FALSE
;
1454 IMAGELISTDRAWPARAMS ildp
= { sizeof(IMAGELISTDRAWPARAMS
), himl
, index
, hdc
,
1455 0, 0, 0, 0, 0, 0, CLR_NONE
, CLR_NONE
, ILD_NORMAL
, 0, ILS_SATURATE
, 0, 0x00000000 };
1456 memset(dst_bits
, 0, width
* height
* sizeof(*dst_bits
));
1457 pImageList_DrawIndirect(&ildp
);
1459 for (i
= 0; i
< width
* height
; i
++)
1460 if ((has_alpha
= ((bitmap_bits
[i
] & 0xFF000000) != 0))) break;
1462 for (i
= 0; i
< width
* height
; i
++)
1464 UINT32 expected
, expected_winxp
;
1465 UINT32 red
= (bitmap_bits
[i
] & 0x00FF0000) >> 16;
1466 UINT32 green
= (bitmap_bits
[i
] & 0x0000FF00) >> 8;
1467 UINT32 blue
= (bitmap_bits
[i
] & 0x000000FF) >> 0;
1468 UINT32 gray
= (red
* 299 + green
* 587 + blue
* 114 + 500) / 1000;
1469 UINT32 gray_winxp
= (red
+ green
+ blue
) / 3;
1472 UINT32 alpha
= (bitmap_bits
[i
] & 0xFF000000) >> 24;
1473 gray
= gray
* alpha
/ 0xff * alpha
/ 0xff;
1474 gray_winxp
= gray_winxp
* alpha
/ 0xff * 0x96 / 0xff;
1475 expected
= (alpha
<< 24) | (gray
<< 16) | (gray
<< 8) | gray
;
1476 expected_winxp
= ((alpha
* 0x96 / 0xff) << 24) | (gray_winxp
<< 16) | (gray_winxp
<< 8) | gray_winxp
;
1480 expected
= ((UINT32
)0xFF << 24) | (gray
<< 16) | (gray
<< 8) | gray
;
1481 expected_winxp
= (gray_winxp
<< 16) | (gray_winxp
<< 8) | gray_winxp
;
1484 ok(colour_match(dst_bits
[i
], expected
) || broken(colour_match(dst_bits
[i
], expected_winxp
)),
1485 "ImageList_DrawIndirect: got Pixel(%d,%d) %08X, Expected a close match to %08X from line %d\n",
1486 i
% width
, i
/ width
, dst_bits
[i
], expected
, line
);
1490 static void test_ImageList_DrawIndirect(void)
1492 const UINT32 bits_image
[] = { 0x00ABCDEF, 0x00ABCDEF };
1493 const UINT32 bits_alpha
[] = { 0x89ABCDEF, 0x89ABCDEF };
1494 const UINT32 bits_transparent
[] = { 0x00ABCDEF, 0x89ABCDEF };
1496 const UINT32 bits_4x4
[] = { 0x00ABCDEF, 0x89ABCDEF, 0xFFABCDEF, 0xFEDCBA98,
1497 0x00345678, 0x12345678, 0xFF345678, 0x87654321,
1498 0x00987654, 0xBA987654, 0xFF987654, 0x456789AB,
1499 0x00000000, 0xFF000000, 0xFFFFFFFF, 0x00FFFFFF };
1501 HIMAGELIST himl
= NULL
;
1504 HBITMAP hbmOld
= NULL
, hbmDst
= NULL
;
1505 HBITMAP hbmMask
= NULL
, hbmInverseMask
= NULL
;
1506 HBITMAP hbmImage
= NULL
, hbmAlphaImage
= NULL
, hbmTransparentImage
= NULL
, hbm4x4
= NULL
;
1507 int iImage
= -1, iAlphaImage
= -1, iTransparentImage
= -1;
1509 UINT32 maskBits
= 0x00000000, inverseMaskBits
= 0xFFFFFFFF;
1514 BITMAPINFO bitmapInfo
= {{sizeof(BITMAPINFOHEADER
), 2, 1, 1, 32, BI_RGB
,
1517 hdcDst
= CreateCompatibleDC(0);
1518 ok(hdcDst
!= 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
1522 hbmMask
= CreateBitmap(2, 1, 1, 1, &maskBits
);
1523 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1525 hbmInverseMask
= CreateBitmap(2, 1, 1, 1, &inverseMaskBits
);
1526 ok(hbmInverseMask
!= 0, "CreateBitmap failed\n");
1528 himl
= pImageList_Create(2, 1, ILC_COLOR32
, 0, 1);
1529 ok(himl
!= 0, "ImageList_Create failed\n");
1531 hr
= pHIMAGELIST_QueryInterface(himl
, &IID_IImageList
, (void **) &imgl
);
1532 ok(hr
== S_OK
, "Failed to get interface, hr %#x.\n", hr
);
1534 /* Add a no-alpha image */
1535 hbmImage
= create_test_bitmap(hdcDst
, 2, 1, 32, bits_image
);
1536 ok(hbmImage
!= NULL
, "Failed to create test bitmap.\n");
1538 iImage
= pImageList_Add(himl
, hbmImage
, hbmMask
);
1539 ok(iImage
!= -1, "ImageList_Add failed\n");
1541 hr
= IImageList_GetItemFlags(imgl
, 1000, &flags
);
1542 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
1544 hr
= IImageList_GetItemFlags(imgl
, 1000, NULL
);
1545 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
1547 hr
= IImageList_GetItemFlags(imgl
, iImage
, &flags
);
1548 ok(hr
== S_OK
, "Failed to get item flags, hr %#x.\n", hr
);
1549 ok(!flags
, "Unexpected flags %#x.\n", flags
);
1551 /* Add an alpha image */
1552 hbmAlphaImage
= create_test_bitmap(hdcDst
, 2, 1, 32, bits_alpha
);
1553 ok(hbmAlphaImage
!= NULL
, "Failed to create test bitmap.\n");
1555 iAlphaImage
= pImageList_Add(himl
, hbmAlphaImage
, hbmMask
);
1556 ok(iAlphaImage
!= -1, "ImageList_Add failed\n");
1558 hr
= IImageList_GetItemFlags(imgl
, iAlphaImage
, &flags
);
1559 ok(hr
== S_OK
, "Failed to get item flags, hr %#x.\n", hr
);
1560 ok(flags
& ILIF_ALPHA
, "Unexpected flags %#x.\n", flags
);
1562 /* Add a transparent alpha image */
1563 hbmTransparentImage
= create_test_bitmap(hdcDst
, 2, 1, 32, bits_transparent
);
1564 ok(hbmTransparentImage
!= NULL
, "Failed to create test bitmap.\n");
1566 iTransparentImage
= pImageList_Add(himl
, hbmTransparentImage
, hbmMask
);
1567 ok(iTransparentImage
!= -1, "ImageList_Add failed\n");
1569 hr
= IImageList_GetItemFlags(imgl
, iTransparentImage
, &flags
);
1570 ok(hr
== S_OK
, "Failed to get item flags, hr %#x.\n", hr
);
1571 ok(flags
& ILIF_ALPHA
, "Unexpected flags %#x.\n", flags
);
1574 bitmapInfo
.bmiHeader
.biBitCount
= 32;
1575 hbmDst
= CreateDIBSection(hdcDst
, &bitmapInfo
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1576 ok (hbmDst
&& bits
, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1577 hbmOld
= SelectObject(hdcDst
, hbmDst
);
1579 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iImage
, ILD_NORMAL
, 0x00ABCDEF, __LINE__
);
1580 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iImage
, ILD_TRANSPARENT
, 0x00ABCDEF, __LINE__
);
1581 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iImage
, ILD_MASK
, 0x00ABCDEF, __LINE__
);
1582 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iImage
, ILD_IMAGE
, 0x00ABCDEF, __LINE__
);
1583 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iImage
, ILD_PRESERVEALPHA
, 0x00ABCDEF, __LINE__
);
1585 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iAlphaImage
, ILD_NORMAL
, 0xFFD3E5F7, __LINE__
);
1586 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iAlphaImage
, ILD_TRANSPARENT
, 0xFFD3E5F7, __LINE__
);
1588 /* broken on winxp */
1589 todo_wine
check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iAlphaImage
, ILD_BLEND25
, ILS_NORMAL
, 0, 0xFFE8F1FA, 0xFFD4D9DD, __LINE__
);
1590 todo_wine
check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iAlphaImage
, ILD_BLEND50
, ILS_NORMAL
, 0, 0xFFE8F1FA, 0xFFB4BDC4, __LINE__
);
1592 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iAlphaImage
, ILD_MASK
, 0xFFD3E5F7, __LINE__
);
1593 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iAlphaImage
, ILD_IMAGE
, 0xFFD3E5F7, __LINE__
);
1595 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iAlphaImage
, ILD_PRESERVEALPHA
, 0x895D6F81, __LINE__
);
1596 check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iAlphaImage
, ILD_PRESERVEALPHA
, ILS_ALPHA
, 127, 0xFFE9F2FB, 0xFFAEB7C0, __LINE__
);
1597 check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iAlphaImage
, ILD_PRESERVEALPHA
, ILS_SATURATE
, 0, 0xFFAFAFAF, 0xFFF0F0F0, __LINE__
);
1599 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iTransparentImage
, ILD_NORMAL
, 0xFFFFFFFF, __LINE__
);
1601 check_ImageList_DrawIndirect_ILD_ROP(hdcDst
, himl
, bits
, iImage
, SRCCOPY
, 0x00ABCDEF, __LINE__
);
1602 check_ImageList_DrawIndirect_ILD_ROP(hdcDst
, himl
, bits
, iImage
, SRCINVERT
, 0xFF543210, __LINE__
);
1604 /* ILD_ROP is ignored when the image has an alpha channel */
1605 check_ImageList_DrawIndirect_ILD_ROP(hdcDst
, himl
, bits
, iAlphaImage
, SRCCOPY
, 0xFFD3E5F7, __LINE__
);
1606 check_ImageList_DrawIndirect_ILD_ROP(hdcDst
, himl
, bits
, iAlphaImage
, SRCINVERT
, 0xFFD3E5F7, __LINE__
);
1608 check_ImageList_DrawIndirect_grayscale(hdcDst
, himl
, bits
, bits_image
, iImage
, 2, 1, __LINE__
);
1609 check_ImageList_DrawIndirect_grayscale(hdcDst
, himl
, bits
, bits_alpha
, iAlphaImage
, 2, 1, __LINE__
);
1610 check_ImageList_DrawIndirect_grayscale(hdcDst
, himl
, bits
, bits_transparent
, iTransparentImage
, 2, 1, __LINE__
);
1612 check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iImage
, ILD_NORMAL
, ILS_GLOW
, 0, 0x00ABCDEF, 0xFFABCDEF, __LINE__
);
1613 check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iImage
, ILD_NORMAL
, ILS_SHADOW
, 0, 0x00ABCDEF, 0xFFABCDEF, __LINE__
);
1615 check_ImageList_DrawIndirect_fState(hdcDst
, himl
, bits
, iImage
, ILD_NORMAL
, ILS_ALPHA
, 127, 0xFFD5E6F7, __LINE__
);
1616 check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iAlphaImage
, ILD_NORMAL
, ILS_ALPHA
, 127, 0xFFE9F2FB, 0xFFAEB7C0, __LINE__
);
1617 check_ImageList_DrawIndirect_fState(hdcDst
, himl
, bits
, iAlphaImage
, ILD_NORMAL
, ILS_NORMAL
, 127, 0xFFD3E5F7, __LINE__
);
1619 /* 4x4 bitmap tests */
1620 SelectObject(hdcDst
, hbmOld
);
1621 DeleteObject(hbmDst
);
1622 bitmapInfo
.bmiHeader
.biWidth
= 4;
1623 bitmapInfo
.bmiHeader
.biHeight
= -4;
1624 hbmDst
= CreateDIBSection(hdcDst
, &bitmapInfo
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1625 ok (hbmDst
&& bits
, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1626 SelectObject(hdcDst
, hbmDst
);
1628 hbm4x4
= create_test_bitmap(hdcDst
, 4, 4, 32, bits_4x4
);
1629 ok(hbm4x4
!= NULL
, "Failed to create a test bitmap.\n");
1631 ret
= pImageList_SetIconSize(himl
, 4, 4);
1632 ok(ret
, "ImageList_SetIconSize failed\n");
1634 ret
= pImageList_Add(himl
, hbm4x4
, NULL
);
1635 ok(ret
!= -1, "ImageList_Add failed\n");
1637 check_ImageList_DrawIndirect_grayscale(hdcDst
, himl
, bits
, bits_4x4
, 0, 4, 4, __LINE__
);
1640 SelectObject(hdcDst
, hbmOld
);
1642 DeleteObject(hbmDst
);
1647 DeleteObject(hbmMask
);
1649 DeleteObject(hbmInverseMask
);
1652 DeleteObject(hbmImage
);
1654 DeleteObject(hbmAlphaImage
);
1655 if(hbmTransparentImage
)
1656 DeleteObject(hbmTransparentImage
);
1658 DeleteObject(hbm4x4
);
1662 ret
= pImageList_Destroy(himl
);
1663 ok(ret
, "ImageList_Destroy failed\n");
1667 static void test_iimagelist(void)
1669 IImageList
*imgl
, *imgl2
;
1670 IImageList2
*imagelist
;
1675 if (!pHIMAGELIST_QueryInterface
)
1677 win_skip("XP imagelist functions not available\n");
1681 /* test reference counting on destruction */
1682 imgl
= (IImageList
*)createImageList(32, 32);
1683 ret
= IImageList_AddRef(imgl
);
1684 ok(ret
== 2, "Expected 2, got %d\n", ret
);
1685 ret
= pImageList_Destroy((HIMAGELIST
)imgl
);
1686 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
1687 ret
= pImageList_Destroy((HIMAGELIST
)imgl
);
1688 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
1689 ret
= pImageList_Destroy((HIMAGELIST
)imgl
);
1690 ok(ret
== FALSE
, "Expected FALSE, got %d\n", ret
);
1692 imgl
= (IImageList
*)createImageList(32, 32);
1693 ret
= IImageList_AddRef(imgl
);
1694 ok(ret
== 2, "Expected 2, got %d\n", ret
);
1695 ret
= pImageList_Destroy((HIMAGELIST
)imgl
);
1696 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
1697 ret
= IImageList_Release(imgl
);
1698 ok(ret
== 0, "Expected 0, got %d\n", ret
);
1699 ret
= pImageList_Destroy((HIMAGELIST
)imgl
);
1700 ok(ret
== FALSE
, "Expected FALSE, got %d\n", ret
);
1702 /* ref counting, HIMAGELIST_QueryInterface adds a reference */
1703 imgl
= (IImageList
*)createImageList(32, 32);
1704 hr
= pHIMAGELIST_QueryInterface((HIMAGELIST
)imgl
, &IID_IImageList
, (void**)&imgl2
);
1705 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1706 ok(imgl2
== imgl
, "got different pointer\n");
1707 ret
= IImageList_Release(imgl
);
1708 ok(ret
== 1, "got %u\n", ret
);
1709 IImageList_Release(imgl
);
1711 if (!pImageList_CoCreateInstance
)
1713 win_skip("Vista imagelist functions not available\n");
1717 hr
= pImageList_CoCreateInstance(&CLSID_ImageList
, NULL
, &IID_IImageList
, (void **) &imgl
);
1718 ok(SUCCEEDED(hr
), "ImageList_CoCreateInstance failed, hr=%x\n", hr
);
1721 IImageList_Release(imgl
);
1723 himl
= createImageList(32, 32);
1728 hr
= pHIMAGELIST_QueryInterface(himl
, &IID_IImageList
, (void **) &imgl
);
1729 ok(SUCCEEDED(hr
), "HIMAGELIST_QueryInterface failed, hr=%x\n", hr
);
1732 IImageList_Release(imgl
);
1734 pImageList_Destroy(himl
);
1737 hr
= pImageList_CoCreateInstance(&CLSID_ImageList
, NULL
, &IID_IImageList2
, (void**)&imagelist
);
1740 win_skip("IImageList2 is not supported.\n");
1743 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1744 IImageList2_Release(imagelist
);
1747 static void test_IImageList_Add_Remove(void)
1759 /* create an imagelist to play with */
1760 himl
= pImageList_Create(84, 84, ILC_COLOR16
, 0, 3);
1761 ok(himl
!= 0,"failed to create imagelist\n");
1763 imgl
= (IImageList
*) himl
;
1765 /* load the icons to add to the image list */
1766 hicon1
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1767 ok(hicon1
!= 0, "no hicon1\n");
1768 hicon2
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1769 ok(hicon2
!= 0, "no hicon2\n");
1770 hicon3
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1771 ok(hicon3
!= 0, "no hicon3\n");
1773 /* remove when nothing exists */
1774 hr
= IImageList_Remove(imgl
, 0);
1775 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1777 /* removing everything from an empty imagelist should succeed */
1778 hr
= IImageList_Remove(imgl
, -1);
1779 ok(hr
== S_OK
, "removed nonexistent icon\n");
1783 ok( IImageList_ReplaceIcon(imgl
, -1, hicon1
, &ret
) == S_OK
&& (ret
== 0),"failed to add icon1\n");
1785 ok( IImageList_ReplaceIcon(imgl
, -1, hicon2
, &ret
) == S_OK
&& (ret
== 1),"failed to add icon2\n");
1787 ok( IImageList_ReplaceIcon(imgl
, -1, hicon3
, &ret
) == S_OK
&& (ret
== 2),"failed to add icon3\n");
1789 /* remove an index out of range */
1790 ok( IImageList_Remove(imgl
, 4711) == E_INVALIDARG
, "got 0x%08x\n", hr
);
1793 ok( IImageList_Remove(imgl
,0) == S_OK
, "can't remove 0\n");
1794 ok( IImageList_Remove(imgl
,0) == S_OK
, "can't remove 0\n");
1795 ok( IImageList_Remove(imgl
,0) == S_OK
, "can't remove 0\n");
1797 /* remove one extra */
1798 ok( IImageList_Remove(imgl
, 0) == E_INVALIDARG
, "got 0x%08x\n", hr
);
1800 IImageList_Release(imgl
);
1801 ok(DestroyIcon(hicon1
),"icon 1 wasn't deleted\n");
1802 ok(DestroyIcon(hicon2
),"icon 2 wasn't deleted\n");
1803 ok(DestroyIcon(hicon3
),"icon 3 wasn't deleted\n");
1806 static void test_IImageList_Get_SetImageCount(void)
1813 /* create an imagelist to play with */
1814 himl
= pImageList_Create(84, 84, ILC_COLOR16
, 0, 3);
1815 ok(himl
!= 0,"failed to create imagelist\n");
1817 imgl
= (IImageList
*) himl
;
1819 /* check SetImageCount/GetImageCount */
1820 hr
= IImageList_SetImageCount(imgl
, 3);
1821 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1823 hr
= IImageList_GetImageCount(imgl
, &ret
);
1824 ok(hr
== S_OK
&& ret
== 3, "invalid image count after increase\n");
1825 hr
= IImageList_SetImageCount(imgl
, 1);
1826 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1828 hr
= IImageList_GetImageCount(imgl
, &ret
);
1829 ok(hr
== S_OK
&& ret
== 1, "invalid image count after decrease to 1\n");
1830 hr
= IImageList_SetImageCount(imgl
, 0);
1831 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1833 hr
= IImageList_GetImageCount(imgl
, &ret
);
1834 ok(hr
== S_OK
&& ret
== 0, "invalid image count after decrease to 0\n");
1836 IImageList_Release(imgl
);
1839 static void test_IImageList_Draw(void)
1848 IMAGELISTDRAWPARAMS imldp
;
1854 hwndfortest
= create_window();
1855 hdc
= GetDC(hwndfortest
);
1856 ok(hdc
!=NULL
, "couldn't get DC\n");
1858 /* create an imagelist to play with */
1859 himl
= pImageList_Create(48, 48, ILC_COLOR16
, 0, 3);
1860 ok(himl
!=0,"failed to create imagelist\n");
1862 imgl
= (IImageList
*) himl
;
1864 /* load the icons to add to the image list */
1865 hbm1
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
1866 ok(hbm1
!= 0, "no bitmap 1\n");
1867 hbm2
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
1868 ok(hbm2
!= 0, "no bitmap 2\n");
1869 hbm3
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
1870 ok(hbm3
!= 0, "no bitmap 3\n");
1874 ok( IImageList_Add(imgl
, hbm1
, 0, &ret
) == S_OK
&& (ret
== 0), "failed to add bitmap 1\n");
1876 ok( IImageList_Add(imgl
, hbm2
, 0, &ret
) == S_OK
&& (ret
== 1), "failed to add bitmap 2\n");
1878 ok( IImageList_SetImageCount(imgl
, 3) == S_OK
, "Setimage count failed\n");
1879 ok( IImageList_Replace(imgl
, 2, hbm3
, 0) == S_OK
, "failed to replace bitmap 3\n");
1883 /* crashes on native */
1884 IImageList_Draw(imgl
, NULL
);
1887 memset(&imldp
, 0, sizeof (imldp
));
1888 hr
= IImageList_Draw(imgl
, &imldp
);
1889 ok( hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1891 imldp
.cbSize
= IMAGELISTDRAWPARAMS_V3_SIZE
;
1895 force_redraw(hwndfortest
);
1897 imldp
.fStyle
= SRCCOPY
;
1898 imldp
.rgbBk
= CLR_DEFAULT
;
1899 imldp
.rgbFg
= CLR_DEFAULT
;
1902 ok( IImageList_Draw(imgl
, &imldp
) == S_OK
, "should succeed\n");
1904 ok( IImageList_Draw(imgl
, &imldp
) == S_OK
, "should succeed\n");
1906 ok( IImageList_Draw(imgl
, &imldp
) == S_OK
, "should succeed\n");
1908 ok( IImageList_Draw(imgl
, &imldp
) == E_INVALIDARG
, "should fail\n");
1911 ok( IImageList_Remove(imgl
, 0) == S_OK
, "removing 1st bitmap\n");
1912 ok( IImageList_Remove(imgl
, 0) == S_OK
, "removing 2nd bitmap\n");
1913 ok( IImageList_Remove(imgl
, 0) == S_OK
, "removing 3rd bitmap\n");
1916 IImageList_Release(imgl
);
1918 /* bitmaps should not be deleted by the imagelist */
1919 ok(DeleteObject(hbm1
),"bitmap 1 can't be deleted\n");
1920 ok(DeleteObject(hbm2
),"bitmap 2 can't be deleted\n");
1921 ok(DeleteObject(hbm3
),"bitmap 3 can't be deleted\n");
1923 ReleaseDC(hwndfortest
, hdc
);
1924 DestroyWindow(hwndfortest
);
1927 static void test_IImageList_Merge(void)
1929 HIMAGELIST himl1
, himl2
;
1930 IImageList
*imgl1
, *imgl2
, *merge
;
1932 HWND hwnd
= create_window();
1936 himl1
= pImageList_Create(32,32,0,0,3);
1937 ok(himl1
!= NULL
,"failed to create himl1\n");
1939 himl2
= pImageList_Create(32,32,0,0,3);
1940 ok(himl2
!= NULL
,"failed to create himl2\n");
1942 hicon1
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1943 ok(hicon1
!= NULL
, "failed to create hicon1\n");
1945 if (!himl1
|| !himl2
|| !hicon1
)
1948 /* cast to IImageList */
1949 imgl1
= (IImageList
*) himl1
;
1950 imgl2
= (IImageList
*) himl2
;
1953 ok( IImageList_ReplaceIcon(imgl2
, -1, hicon1
, &ret
) == S_OK
&& (ret
== 0),"add icon1 to himl2 failed\n");
1957 /* null cases that crash on native */
1958 IImageList_Merge(imgl1
, -1, NULL
, 0, 0, 0, &IID_IImageList
, (void**)&merge
);
1959 IImageList_Merge(imgl1
, -1, (IUnknown
*) imgl2
, 0, 0, 0, &IID_IImageList
, NULL
);
1962 /* If himl1 has no images, merge still succeeds */
1963 hr
= IImageList_Merge(imgl1
, -1, (IUnknown
*) imgl2
, 0, 0, 0, &IID_IImageList
, (void **) &merge
);
1964 ok(hr
== S_OK
, "merge himl1,-1 failed\n");
1965 if (hr
== S_OK
) IImageList_Release(merge
);
1967 hr
= IImageList_Merge(imgl1
, 0, (IUnknown
*) imgl2
, 0, 0, 0, &IID_IImageList
, (void **) &merge
);
1968 ok(hr
== S_OK
, "merge himl1,0 failed\n");
1969 if (hr
== S_OK
) IImageList_Release(merge
);
1971 /* Same happens if himl2 is empty */
1972 IImageList_Release(imgl2
);
1973 himl2
= pImageList_Create(32,32,0,0,3);
1974 ok(himl2
!= NULL
,"failed to recreate himl2\n");
1976 imgl2
= (IImageList
*) himl2
;
1978 hr
= IImageList_Merge(imgl1
, -1, (IUnknown
*) imgl2
, -1, 0, 0, &IID_IImageList
, (void **) &merge
);
1979 ok(hr
== S_OK
, "merge himl2,-1 failed\n");
1980 if (hr
== S_OK
) IImageList_Release(merge
);
1982 hr
= IImageList_Merge(imgl1
, -1, (IUnknown
*) imgl2
, 0, 0, 0, &IID_IImageList
, (void **) &merge
);
1983 ok(hr
== S_OK
, "merge himl2,0 failed\n");
1984 if (hr
== S_OK
) IImageList_Release(merge
);
1986 /* Now try merging an image with itself */
1988 ok( IImageList_ReplaceIcon(imgl2
, -1, hicon1
, &ret
) == S_OK
&& (ret
== 0),"re-add icon1 to himl2 failed\n");
1990 hr
= IImageList_Merge(imgl2
, 0, (IUnknown
*) imgl2
, 0, 0, 0, &IID_IImageList
, (void **) &merge
);
1991 ok(hr
== S_OK
, "merge himl2 with itself failed\n");
1992 if (hr
== S_OK
) IImageList_Release(merge
);
1994 /* Try merging 2 different image lists */
1996 ok( IImageList_ReplaceIcon(imgl1
, -1, hicon1
, &ret
) == S_OK
&& (ret
== 0),"add icon1 to himl1 failed\n");
1998 hr
= IImageList_Merge(imgl1
, 0, (IUnknown
*) imgl2
, 0, 0, 0, &IID_IImageList
, (void **) &merge
);
1999 ok(hr
== S_OK
, "merge himl1 with himl2 failed\n");
2000 if (hr
== S_OK
) IImageList_Release(merge
);
2002 hr
= IImageList_Merge(imgl1
, 0, (IUnknown
*) imgl2
, 0, 8, 16, &IID_IImageList
, (void **) &merge
);
2003 ok(hr
== S_OK
, "merge himl1 with himl2 8,16 failed\n");
2004 if (hr
== S_OK
) IImageList_Release(merge
);
2006 IImageList_Release(imgl1
);
2007 IImageList_Release(imgl2
);
2009 DestroyIcon(hicon1
);
2010 DestroyWindow(hwnd
);
2013 static void test_iconsize(void)
2019 himl
= pImageList_Create(16, 16, ILC_COLOR16
, 0, 3);
2020 /* null pointers, not zero imagelist dimensions */
2021 ret
= pImageList_GetIconSize(himl
, NULL
, NULL
);
2022 ok(!ret
, "got %d\n", ret
);
2024 /* doesn't touch return pointers */
2026 ret
= pImageList_GetIconSize(himl
, &cx
, NULL
);
2027 ok(!ret
, "got %d\n", ret
);
2028 ok(cx
== 0x1abe11ed, "got %d\n", cx
);
2031 ret
= pImageList_GetIconSize(himl
, NULL
, &cy
);
2032 ok(!ret
, "got %d\n", ret
);
2033 ok(cy
== 0x1abe11ed, "got %d\n", cy
);
2035 pImageList_Destroy(himl
);
2037 ret
= pImageList_GetIconSize((HIMAGELIST
)0xdeadbeef, &cx
, &cy
);
2038 ok(!ret
, "got %d\n", ret
);
2041 static void test_create_destroy(void)
2048 /* list with zero or negative image dimensions */
2049 himl
= pImageList_Create(0, 0, ILC_COLOR16
, 0, 3);
2050 ok(himl
== NULL
, "got %p\n", himl
);
2052 himl
= pImageList_Create(0, 16, ILC_COLOR16
, 0, 3);
2053 ok(himl
== NULL
, "got %p\n", himl
);
2055 himl
= pImageList_Create(16, 0, ILC_COLOR16
, 0, 3);
2056 ok(himl
== NULL
, "got %p\n", himl
);
2058 himl
= pImageList_Create(16, -1, ILC_COLOR16
, 0, 3);
2059 ok(himl
== NULL
, "got %p\n", himl
);
2061 himl
= pImageList_Create(-1, 16, ILC_COLOR16
, 0, 3);
2062 ok(himl
== NULL
, "got %p\n", himl
);
2064 rc
= pImageList_Destroy((HIMAGELIST
)0xdeadbeef);
2065 ok(rc
== FALSE
, "ImageList_Destroy(0xdeadbeef) should fail and not crash\n");
2067 /* DDB image lists */
2068 himl
= pImageList_Create(0, 14, ILC_COLORDDB
, 4, 4);
2069 ok(himl
!= NULL
, "got %p\n", himl
);
2071 pImageList_GetIconSize(himl
, &cx
, &cy
);
2072 ok (cx
== 0, "Wrong cx (%i)\n", cx
);
2073 ok (cy
== 14, "Wrong cy (%i)\n", cy
);
2074 pImageList_Destroy(himl
);
2076 himl
= pImageList_Create(0, 0, ILC_COLORDDB
, 4, 4);
2077 ok(himl
!= NULL
, "got %p\n", himl
);
2078 pImageList_GetIconSize(himl
, &cx
, &cy
);
2079 ok (cx
== 0, "Wrong cx (%i)\n", cx
);
2080 ok (cy
== 0, "Wrong cy (%i)\n", cy
);
2081 pImageList_Destroy(himl
);
2083 himl
= pImageList_Create(0, 0, ILC_COLORDDB
, 0, 4);
2084 ok(himl
!= NULL
, "got %p\n", himl
);
2085 pImageList_GetIconSize(himl
, &cx
, &cy
);
2086 ok (cx
== 0, "Wrong cx (%i)\n", cx
);
2087 ok (cy
== 0, "Wrong cy (%i)\n", cy
);
2089 pImageList_SetImageCount(himl
, 3);
2090 ret
= pImageList_GetImageCount(himl
);
2091 ok(ret
== 3, "Unexpected image count after increase\n");
2093 /* Trying to actually add an image causes a crash on Windows */
2094 pImageList_Destroy(himl
);
2096 /* Negative values fail */
2097 himl
= pImageList_Create(-1, -1, ILC_COLORDDB
, 4, 4);
2098 ok(himl
== NULL
, "got %p\n", himl
);
2099 himl
= pImageList_Create(-1, 1, ILC_COLORDDB
, 4, 4);
2100 ok(himl
== NULL
, "got %p\n", himl
);
2101 himl
= pImageList_Create(1, -1, ILC_COLORDDB
, 4, 4);
2102 ok(himl
== NULL
, "got %p\n", himl
);
2105 static void check_color_table(const char *name
, HDC hdc
, HIMAGELIST himl
, UINT ilc
,
2106 RGBQUAD
*expect
, RGBQUAD
*broken_expect
)
2110 char bmi_buffer
[FIELD_OFFSET( BITMAPINFO
, bmiColors
[256] )];
2111 BITMAPINFO
*bmi
= (BITMAPINFO
*)bmi_buffer
;
2112 int i
, depth
= ilc
& 0xfe;
2114 ret
= pImageList_GetImageInfo(himl
, 0, &info
);
2115 ok(ret
, "got %d\n", ret
);
2116 ok(info
.hbmImage
!= NULL
, "got %p\n", info
.hbmImage
);
2118 memset(bmi_buffer
, 0, sizeof(bmi_buffer
));
2119 bmi
->bmiHeader
.biSize
= sizeof(bmi
->bmiHeader
);
2120 ret
= GetDIBits(hdc
, info
.hbmImage
, 0, 0, NULL
, bmi
, DIB_RGB_COLORS
);
2121 ok(ret
, "got %d\n", ret
);
2122 ok(bmi
->bmiHeader
.biBitCount
== depth
, "got %d\n", bmi
->bmiHeader
.biBitCount
);
2124 ret
= GetDIBits(hdc
, info
.hbmImage
, 0, 0, NULL
, bmi
, DIB_RGB_COLORS
);
2125 ok(ret
, "got %d\n", ret
);
2126 ok(bmi
->bmiHeader
.biBitCount
== depth
, "got %d\n", bmi
->bmiHeader
.biBitCount
);
2128 for (i
= 0; i
< (1 << depth
); i
++)
2129 ok((bmi
->bmiColors
[i
].rgbRed
== expect
[i
].rgbRed
&&
2130 bmi
->bmiColors
[i
].rgbGreen
== expect
[i
].rgbGreen
&&
2131 bmi
->bmiColors
[i
].rgbBlue
== expect
[i
].rgbBlue
) ||
2132 (broken_expect
&& broken(bmi
->bmiColors
[i
].rgbRed
== broken_expect
[i
].rgbRed
&&
2133 bmi
->bmiColors
[i
].rgbGreen
== broken_expect
[i
].rgbGreen
&&
2134 bmi
->bmiColors
[i
].rgbBlue
== broken_expect
[i
].rgbBlue
)),
2135 "%d: %s: got color[%d] %02x %02x %02x expect %02x %02x %02x\n", depth
, name
, i
,
2136 bmi
->bmiColors
[i
].rgbRed
, bmi
->bmiColors
[i
].rgbGreen
, bmi
->bmiColors
[i
].rgbBlue
,
2137 expect
[i
].rgbRed
, expect
[i
].rgbGreen
, expect
[i
].rgbBlue
);
2140 static void get_default_color_table(HDC hdc
, int bpp
, RGBQUAD
*table
)
2142 char bmi_buffer
[FIELD_OFFSET( BITMAPINFO
, bmiColors
[256] )];
2143 BITMAPINFO
*bmi
= (BITMAPINFO
*)bmi_buffer
;
2147 PALETTEENTRY entries
[256];
2152 tmp
= CreateBitmap( 1, 1, 1, 1, NULL
);
2153 memset(bmi_buffer
, 0, sizeof(bmi_buffer
));
2154 bmi
->bmiHeader
.biSize
= sizeof(bmi
->bmiHeader
);
2155 bmi
->bmiHeader
.biHeight
= 1;
2156 bmi
->bmiHeader
.biWidth
= 1;
2157 bmi
->bmiHeader
.biBitCount
= bpp
;
2158 bmi
->bmiHeader
.biPlanes
= 1;
2159 bmi
->bmiHeader
.biCompression
= BI_RGB
;
2160 GetDIBits( hdc
, tmp
, 0, 0, NULL
, bmi
, DIB_RGB_COLORS
);
2162 memcpy(table
, bmi
->bmiColors
, (1 << bpp
) * sizeof(RGBQUAD
));
2163 table
[7] = bmi
->bmiColors
[8];
2164 table
[8] = bmi
->bmiColors
[7];
2165 DeleteObject( tmp
);
2169 pal
= CreateHalftonePalette(hdc
);
2170 GetPaletteEntries(pal
, 0, 256, entries
);
2171 for (i
= 0; i
< 256; i
++)
2173 table
[i
].rgbRed
= entries
[i
].peRed
;
2174 table
[i
].rgbGreen
= entries
[i
].peGreen
;
2175 table
[i
].rgbBlue
= entries
[i
].peBlue
;
2176 table
[i
].rgbReserved
= 0;
2182 ok(0, "unhandled depth %d\n", bpp
);
2186 static void test_color_table(UINT ilc
)
2190 char bmi_buffer
[FIELD_OFFSET( BITMAPINFO
, bmiColors
[256] )];
2191 BITMAPINFO
*bmi
= (BITMAPINFO
*)bmi_buffer
;
2192 HDC hdc
= CreateCompatibleDC(0);
2193 HBITMAP dib4
, dib8
, dib32
;
2194 RGBQUAD rgb
[256], default_table
[256];
2196 get_default_color_table(hdc
, ilc
& 0xfe, default_table
);
2198 himl
= pImageList_Create(16, 16, ilc
, 0, 3);
2199 ok(himl
!= NULL
, "got %p\n", himl
);
2201 memset(bmi_buffer
, 0, sizeof(bmi_buffer
));
2202 bmi
->bmiHeader
.biSize
= sizeof(bmi
->bmiHeader
);
2203 bmi
->bmiHeader
.biHeight
= 16;
2204 bmi
->bmiHeader
.biWidth
= 16;
2205 bmi
->bmiHeader
.biBitCount
= 8;
2206 bmi
->bmiHeader
.biPlanes
= 1;
2207 bmi
->bmiHeader
.biCompression
= BI_RGB
;
2208 bmi
->bmiColors
[0].rgbRed
= 0xff;
2209 bmi
->bmiColors
[1].rgbGreen
= 0xff;
2210 bmi
->bmiColors
[2].rgbBlue
= 0xff;
2212 dib8
= CreateDIBSection(hdc
, bmi
, DIB_RGB_COLORS
, NULL
, NULL
, 0);
2214 bmi
->bmiHeader
.biBitCount
= 4;
2215 bmi
->bmiColors
[0].rgbRed
= 0xff;
2216 bmi
->bmiColors
[0].rgbGreen
= 0x00;
2217 bmi
->bmiColors
[0].rgbBlue
= 0xff;
2218 bmi
->bmiColors
[1].rgbRed
= 0xff;
2219 bmi
->bmiColors
[1].rgbGreen
= 0xff;
2220 bmi
->bmiColors
[1].rgbBlue
= 0x00;
2221 bmi
->bmiColors
[2].rgbRed
= 0x00;
2222 bmi
->bmiColors
[2].rgbGreen
= 0xff;
2223 bmi
->bmiColors
[2].rgbBlue
= 0xff;
2225 dib4
= CreateDIBSection(hdc
, bmi
, DIB_RGB_COLORS
, NULL
, NULL
, 0);
2227 bmi
->bmiHeader
.biBitCount
= 32;
2229 dib32
= CreateDIBSection(hdc
, bmi
, DIB_RGB_COLORS
, NULL
, NULL
, 0);
2231 /* add 32 first then 8. This won't set the color table */
2232 ret
= pImageList_Add(himl
, dib32
, NULL
);
2233 ok(ret
== 0, "got %d\n", ret
);
2234 ret
= pImageList_Add(himl
, dib8
, NULL
);
2235 ok(ret
== 1, "got %d\n", ret
);
2237 check_color_table("add 32, 8", hdc
, himl
, ilc
, default_table
, NULL
);
2239 /* since the previous _Adds didn't set the color table, this one will */
2240 ret
= pImageList_Remove(himl
, -1);
2241 ok(ret
, "got %d\n", ret
);
2242 ret
= pImageList_Add(himl
, dib8
, NULL
);
2243 ok(ret
== 0, "got %d\n", ret
);
2245 memset(rgb
, 0, sizeof(rgb
));
2246 rgb
[0].rgbRed
= 0xff;
2247 rgb
[1].rgbGreen
= 0xff;
2248 rgb
[2].rgbBlue
= 0xff;
2249 check_color_table("remove all, add 8", hdc
, himl
, ilc
, rgb
, default_table
);
2251 /* remove all, add 4. Color table remains the same since it's implicitly
2252 been set by the previous _Add */
2253 ret
= pImageList_Remove(himl
, -1);
2254 ok(ret
, "got %d\n", ret
);
2255 ret
= pImageList_Add(himl
, dib4
, NULL
);
2256 ok(ret
== 0, "got %d\n", ret
);
2257 check_color_table("remove all, add 4", hdc
, himl
, ilc
, rgb
, default_table
);
2259 pImageList_Destroy(himl
);
2260 himl
= pImageList_Create(16, 16, ilc
, 0, 3);
2261 ok(himl
!= NULL
, "got %p\n", himl
);
2264 ret
= pImageList_Add(himl
, dib4
, NULL
);
2265 ok(ret
== 0, "got %d\n", ret
);
2267 memset(rgb
, 0, 16 * sizeof(rgb
[0]));
2268 rgb
[0].rgbRed
= 0xff;
2269 rgb
[0].rgbBlue
= 0xff;
2270 rgb
[1].rgbRed
= 0xff;
2271 rgb
[1].rgbGreen
= 0xff;
2272 rgb
[2].rgbGreen
= 0xff;
2273 rgb
[2].rgbBlue
= 0xff;
2274 memcpy(rgb
+ 16, default_table
+ 16, 240 * sizeof(rgb
[0]));
2276 check_color_table("add 4", hdc
, himl
, ilc
, rgb
, default_table
);
2278 pImageList_Destroy(himl
);
2279 himl
= pImageList_Create(16, 16, ilc
, 0, 3);
2280 ok(himl
!= NULL
, "got %p\n", himl
);
2282 /* set color table, add 8 */
2283 ret
= pImageList_Remove(himl
, -1);
2284 ok(ret
, "got %d\n", ret
);
2285 memset(rgb
, 0, sizeof(rgb
));
2286 rgb
[0].rgbRed
= 0xcc;
2287 rgb
[1].rgbBlue
= 0xcc;
2288 ret
= pImageList_SetColorTable(himl
, 0, 2, rgb
);
2289 ok(ret
== 2, "got %d\n", ret
);
2290 /* the table is set, so this doesn't change it */
2291 ret
= pImageList_Add(himl
, dib8
, NULL
);
2292 ok(ret
== 0, "got %d\n", ret
);
2294 memcpy(rgb
+ 2, default_table
+ 2, 254 * sizeof(rgb
[0]));
2295 check_color_table("SetColorTable", hdc
, himl
, ilc
, rgb
, NULL
);
2297 DeleteObject(dib32
);
2301 pImageList_Destroy(himl
);
2304 static void test_copy(void)
2306 HIMAGELIST dst
, src
;
2310 dst
= pImageList_Create(5, 11, ILC_COLOR
, 1, 1);
2311 count
= pImageList_GetImageCount(dst
);
2312 ok(!count
, "ImageList not empty.\n");
2313 src
= createImageList(7, 13);
2314 count
= pImageList_GetImageCount(src
);
2315 ok(count
> 2, "Tests need an ImageList with more than 2 images\n");
2317 /* ImageList_Copy() cannot copy between two ImageLists */
2318 ret
= pImageList_Copy(dst
, 0, src
, 2, ILCF_MOVE
);
2319 ok(!ret
, "ImageList_Copy() should have returned FALSE\n");
2320 count
= pImageList_GetImageCount(dst
);
2321 ok(count
== 0, "Expected no image in dst ImageList, got %d\n", count
);
2323 pImageList_Destroy(dst
);
2324 pImageList_Destroy(src
);
2327 static void test_loadimage(void)
2332 list
= pImageList_LoadImageW( hinst
, MAKEINTRESOURCEW(IDB_BITMAP_128x15
), 16, 1, CLR_DEFAULT
,
2333 IMAGE_BITMAP
, LR_CREATEDIBSECTION
);
2334 ok( list
!= NULL
, "got %p\n", list
);
2335 flags
= pImageList_GetFlags( list
);
2336 ok( flags
== (ILC_COLOR4
| ILC_MASK
), "got %08x\n", flags
);
2337 pImageList_Destroy( list
);
2339 list
= pImageList_LoadImageW( hinst
, MAKEINTRESOURCEW(IDB_BITMAP_128x15
), 16, 1, CLR_NONE
,
2340 IMAGE_BITMAP
, LR_CREATEDIBSECTION
);
2341 ok( list
!= NULL
, "got %p\n", list
);
2342 flags
= pImageList_GetFlags( list
);
2343 ok( flags
== ILC_COLOR4
, "got %08x\n", flags
);
2344 pImageList_Destroy( list
);
2347 #define GetAValue(argb) ((BYTE) ((argb) >> 24))
2349 static void get_image_bits(HIMAGELIST himl
, int index
, int width
, int height
, UINT32
*bits
)
2353 BITMAPINFO bitmap_info
= {{sizeof(BITMAPINFOHEADER
), width
, height
, 1, 32, BI_RGB
, 0, 0, 0, 0, 0}};
2355 HDC hdc_dst
= CreateCompatibleDC(0);
2356 hbm_dst
= CreateDIBSection(hdc_dst
, &bitmap_info
, DIB_RGB_COLORS
, &bitmap_bits
, NULL
, 0);
2357 SelectObject(hdc_dst
, hbm_dst
);
2359 pImageList_Draw(himl
, index
, hdc_dst
, 0, 0, ILD_TRANSPARENT
);
2360 memcpy(bits
, bitmap_bits
, (size_t)(width
* height
* 32 / 8));
2362 DeleteObject(hbm_dst
);
2366 static void test_alpha(void)
2368 /* each line is a 2*1 bitmap */
2369 const static UINT32 test_bitmaps
[] =
2371 0x00654321, 0x00ABCDEF,
2372 0x00654321, 0x00654321,
2373 0x00ABCDEF, 0x00654321,
2374 0x00ABCDEF, 0x00ABCDEF,
2375 0x00654321, 0x01ABCDEF,
2376 0x01654321, 0x00ABCDEF,
2377 0x00654321, 0xFFABCDEF,
2378 0x00654321, 0x89ABCDEF,
2379 0xFF654321, 0x00ABCDEF,
2380 0xFF654321, 0xFFABCDEF,
2381 0xFF654321, 0x89ABCDEF,
2382 0x87654321, 0x00ABCDEF,
2383 0x87654321, 0xFFABCDEF,
2384 0x87654321, 0x89ABCDEF
2386 const static BYTE mask_bits
= 0xAA;
2390 HBITMAP hbm_test
, hbm_mask
;
2394 hdc
= CreateCompatibleDC(0);
2395 himl
= pImageList_Create(2, 1, ILC_COLOR32
| ILC_MASK
, 0, 15);
2397 for (i
= 0; i
< ARRAY_SIZE(test_bitmaps
); i
+= 2)
2399 hbm_test
= create_test_bitmap(hdc
, 2, 1, 32, test_bitmaps
+ i
);
2400 ret
= pImageList_AddMasked(himl
, hbm_test
, RGB(0x65,0x43,0x21));
2401 ok(ret
== i
/ 2, "ImageList_AddMasked returned %d, expected %d\n", ret
, i
/ 2);
2402 DeleteObject(hbm_test
);
2404 get_image_bits(himl
, i
/ 2, 2, 1, bits
);
2405 ok(GetAValue(bits
[0]) == GetAValue(test_bitmaps
[i
]) && GetAValue(bits
[1]) == GetAValue(test_bitmaps
[i
+ 1]),
2406 "Bitmap [%08X, %08X] returned alpha value [%02X, %02X], expected [%02X, %02X]\n",
2407 test_bitmaps
[i
], test_bitmaps
[i
+ 1], GetAValue(bits
[0]), GetAValue(bits
[1]),
2408 GetAValue(test_bitmaps
[i
]), GetAValue(test_bitmaps
[i
+ 1]));
2410 /* If all alpha values are zero, the image is considered to have no alpha and gets masked */
2411 if (!GetAValue(bits
[0]) && !GetAValue(bits
[1]))
2412 ok(bits
[0] == (test_bitmaps
[i
] == 0x654321 ? 0 : test_bitmaps
[i
]) &&
2413 bits
[1] == (test_bitmaps
[i
+ 1] == 0x654321 ? 0 : test_bitmaps
[i
+ 1]),
2414 "Bitmap [%08X, %08X] returned [%08X, %08X], expected [%08X, %08X]\n",
2415 test_bitmaps
[i
], test_bitmaps
[i
+ 1], bits
[0], bits
[1],
2416 test_bitmaps
[i
] == 0x654321 ? 0 : test_bitmaps
[i
],
2417 test_bitmaps
[i
+ 1] == 0x654321 ? 0 : test_bitmaps
[i
+ 1]);
2420 pImageList_Destroy(himl
);
2421 hbm_mask
= CreateBitmap(2, 1, 1, 1, &mask_bits
);
2422 himl
= pImageList_Create(2, 1, ILC_COLOR32
| ILC_MASK
, 0, 15);
2424 for (i
= 0; i
< ARRAY_SIZE(test_bitmaps
); i
+= 2)
2426 hbm_test
= create_test_bitmap(hdc
, 2, 1, 32, test_bitmaps
+ i
);
2427 ret
= pImageList_Add(himl
, hbm_test
, hbm_mask
);
2428 ok(ret
== i
/ 2, "ImageList_Add returned %d, expected %d\n", ret
, i
/ 2);
2429 DeleteObject(hbm_test
);
2431 get_image_bits(himl
, i
/ 2, 2, 1, bits
);
2432 ok(GetAValue(bits
[0]) == GetAValue(test_bitmaps
[i
]) && GetAValue(bits
[1]) == GetAValue(test_bitmaps
[i
+ 1]),
2433 "Bitmap [%08X, %08X] returned alpha value [%02X, %02X], expected [%02X, %02X]\n",
2434 test_bitmaps
[i
], test_bitmaps
[i
+ 1], GetAValue(bits
[0]), GetAValue(bits
[1]),
2435 GetAValue(test_bitmaps
[i
]), GetAValue(test_bitmaps
[i
+ 1]));
2437 /* If all alpha values are zero, the image is considered to have no alpha and gets masked */
2438 if (!GetAValue(bits
[0]) && !GetAValue(bits
[1]))
2439 ok(!bits
[0] && bits
[1] == test_bitmaps
[i
+ 1],
2440 "Bitmap [%08X, %08X] returned [%08X, %08X], expected [%08X, %08X]\n",
2441 test_bitmaps
[i
], test_bitmaps
[i
+ 1], bits
[0], bits
[1], 0, test_bitmaps
[i
+ 1]);
2444 if (GetAValue(bits
[0]) >= 0x80)
2445 ok(bits
[0] & 0x00FFFFFF, "Bitmap [%08X, %08X] has alpha and masked first pixel [%08X]\n",
2446 test_bitmaps
[i
], test_bitmaps
[i
+ 1], bits
[0]);
2450 pImageList_Destroy(himl
);
2451 DeleteObject(hbm_mask
);
2455 static void test_IImageList_Clone(void)
2457 IImageList
*imgl
, *imgl2
;
2462 himl
= pImageList_Create(16, 16, ILC_COLOR16
, 0, 3);
2463 imgl
= (IImageList
*)himl
;
2467 /* crashes on native */
2468 IImageList_Clone(imgl
, &IID_IImageList
, NULL
);
2471 hr
= IImageList_Clone(imgl
, &IID_IImageList
, (void**)&imgl2
);
2472 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2473 ref
= IImageList_Release(imgl2
);
2474 ok(ref
== 0, "got %u\n", ref
);
2476 IImageList_Release(imgl
);
2479 static void test_IImageList_GetBkColor(void)
2486 himl
= pImageList_Create(16, 16, ILC_COLOR16
, 0, 3);
2487 imgl
= (IImageList
*)himl
;
2491 /* crashes on native */
2492 IImageList_GetBkColor(imgl
, NULL
);
2495 hr
= IImageList_GetBkColor(imgl
, &color
);
2496 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2498 IImageList_Release(imgl
);
2501 static void test_IImageList_SetBkColor(void)
2508 himl
= pImageList_Create(16, 16, ILC_COLOR16
, 0, 3);
2509 imgl
= (IImageList
*)himl
;
2513 /* crashes on native */
2514 IImageList_SetBkColor(imgl
, RGB(0, 0, 0), NULL
);
2517 hr
= IImageList_SetBkColor(imgl
, CLR_NONE
, &color
);
2518 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2520 hr
= IImageList_SetBkColor(imgl
, CLR_NONE
, &color
);
2521 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2524 hr
= IImageList_GetBkColor(imgl
, &color
);
2525 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2526 ok(color
== CLR_NONE
, "got %x\n", color
);
2528 IImageList_Release(imgl
);
2531 static void test_IImageList_GetImageCount(void)
2538 himl
= pImageList_Create(16, 16, ILC_COLOR16
, 0, 3);
2539 imgl
= (IImageList
*)himl
;
2543 /* crashes on native */
2544 IImageList_GetImageCount(imgl
, NULL
);
2548 hr
= IImageList_GetImageCount(imgl
, &count
);
2549 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2550 ok(count
== 0, "got %d\n", count
);
2552 IImageList_Release(imgl
);
2555 static void test_IImageList_GetIconSize(void)
2562 himl
= pImageList_Create(16, 16, ILC_COLOR16
, 0, 3);
2563 imgl
= (IImageList
*)himl
;
2565 hr
= IImageList_GetIconSize(imgl
, NULL
, NULL
);
2566 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2568 hr
= IImageList_GetIconSize(imgl
, &cx
, NULL
);
2569 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2571 hr
= IImageList_GetIconSize(imgl
, NULL
, &cy
);
2572 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2574 IImageList_Release(imgl
);
2577 static void init_functions(void)
2579 HMODULE hComCtl32
= LoadLibraryA("comctl32.dll");
2581 #define X(f) p##f = (void*)GetProcAddress(hComCtl32, #f);
2582 #define X2(f, ord) p##f = (void*)GetProcAddress(hComCtl32, (const char *)ord);
2583 X(ImageList_Create
);
2584 X(ImageList_Destroy
);
2586 X(ImageList_AddMasked
);
2587 X(ImageList_DrawIndirect
);
2588 X(ImageList_SetImageCount
);
2589 X2(ImageList_SetColorTable
, 390);
2590 X(ImageList_GetFlags
);
2591 X(ImageList_BeginDrag
);
2592 X(ImageList_GetDragImage
);
2593 X(ImageList_EndDrag
);
2594 X(ImageList_GetImageCount
);
2595 X(ImageList_SetDragCursorImage
);
2596 X(ImageList_GetIconSize
);
2597 X(ImageList_SetIconSize
);
2598 X(ImageList_Remove
);
2599 X(ImageList_ReplaceIcon
);
2600 X(ImageList_Replace
);
2602 X(ImageList_GetImageInfo
);
2606 X(ImageList_LoadImageW
);
2607 X(ImageList_CoCreateInstance
);
2608 X(HIMAGELIST_QueryInterface
);
2614 START_TEST(imagelist
)
2616 ULONG_PTR ctx_cookie
;
2621 hinst
= GetModuleHandleA(NULL
);
2623 test_create_destroy();
2628 test_DrawIndirect();
2630 test_merge_colors();
2631 test_imagelist_storage();
2633 test_color_table(ILC_COLOR4
);
2634 test_color_table(ILC_COLOR8
);
2638 /* Now perform v6 tests */
2639 if (!load_v6_module(&ctx_cookie
, &hCtx
))
2644 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
2649 test_DrawIndirect();
2651 test_imagelist_storage();
2653 test_color_table(ILC_COLOR4
);
2654 test_color_table(ILC_COLOR8
);
2659 test_ImageList_DrawIndirect();
2660 test_shell_imagelist();
2663 test_IImageList_Add_Remove();
2664 test_IImageList_Get_SetImageCount();
2665 test_IImageList_Draw();
2666 test_IImageList_Merge();
2667 test_IImageList_Clone();
2668 test_IImageList_GetBkColor();
2669 test_IImageList_SetBkColor();
2670 test_IImageList_GetImageCount();
2671 test_IImageList_GetIconSize();
2675 unload_v6_module(ctx_cookie
, hCtx
);