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
);
91 static HRESULT (WINAPI
*pImageList_WriteEx
)(HIMAGELIST himl
, DWORD flags
, IStream
*stream
);
93 static HINSTANCE hinst
;
95 /* only used in interactive mode */
96 static void force_redraw(HWND hwnd
)
98 if (!winetest_interactive
)
101 RedrawWindow(hwnd
, NULL
, 0, RDW_UPDATENOW
);
105 static BOOL
is_v6_test(void)
107 return pHIMAGELIST_QueryInterface
!= NULL
;
110 /* These macros build cursor/bitmap data in 4x4 pixel blocks */
111 #define B(x,y) ((x?0xf0:0)|(y?0xf:0))
112 #define ROW1(a,b,c,d,e,f,g,h) B(a,b),B(c,d),B(e,f),B(g,h)
113 #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), \
114 ROW1(a,b,c,d,e,f,g,h), ROW1(a,b,c,d,e,f,g,h)
115 #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)
116 #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), \
117 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), \
118 ROW2(a,b,c,d,e,f,g,h,i,j,k,l)
120 static const BYTE empty_bits
[48*48/8];
122 static const BYTE icon_bits
[32*32/8] =
124 ROW32(0,0,0,0,0,0,0,0),
125 ROW32(0,0,1,1,1,1,0,0),
126 ROW32(0,1,1,1,1,1,1,0),
127 ROW32(0,1,1,0,0,1,1,0),
128 ROW32(0,1,1,0,0,1,1,0),
129 ROW32(0,1,1,1,1,1,1,0),
130 ROW32(0,0,1,1,1,1,0,0),
131 ROW32(0,0,0,0,0,0,0,0)
134 static const BYTE bitmap_bits
[48*48/8] =
136 ROW48(0,0,0,0,0,0,0,0,0,0,0,0),
137 ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
138 ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
139 ROW48(0,1,0,0,0,0,0,0,1,0,1,0),
140 ROW48(0,1,0,0,0,0,0,1,0,0,1,0),
141 ROW48(0,1,0,0,0,0,1,0,0,0,1,0),
142 ROW48(0,1,0,0,0,1,0,0,0,0,1,0),
143 ROW48(0,1,0,0,1,0,0,0,0,0,1,0),
144 ROW48(0,1,0,1,0,0,0,0,0,0,1,0),
145 ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
146 ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
147 ROW48(0,0,0,0,0,0,0,0,0,0,0,0)
150 static HIMAGELIST
createImageList(int cx
, int cy
)
152 /* Create an ImageList and put an image into it */
153 HIMAGELIST himl
= pImageList_Create(cx
, cy
, ILC_COLOR
, 1, 1);
154 HBITMAP hbm
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
156 ok(himl
!= NULL
, "Failed to create image list, %d x %d.\n", cx
, cy
);
157 pImageList_Add(himl
, hbm
, NULL
);
162 static HWND
create_window(void)
164 char className
[] = "bmwnd";
165 char winName
[] = "Test Bitmap";
167 static BOOL registered
= FALSE
;
173 cls
.style
= CS_HREDRAW
| CS_VREDRAW
| CS_GLOBALCLASS
;
174 cls
.lpfnWndProc
= DefWindowProcA
;
178 cls
.hIcon
= LoadIconA(0, (LPCSTR
)IDI_APPLICATION
);
179 cls
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
180 cls
.hbrBackground
= GetStockObject (WHITE_BRUSH
);
181 cls
.lpszMenuName
= 0;
182 cls
.lpszClassName
= className
;
184 RegisterClassA (&cls
);
189 hWnd
= CreateWindowA (className
, winName
,
190 WS_OVERLAPPEDWINDOW
,
191 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
194 if (winetest_interactive
)
196 ShowWindow (hWnd
, SW_SHOW
);
203 static HDC
show_image(HWND hwnd
, HIMAGELIST himl
, int idx
, int size
,
204 LPCSTR loc
, BOOL clear
)
208 if (!winetest_interactive
|| !himl
) return NULL
;
210 SetWindowTextA(hwnd
, loc
);
212 pImageList_Draw(himl
, idx
, hdc
, 0, 0, ILD_TRANSPARENT
);
218 BitBlt(hdc
, 0, 0, size
, size
, hdc
, size
+1, size
+1, SRCCOPY
);
219 ReleaseDC(hwnd
, hdc
);
226 /* Useful for checking differences */
227 static void dump_bits(const BYTE
*p
, const BYTE
*q
, int size
)
233 for (i
= 0; i
< size
* 2; i
++)
236 for (j
= 0; j
< size
; j
++)
237 printf("%c%c", p
[j
] & 0xf0 ? 'X' : ' ', p
[j
] & 0xf ? 'X' : ' ');
239 for (j
= 0; j
< size
; j
++)
240 printf("%c%c", q
[j
] & 0xf0 ? 'X' : ' ', q
[j
] & 0xf ? 'X' : ' ');
248 static void check_bits(HWND hwnd
, HIMAGELIST himl
, int idx
, int size
,
249 const BYTE
*checkbits
, LPCSTR loc
)
251 BYTE bits
[100*100/8];
256 if (!winetest_interactive
|| !himl
) return;
258 memset(bits
, 0, sizeof(bits
));
259 hdc
= show_image(hwnd
, himl
, idx
, size
, loc
, FALSE
);
261 c
= GetPixel(hdc
, 0, 0);
263 for (y
= 0; y
< size
; y
++)
265 for (x
= 0; x
< size
; x
++)
268 if (GetPixel(hdc
, x
, y
) != c
) bits
[i
] |= (0x80 >> (x
& 0x7));
272 BitBlt(hdc
, 0, 0, size
, size
, hdc
, size
+1, size
+1, SRCCOPY
);
273 ReleaseDC(hwnd
, hdc
);
275 ok (memcmp(bits
, checkbits
, (size
* size
)/8) == 0,
276 "%s: bits different\n", loc
);
277 if (memcmp(bits
, checkbits
, (size
* size
)/8))
278 dump_bits(bits
, checkbits
, size
);
281 static void test_begindrag(void)
283 HIMAGELIST himl
= createImageList(7,13);
289 count
= pImageList_GetImageCount(himl
);
290 ok(count
> 2, "Tests need an ImageList with more than 2 images\n");
292 /* Two BeginDrag() without EndDrag() in between */
293 ret
= pImageList_BeginDrag(himl
, 1, 0, 0);
294 drag
= pImageList_GetDragImage(NULL
, NULL
);
295 ok(ret
&& drag
, "ImageList_BeginDrag() failed\n");
296 ret
= pImageList_BeginDrag(himl
, 0, 3, 5);
297 ok(!ret
, "ImageList_BeginDrag() returned TRUE\n");
298 drag
= pImageList_GetDragImage(NULL
, &hotspot
);
299 ok(!!drag
, "No active ImageList drag left\n");
300 ok(hotspot
.x
== 0 && hotspot
.y
== 0, "New ImageList drag was created\n");
301 pImageList_EndDrag();
302 drag
= pImageList_GetDragImage(NULL
, NULL
);
303 ok(!drag
, "ImageList drag was not destroyed\n");
305 /* Invalid image index */
306 pImageList_BeginDrag(himl
, 0, 0, 0);
307 ret
= pImageList_BeginDrag(himl
, count
, 3, 5);
308 ok(!ret
, "ImageList_BeginDrag() returned TRUE\n");
309 drag
= pImageList_GetDragImage(NULL
, &hotspot
);
310 ok(drag
&& hotspot
.x
== 0 && hotspot
.y
== 0, "Active drag should not have been canceled\n");
311 pImageList_EndDrag();
312 drag
= pImageList_GetDragImage(NULL
, NULL
);
313 ok(!drag
, "ImageList drag was not destroyed\n");
314 /* Invalid negative image indexes succeed */
315 ret
= pImageList_BeginDrag(himl
, -17, 0, 0);
316 drag
= pImageList_GetDragImage(NULL
, NULL
);
317 ok(ret
&& drag
, "ImageList drag was created\n");
318 pImageList_EndDrag();
319 ret
= pImageList_BeginDrag(himl
, -1, 0, 0);
320 drag
= pImageList_GetDragImage(NULL
, NULL
);
321 ok(ret
&& drag
, "ImageList drag was created\n");
322 pImageList_EndDrag();
323 pImageList_Destroy(himl
);
326 static void test_hotspot(void)
337 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
338 static const struct hotspot hotspots
[HOTSPOTS_MAX
] = {
345 HIMAGELIST himl1
= createImageList(SIZEX1
, SIZEY1
);
346 HIMAGELIST himl2
= createImageList(SIZEX2
, SIZEY2
);
347 HWND hwnd
= create_window();
350 for (i
= 0; i
< HOTSPOTS_MAX
; i
++) {
351 for (j
= 0; j
< HOTSPOTS_MAX
; j
++) {
352 int dx1
= hotspots
[i
].dx
;
353 int dy1
= hotspots
[i
].dy
;
354 int dx2
= hotspots
[j
].dx
;
355 int dy2
= hotspots
[j
].dy
;
356 int correctx
, correcty
, newx
, newy
;
361 ret
= pImageList_BeginDrag(himl1
, 0, dx1
, dy1
);
362 ok(ret
!= 0, "BeginDrag failed for { %d, %d }\n", dx1
, dy1
);
363 sprintf(loc
, "BeginDrag (%d,%d)\n", i
, j
);
364 show_image(hwnd
, himl1
, 0, max(SIZEX1
, SIZEY1
), loc
, TRUE
);
366 /* check merging the dragged image with a second image */
367 ret
= pImageList_SetDragCursorImage(himl2
, 0, dx2
, dy2
);
368 ok(ret
!= 0, "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
370 sprintf(loc
, "SetDragCursorImage (%d,%d)\n", i
, j
);
371 show_image(hwnd
, himl2
, 0, max(SIZEX2
, SIZEY2
), loc
, TRUE
);
373 /* check new hotspot, it should be the same like the old one */
374 himlNew
= pImageList_GetDragImage(NULL
, &ppt
);
375 ok(ppt
.x
== dx1
&& ppt
.y
== dy1
,
376 "Expected drag hotspot [%d,%d] got [%ld,%ld]\n",
377 dx1
, dy1
, ppt
.x
, ppt
.y
);
378 /* check size of new dragged image */
379 pImageList_GetIconSize(himlNew
, &newx
, &newy
);
380 correctx
= max(SIZEX1
, max(SIZEX2
+ dx2
, SIZEX1
- dx2
));
381 correcty
= max(SIZEY1
, max(SIZEY2
+ dy2
, SIZEY1
- dy2
));
382 ok(newx
== correctx
&& newy
== correcty
,
383 "Expected drag image size [%d,%d] got [%d,%d]\n",
384 correctx
, correcty
, newx
, newy
);
385 sprintf(loc
, "GetDragImage (%d,%d)\n", i
, j
);
386 show_image(hwnd
, himlNew
, 0, max(correctx
, correcty
), loc
, TRUE
);
387 pImageList_EndDrag();
395 pImageList_Destroy(himl2
);
396 pImageList_Destroy(himl1
);
400 static void test_add_remove(void)
408 /* create an imagelist to play with */
409 himl
= pImageList_Create(84, 84, ILC_COLOR16
, 0, 3);
410 ok(himl
!=0,"failed to create imagelist\n");
412 /* load the icons to add to the image list */
413 hicon1
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
414 ok(hicon1
!= 0, "no hicon1\n");
415 hicon2
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
416 ok(hicon2
!= 0, "no hicon2\n");
417 hicon3
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
418 ok(hicon3
!= 0, "no hicon3\n");
420 /* remove when nothing exists */
421 ok(!pImageList_Remove(himl
, 0), "Removed nonexistent icon.\n");
422 /* removing everything from an empty imagelist should succeed */
423 ok(pImageList_Remove(himl
, -1), "Removed nonexistent icon\n");
426 ok(0 == pImageList_ReplaceIcon(himl
, -1, hicon1
), "Failed to add icon1.\n");
427 ok(1 == pImageList_ReplaceIcon(himl
, -1, hicon2
), "Failed to add icon2.\n");
428 ok(2 == pImageList_ReplaceIcon(himl
, -1, hicon3
), "Failed to add icon3.\n");
430 /* remove an index out of range */
431 ok(!pImageList_Remove(himl
, 4711), "removed nonexistent icon\n");
434 ok(pImageList_Remove(himl
, 0), "Can't remove 0\n");
435 ok(pImageList_Remove(himl
, 0), "Can't remove 0\n");
436 ok(pImageList_Remove(himl
, 0), "Can't remove 0\n");
438 /* remove one extra */
439 ok(!pImageList_Remove(himl
, 0), "Removed nonexistent icon.\n");
442 ok(pImageList_Destroy(himl
), "Failed to destroy imagelist.\n");
444 ok(-1 == pImageList_ReplaceIcon((HIMAGELIST
)0xdeadbeef, -1, hicon1
), "Don't crash on bad handle\n");
446 ok(DestroyIcon(hicon1
), "Failed to destroy icon 1.\n");
447 ok(DestroyIcon(hicon2
), "Failed to destroy icon 2.\n");
448 ok(DestroyIcon(hicon3
), "Failed to destroy icon 3.\n");
451 static void test_imagecount(void)
455 ok(0 == pImageList_GetImageCount((HIMAGELIST
)0xdeadbeef), "don't crash on bad handle\n");
457 if (!pImageList_SetImageCount
)
459 win_skip("ImageList_SetImageCount not available\n");
463 himl
= pImageList_Create(84, 84, ILC_COLOR16
, 0, 3);
464 ok(himl
!= 0, "Failed to create imagelist.\n");
466 ok(pImageList_SetImageCount(himl
, 3), "couldn't increase image count\n");
467 ok(pImageList_GetImageCount(himl
) == 3, "invalid image count after increase\n");
468 ok(pImageList_SetImageCount(himl
, 1), "couldn't decrease image count\n");
469 ok(pImageList_GetImageCount(himl
) == 1, "invalid image count after decrease to 1\n");
470 ok(pImageList_SetImageCount(himl
, 0), "couldn't decrease image count\n");
471 ok(pImageList_GetImageCount(himl
) == 0, "invalid image count after decrease to 0\n");
473 ok(pImageList_Destroy(himl
), "Failed to destroy imagelist.\n");
476 static void test_DrawIndirect(void)
484 IMAGELISTDRAWPARAMS imldp
;
488 if (!pImageList_DrawIndirect
)
490 win_skip("ImageList_DrawIndirect not available, skipping test\n");
494 hwndfortest
= create_window();
495 hdc
= GetDC(hwndfortest
);
496 ok(hdc
!=NULL
, "couldn't get DC\n");
498 /* create an imagelist to play with */
499 himl
= pImageList_Create(48, 48, ILC_COLOR16
, 0, 3);
500 ok(himl
!= 0, "Failed to create imagelist.\n");
502 /* load the icons to add to the image list */
503 hbm1
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
504 ok(hbm1
!= 0, "no bitmap 1\n");
505 hbm2
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
506 ok(hbm2
!= 0, "no bitmap 2\n");
507 hbm3
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
508 ok(hbm3
!= 0, "no bitmap 3\n");
511 ok(0 == pImageList_Add(himl
, hbm1
, 0),"failed to add bitmap 1\n");
512 ok(1 == pImageList_Add(himl
, hbm2
, 0),"failed to add bitmap 2\n");
514 if (pImageList_SetImageCount
)
516 ok(pImageList_SetImageCount(himl
,3),"Setimage count failed\n");
517 /*ok(2==ImageList_Add(himl, hbm3, NULL),"failed to add bitmap 3\n"); */
518 ok(pImageList_Replace(himl
, 2, hbm3
, 0),"failed to replace bitmap 3\n");
521 memset(&imldp
, 0, sizeof (imldp
));
522 ok(!pImageList_DrawIndirect(&imldp
), "zero data succeeded!\n");
523 imldp
.cbSize
= IMAGELISTDRAWPARAMS_V3_SIZE
;
524 ok(!pImageList_DrawIndirect(&imldp
), "zero hdc succeeded!\n");
526 ok(!pImageList_DrawIndirect(&imldp
),"zero himl succeeded!\n");
527 imldp
.himl
= (HIMAGELIST
)0xdeadbeef;
528 ok(!pImageList_DrawIndirect(&imldp
),"bad himl succeeded!\n");
531 force_redraw(hwndfortest
);
533 imldp
.fStyle
= SRCCOPY
;
534 imldp
.rgbBk
= CLR_DEFAULT
;
535 imldp
.rgbFg
= CLR_DEFAULT
;
538 ok(pImageList_DrawIndirect(&imldp
),"should succeed\n");
540 ok(pImageList_DrawIndirect(&imldp
),"should succeed\n");
542 ok(pImageList_DrawIndirect(&imldp
),"should succeed\n");
544 ok(!pImageList_DrawIndirect(&imldp
),"should fail\n");
547 ok(pImageList_Remove(himl
, 0), "removing 1st bitmap\n");
548 ok(pImageList_Remove(himl
, 0), "removing 2nd bitmap\n");
549 ok(pImageList_Remove(himl
, 0), "removing 3rd bitmap\n");
552 ok(pImageList_Destroy(himl
), "Failed to destroy imagelist.\n");
554 /* bitmaps should not be deleted by the imagelist */
555 ok(DeleteObject(hbm1
),"bitmap 1 can't be deleted\n");
556 ok(DeleteObject(hbm2
),"bitmap 2 can't be deleted\n");
557 ok(DeleteObject(hbm3
),"bitmap 3 can't be deleted\n");
559 ReleaseDC(hwndfortest
, hdc
);
560 DestroyWindow(hwndfortest
);
563 static int get_color_format(HBITMAP bmp
)
566 HDC hdc
= CreateCompatibleDC(0);
567 HBITMAP hOldBmp
= SelectObject(hdc
, bmp
);
570 memset(&bmi
, 0, sizeof(bmi
));
571 bmi
.bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
572 ret
= GetDIBits(hdc
, bmp
, 0, 0, 0, &bmi
, DIB_RGB_COLORS
);
573 ok(ret
, "GetDIBits failed\n");
575 SelectObject(hdc
, hOldBmp
);
577 return bmi
.bmiHeader
.biBitCount
;
580 static void test_merge_colors(void)
582 HIMAGELIST himl
[8], hmerge
;
583 int sizes
[] = { ILC_COLOR
, ILC_COLOR
| ILC_MASK
, ILC_COLOR4
, ILC_COLOR8
, ILC_COLOR16
, ILC_COLOR24
, ILC_COLOR32
, ILC_COLORDDB
};
588 hicon1
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
589 ok(hicon1
!= NULL
, "failed to create hicon1\n");
591 for (i
= 0; i
< 8; i
++)
593 himl
[i
] = pImageList_Create(32, 32, sizes
[i
], 0, 3);
594 ok(himl
[i
] != NULL
, "failed to create himl[%d]\n", i
);
595 ok(0 == pImageList_ReplaceIcon(himl
[i
], -1, hicon1
), "Failed to add icon1 to himl[%d].\n", i
);
596 if (i
== 0 || i
== 1 || i
== 7)
598 pImageList_GetImageInfo(himl
[i
], 0, &info
);
599 sizes
[i
] = get_color_format(info
.hbmImage
);
603 for (i
= 0; i
< 8; i
++)
604 for (j
= 0; j
< 8; j
++)
606 hmerge
= pImageList_Merge(himl
[i
], 0, himl
[j
], 0, 0, 0);
607 ok(hmerge
!= NULL
, "merge himl[%d], himl[%d] failed\n", i
, j
);
609 pImageList_GetImageInfo(hmerge
, 0, &info
);
610 bpp
= get_color_format(info
.hbmImage
);
611 /* ILC_COLOR[X] is defined as [X] */
612 if (i
== 4 && j
== 7)
613 ok(bpp
== 16, /* merging ILC_COLOR16 with ILC_COLORDDB seems to be a special case */
614 "wrong biBitCount %d when merging lists %d (%d) and %d (%d)\n", bpp
, i
, sizes
[i
], j
, sizes
[j
]);
616 ok(bpp
== (i
> j
? sizes
[i
] : sizes
[j
]),
617 "wrong biBitCount %d when merging lists %d (%d) and %d (%d)\n", bpp
, i
, sizes
[i
], j
, sizes
[j
]);
618 ok(info
.hbmMask
!= 0, "Imagelist merged from %d and %d had no mask\n", i
, j
);
620 pImageList_Destroy(hmerge
);
623 for (i
= 0; i
< 8; i
++)
624 pImageList_Destroy(himl
[i
]);
627 static void test_merge(void)
629 HIMAGELIST himl1
, himl2
, hmerge
;
631 HWND hwnd
= create_window();
633 himl1
= pImageList_Create(32, 32, 0, 0, 3);
634 ok(himl1
!= NULL
,"failed to create himl1\n");
636 himl2
= pImageList_Create(32, 32, 0, 0, 3);
637 ok(himl2
!= NULL
,"failed to create himl2\n");
639 hicon1
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
640 ok(hicon1
!= NULL
, "failed to create hicon1\n");
642 if (!himl1
|| !himl2
|| !hicon1
)
645 ok(0 == pImageList_ReplaceIcon(himl2
, -1, hicon1
), "Failed to add icon1 to himl2.\n");
646 check_bits(hwnd
, himl2
, 0, 32, icon_bits
, "add icon1 to himl2");
648 /* If himl1 has no images, merge still succeeds */
649 hmerge
= pImageList_Merge(himl1
, -1, himl2
, 0, 0, 0);
650 ok(hmerge
!= NULL
, "merge himl1,-1 failed\n");
651 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl1,-1");
652 pImageList_Destroy(hmerge
);
654 hmerge
= pImageList_Merge(himl1
, 0, himl2
, 0, 0, 0);
655 ok(hmerge
!= NULL
,"merge himl1,0 failed\n");
656 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl1,0");
657 pImageList_Destroy(hmerge
);
659 /* Same happens if himl2 is empty */
660 pImageList_Destroy(himl2
);
661 himl2
= pImageList_Create(32, 32, 0, 0, 3);
662 ok(himl2
!= NULL
,"failed to recreate himl2\n");
666 hmerge
= pImageList_Merge(himl1
, -1, himl2
, -1, 0, 0);
667 ok(hmerge
!= NULL
, "merge himl2,-1 failed\n");
668 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl2,-1");
669 pImageList_Destroy(hmerge
);
671 hmerge
= pImageList_Merge(himl1
, -1, himl2
, 0, 0, 0);
672 ok(hmerge
!= NULL
, "merge himl2,0 failed\n");
673 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl2,0");
674 pImageList_Destroy(hmerge
);
676 /* Now try merging an image with itself */
677 ok(0 == pImageList_ReplaceIcon(himl2
, -1, hicon1
), "Failed to re-add icon1 to himl2.\n");
679 hmerge
= pImageList_Merge(himl2
, 0, himl2
, 0, 0, 0);
680 ok(hmerge
!= NULL
, "merge himl2 with itself failed\n");
681 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl2 with itself");
682 pImageList_Destroy(hmerge
);
684 /* Try merging 2 different image lists */
685 ok(0 == pImageList_ReplaceIcon(himl1
, -1, hicon1
), "Failed to add icon1 to himl1.\n");
687 hmerge
= pImageList_Merge(himl1
, 0, himl2
, 0, 0, 0);
688 ok(hmerge
!= NULL
, "merge himl1 with himl2 failed\n");
689 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl1 with himl2");
690 pImageList_Destroy(hmerge
);
692 hmerge
= pImageList_Merge(himl1
, 0, himl2
, 0, 8, 16);
693 ok(hmerge
!= NULL
, "merge himl1 with himl2 8,16 failed\n");
694 check_bits(hwnd
, hmerge
, 0, 32, empty_bits
, "merge himl1 with himl2, 8,16");
695 pImageList_Destroy(hmerge
);
697 pImageList_Destroy(himl1
);
698 pImageList_Destroy(himl2
);
703 /*********************** imagelist storage test ***************************/
709 IStream IStream_iface
;
713 static struct memstream
*impl_from_IStream(IStream
*iface
)
715 return CONTAINING_RECORD(iface
, struct memstream
, IStream_iface
);
718 static HRESULT STDMETHODCALLTYPE
Test_Stream_QueryInterface(IStream
*iface
, REFIID riid
,
721 ok(0, "unexpected call\n");
725 static ULONG STDMETHODCALLTYPE
Test_Stream_AddRef(IStream
*iface
)
727 ok(0, "unexpected call\n");
731 static ULONG STDMETHODCALLTYPE
Test_Stream_Release(IStream
*iface
)
733 ok(0, "unexpected call\n");
737 static HRESULT STDMETHODCALLTYPE
Test_Stream_Read(IStream
*iface
, void *pv
, ULONG cb
,
740 struct memstream
*stream
= impl_from_IStream(iface
);
741 return IStream_Read(stream
->stream
, pv
, cb
, pcbRead
);
744 static HRESULT STDMETHODCALLTYPE
Test_Stream_Write(IStream
*iface
, const void *pv
, ULONG cb
,
747 struct memstream
*stream
= impl_from_IStream(iface
);
748 return IStream_Write(stream
->stream
, pv
, cb
, pcbWritten
);
751 static HRESULT STDMETHODCALLTYPE
Test_Stream_Seek(IStream
*iface
, LARGE_INTEGER offset
, DWORD origin
,
752 ULARGE_INTEGER
*new_pos
)
754 struct memstream
*stream
= impl_from_IStream(iface
);
758 ok(origin
== STREAM_SEEK_CUR
, "Unexpected origin %ld.\n", origin
);
759 ok(offset
.QuadPart
== 0, "Unexpected offset %s.\n", wine_dbgstr_longlong(offset
.QuadPart
));
760 ok(new_pos
!= NULL
, "Unexpected out position pointer.\n");
761 return IStream_Seek(stream
->stream
, offset
, origin
, new_pos
);
765 ok(0, "unexpected call\n");
770 static HRESULT STDMETHODCALLTYPE
Test_Stream_SetSize(IStream
*iface
, ULARGE_INTEGER libNewSize
)
772 ok(0, "unexpected call\n");
776 static HRESULT STDMETHODCALLTYPE
Test_Stream_CopyTo(IStream
*iface
, IStream
*pstm
,
777 ULARGE_INTEGER cb
, ULARGE_INTEGER
*pcbRead
,
778 ULARGE_INTEGER
*pcbWritten
)
780 ok(0, "unexpected call\n");
784 static HRESULT STDMETHODCALLTYPE
Test_Stream_Commit(IStream
*iface
, DWORD grfCommitFlags
)
786 ok(0, "unexpected call\n");
790 static HRESULT STDMETHODCALLTYPE
Test_Stream_Revert(IStream
*iface
)
792 ok(0, "unexpected call\n");
796 static HRESULT STDMETHODCALLTYPE
Test_Stream_LockRegion(IStream
*iface
, ULARGE_INTEGER libOffset
,
797 ULARGE_INTEGER cb
, DWORD dwLockType
)
799 ok(0, "unexpected call\n");
803 static HRESULT STDMETHODCALLTYPE
Test_Stream_UnlockRegion(IStream
*iface
, ULARGE_INTEGER libOffset
,
804 ULARGE_INTEGER cb
, DWORD dwLockType
)
806 ok(0, "unexpected call\n");
810 static HRESULT STDMETHODCALLTYPE
Test_Stream_Stat(IStream
*iface
, STATSTG
*pstatstg
,
813 ok(0, "unexpected call\n");
817 static HRESULT STDMETHODCALLTYPE
Test_Stream_Clone(IStream
*iface
, IStream
**ppstm
)
819 ok(0, "unexpected call\n");
823 static const IStreamVtbl Test_Stream_Vtbl
=
825 Test_Stream_QueryInterface
,
835 Test_Stream_LockRegion
,
836 Test_Stream_UnlockRegion
,
841 static void init_memstream(struct memstream
*stream
)
845 stream
->IStream_iface
.lpVtbl
= &Test_Stream_Vtbl
;
846 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
->stream
);
847 ok(hr
== S_OK
, "Failed to create a stream, hr %#lx.\n", hr
);
850 static void cleanup_memstream(struct memstream
*stream
)
852 IStream_Release(stream
->stream
);
855 static INT
DIB_GetWidthBytes( int width
, int bpp
)
857 return ((width
* bpp
+ 31) / 8) & ~3;
860 static ULONG
check_bitmap_data(const ILHEAD
*header
, const char *bm_data
,
861 ULONG bm_data_size
, const SIZE
*bmpsize
, INT bpp
, const char *comment
)
863 const BITMAPFILEHEADER
*bmfh
= (const BITMAPFILEHEADER
*)bm_data
;
864 const BITMAPINFOHEADER
*bmih
= (const BITMAPINFOHEADER
*)(bm_data
+ sizeof(*bmfh
));
865 ULONG hdr_size
, image_size
;
867 hdr_size
= sizeof(*bmfh
) + sizeof(*bmih
);
868 if (bmih
->biBitCount
<= 8) hdr_size
+= (1 << bpp
) * sizeof(RGBQUAD
);
870 ok(bmfh
->bfType
== (('M' << 8) | 'B'), "wrong bfType 0x%02x\n", bmfh
->bfType
);
871 ok(bmfh
->bfSize
== hdr_size
, "wrong bfSize 0x%02lx\n", bmfh
->bfSize
);
872 ok(bmfh
->bfReserved1
== 0, "wrong bfReserved1 0x%02x\n", bmfh
->bfReserved1
);
873 ok(bmfh
->bfReserved2
== 0, "wrong bfReserved2 0x%02x\n", bmfh
->bfReserved2
);
874 ok(bmfh
->bfOffBits
== hdr_size
, "wrong bfOffBits 0x%02lx\n", bmfh
->bfOffBits
);
876 ok(bmih
->biSize
== sizeof(*bmih
), "wrong biSize %ld\n", bmih
->biSize
);
877 ok(bmih
->biPlanes
== 1, "wrong biPlanes %d\n", bmih
->biPlanes
);
878 ok(bmih
->biBitCount
== bpp
, "wrong biBitCount %d\n", bmih
->biBitCount
);
880 image_size
= DIB_GetWidthBytes(bmih
->biWidth
, bmih
->biBitCount
) * bmih
->biHeight
;
881 ok(bmih
->biSizeImage
== image_size
, "wrong biSizeImage %lu\n", bmih
->biSizeImage
);
882 ok(bmih
->biWidth
== bmpsize
->cx
&& bmih
->biHeight
== bmpsize
->cy
, "Unexpected bitmap size %ld x %ld, "
883 "expected %ld x %ld\n", bmih
->biWidth
, bmih
->biHeight
, bmpsize
->cx
, bmpsize
->cy
);
889 sprintf(fname
, "bmp_%s.bmp", comment
);
890 f
= fopen(fname
, "wb");
891 fwrite(bm_data
, 1, bm_data_size
, f
);
895 return hdr_size
+ image_size
;
898 static BOOL
is_v6_header(const ILHEAD
*header
)
900 return (header
->usVersion
& 0xff00) == 0x600;
903 static void check_ilhead_data(const ILHEAD
*ilh
, INT cx
, INT cy
, INT cur
, INT max
, INT grow
, INT flags
)
907 ok(ilh
->usMagic
== IMAGELIST_MAGIC
, "wrong usMagic %4x (expected %02x)\n", ilh
->usMagic
, IMAGELIST_MAGIC
);
908 ok(ilh
->usVersion
== 0x101 ||
909 ilh
->usVersion
== 0x600 || /* WinXP/W2k3 */
910 ilh
->usVersion
== 0x620, "Unknown usVersion %#x.\n", ilh
->usVersion
);
911 ok(ilh
->cCurImage
== cur
, "wrong cCurImage %d (expected %d)\n", ilh
->cCurImage
, cur
);
914 grow_aligned
= (WORD
)(grow
+ 3) & ~3;
916 if (is_v6_header(ilh
))
918 grow
= (WORD
)(grow
+ 2 + 3) & ~3;
919 ok(ilh
->cGrow
== grow
|| broken(ilh
->cGrow
== grow_aligned
) /* XP/Vista */,
920 "Unexpected cGrow %d, expected %d\n", ilh
->cGrow
, grow
);
924 ok(ilh
->cMaxImage
== max
, "wrong cMaxImage %d (expected %d)\n", ilh
->cMaxImage
, max
);
925 ok(ilh
->cGrow
== grow_aligned
, "Unexpected cGrow %d, expected %d\n", ilh
->cGrow
, grow_aligned
);
928 ok(ilh
->cx
== cx
, "wrong cx %d (expected %d)\n", ilh
->cx
, cx
);
929 ok(ilh
->cy
== cy
, "wrong cy %d (expected %d)\n", ilh
->cy
, cy
);
930 ok(ilh
->bkcolor
== CLR_NONE
, "wrong bkcolor %lx\n", ilh
->bkcolor
);
931 ok(ilh
->flags
== flags
|| broken(!(ilh
->flags
& 0xfe) && (flags
& 0xfe) == ILC_COLOR4
), /* <= w2k */
932 "wrong flags %04x\n", ilh
->flags
);
933 ok(ilh
->ovls
[0] == -1, "wrong ovls[0] %04x\n", ilh
->ovls
[0]);
934 ok(ilh
->ovls
[1] == -1, "wrong ovls[1] %04x\n", ilh
->ovls
[1]);
935 ok(ilh
->ovls
[2] == -1, "wrong ovls[2] %04x\n", ilh
->ovls
[2]);
936 ok(ilh
->ovls
[3] == -1, "wrong ovls[3] %04x\n", ilh
->ovls
[3]);
939 static HBITMAP
create_bitmap(INT cx
, INT cy
, COLORREF color
, const char *comment
)
943 HBITMAP hbmp
, hbmp_old
;
945 RECT rc
= { 0, 0, cx
, cy
};
947 hdc
= CreateCompatibleDC(0);
949 memset(&bmi
, 0, sizeof(bmi
));
950 bmi
.bmiHeader
.biSize
= sizeof(bmi
.bmiHeader
);
951 bmi
.bmiHeader
.biWidth
= cx
;
952 bmi
.bmiHeader
.biHeight
= cy
;
953 bmi
.bmiHeader
.biBitCount
= 24;
954 bmi
.bmiHeader
.biPlanes
= 1;
955 bmi
.bmiHeader
.biCompression
= BI_RGB
;
956 hbmp
= CreateDIBSection(hdc
, &bmi
, DIB_RGB_COLORS
, NULL
, NULL
, 0);
958 hbmp_old
= SelectObject(hdc
, hbmp
);
960 hbrush
= CreateSolidBrush(color
);
961 FillRect(hdc
, &rc
, hbrush
);
962 DeleteObject(hbrush
);
964 DrawTextA(hdc
, comment
, -1, &rc
, DT_CENTER
| DT_VCENTER
| DT_SINGLELINE
);
966 SelectObject(hdc
, hbmp_old
);
972 static inline void imagelist_get_bitmap_size(const ILHEAD
*header
, SIZE
*sz
)
974 const int tile_count
= 4;
976 if (is_v6_header(header
))
979 sz
->cy
= header
->cMaxImage
* header
->cy
;
983 sz
->cx
= header
->cx
* tile_count
;
984 sz
->cy
= ((header
->cMaxImage
+ tile_count
- 1) / tile_count
) * header
->cy
;
988 /* Grow argument matches what was used when imagelist was created. */
989 static void check_iml_data(HIMAGELIST himl
, INT cx
, INT cy
, INT cur
, INT max
, INT grow
,
990 INT flags
, const char *comment
)
992 INT ret
, cxx
, cyy
, size
;
993 struct memstream stream
;
994 const ILHEAD
*header
;
1004 ret
= pImageList_GetImageCount(himl
);
1005 ok(ret
== cur
, "%s: expected image count %d got %d\n", comment
, cur
, ret
);
1007 ret
= pImageList_GetIconSize(himl
, &cxx
, &cyy
);
1008 ok(ret
, "ImageList_GetIconSize failed\n");
1009 ok(cxx
== cx
, "%s: wrong cx %d (expected %d)\n", comment
, cxx
, cx
);
1010 ok(cyy
== cy
, "%s: wrong cy %d (expected %d)\n", comment
, cyy
, cy
);
1012 init_memstream(&stream
);
1013 b
= pImageList_Write(himl
, &stream
.IStream_iface
);
1014 ok(b
, "%s: ImageList_Write failed\n", comment
);
1016 hr
= GetHGlobalFromStream(stream
.stream
, &hglobal
);
1017 ok(hr
== S_OK
, "%s: Failed to get hglobal, %#lx\n", comment
, hr
);
1019 hr
= IStream_Stat(stream
.stream
, &stat
, STATFLAG_NONAME
);
1020 ok(hr
== S_OK
, "Stat() failed, hr %#lx.\n", hr
);
1022 data
= GlobalLock(hglobal
);
1024 ok(data
!= 0, "%s: ImageList_Write didn't write any data\n", comment
);
1025 ok(stat
.cbSize
.LowPart
> sizeof(ILHEAD
), "%s: ImageList_Write wrote not enough data\n", comment
);
1027 header
= (const ILHEAD
*)data
;
1028 check_ilhead_data(header
, cx
, cy
, cur
, max
, grow
, flags
);
1029 imagelist_get_bitmap_size(header
, &bmpsize
);
1030 size
= check_bitmap_data(header
, data
+ sizeof(ILHEAD
), stat
.cbSize
.LowPart
- sizeof(ILHEAD
),
1031 &bmpsize
, flags
& 0xfe, comment
);
1032 if (!is_v6_header(header
) && size
< stat
.cbSize
.LowPart
- sizeof(ILHEAD
)) /* mask is present */
1034 ok( flags
& ILC_MASK
, "%s: extra data %lu/%u but mask not expected\n", comment
, stat
.cbSize
.LowPart
, size
);
1035 check_bitmap_data(header
, data
+ sizeof(ILHEAD
) + size
, stat
.cbSize
.LowPart
- sizeof(ILHEAD
) - size
,
1036 &bmpsize
, 1, comment
);
1039 /* rewind and reconstruct from stream */
1041 IStream_Seek(stream
.stream
, mv
, STREAM_SEEK_SET
, NULL
);
1042 himl2
= pImageList_Read(&stream
.IStream_iface
);
1043 ok(himl2
!= NULL
, "%s: Failed to deserialize imagelist\n", comment
);
1044 pImageList_Destroy(himl2
);
1046 GlobalUnlock(hglobal
);
1047 cleanup_memstream(&stream
);
1050 static void image_list_add_bitmap(HIMAGELIST himl
, BYTE grey
, int i
)
1056 sprintf(comment
, "%d", i
);
1057 hbm
= create_bitmap(BMP_CX
, BMP_CX
, RGB(grey
, grey
, grey
), comment
);
1058 ret
= pImageList_Add(himl
, hbm
, NULL
);
1059 ok(ret
!= -1, "Failed to add image to imagelist.\n");
1063 static void image_list_init(HIMAGELIST himl
, INT grow
)
1066 static const struct test_data
1069 INT cx
, cy
, cur
, max
, bpp
;
1070 const char *comment
;
1073 { 255, BMP_CX
, BMP_CX
, 1, 2, 24, "total 1" },
1074 { 170, BMP_CX
, BMP_CX
, 2, 7, 24, "total 2" },
1075 { 85, BMP_CX
, BMP_CX
, 3, 7, 24, "total 3" },
1076 { 0, BMP_CX
, BMP_CX
, 4, 7, 24, "total 4" },
1077 { 0, BMP_CX
, BMP_CX
, 5, 7, 24, "total 5" },
1078 { 85, BMP_CX
, BMP_CX
, 6, 7, 24, "total 6" },
1079 { 170, BMP_CX
, BMP_CX
, 7, 12, 24, "total 7" },
1080 { 255, BMP_CX
, BMP_CX
, 8, 12, 24, "total 8" },
1081 { 255, BMP_CX
, BMP_CX
, 9, 12, 24, "total 9" },
1082 { 170, BMP_CX
, BMP_CX
, 10, 12, 24, "total 10" },
1083 { 85, BMP_CX
, BMP_CX
, 11, 12, 24, "total 11" },
1084 { 0, BMP_CX
, BMP_CX
, 12, 17, 24, "total 12" },
1085 { 0, BMP_CX
, BMP_CX
, 13, 17, 24, "total 13" },
1086 { 85, BMP_CX
, BMP_CX
, 14, 17, 24, "total 14" },
1087 { 170, BMP_CX
, BMP_CX
, 15, 17, 24, "total 15" },
1088 { 255, BMP_CX
, BMP_CX
, 16, 17, 24, "total 16" },
1089 { 255, BMP_CX
, BMP_CX
, 17, 22, 24, "total 17" },
1090 { 170, BMP_CX
, BMP_CX
, 18, 22, 24, "total 18" },
1091 { 85, BMP_CX
, BMP_CX
, 19, 22, 24, "total 19" },
1092 { 0, BMP_CX
, BMP_CX
, 20, 22, 24, "total 20" },
1093 { 0, BMP_CX
, BMP_CX
, 21, 22, 24, "total 21" },
1094 { 85, BMP_CX
, BMP_CX
, 22, 27, 24, "total 22" },
1095 { 170, BMP_CX
, BMP_CX
, 23, 27, 24, "total 23" },
1096 { 255, BMP_CX
, BMP_CX
, 24, 27, 24, "total 24" }
1099 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 2, grow
, ILC_COLOR24
, "total 0");
1101 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
1103 image_list_add_bitmap(himl
, td
[i
].grey
, i
+ 1);
1104 check_iml_data(himl
, td
[i
].cx
, td
[i
].cy
, td
[i
].cur
, td
[i
].max
, grow
, td
[i
].bpp
, td
[i
].comment
);
1108 static void test_imagelist_storage(void)
1115 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 1, 1);
1116 ok(himl
!= 0, "ImageList_Create failed\n");
1118 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 2, 1, ILC_COLOR24
, "empty");
1120 image_list_init(himl
, 1);
1121 check_iml_data(himl
, BMP_CX
, BMP_CX
, 24, 27, 1, ILC_COLOR24
, "orig");
1123 ret
= pImageList_Remove(himl
, 4);
1124 ok(ret
, "ImageList_Remove failed\n");
1125 check_iml_data(himl
, BMP_CX
, BMP_CX
, 23, 27, 1, ILC_COLOR24
, "1");
1127 ret
= pImageList_Remove(himl
, 5);
1128 ok(ret
, "ImageList_Remove failed\n");
1129 check_iml_data(himl
, BMP_CX
, BMP_CX
, 22, 27, 1, ILC_COLOR24
, "2");
1131 ret
= pImageList_Remove(himl
, 6);
1132 ok(ret
, "ImageList_Remove failed\n");
1133 check_iml_data(himl
, BMP_CX
, BMP_CX
, 21, 27, 1, ILC_COLOR24
, "3");
1135 ret
= pImageList_Remove(himl
, 7);
1136 ok(ret
, "ImageList_Remove failed\n");
1137 check_iml_data(himl
, BMP_CX
, BMP_CX
, 20, 27, 1, ILC_COLOR24
, "4");
1139 ret
= pImageList_Remove(himl
, -2);
1140 ok(!ret
, "ImageList_Remove(-2) should fail\n");
1141 check_iml_data(himl
, BMP_CX
, BMP_CX
, 20, 27, 1, ILC_COLOR24
, "5");
1143 ret
= pImageList_Remove(himl
, 20);
1144 ok(!ret
, "ImageList_Remove(20) should fail\n");
1145 check_iml_data(himl
, BMP_CX
, BMP_CX
, 20, 27, 1, ILC_COLOR24
, "6");
1147 ret
= pImageList_Remove(himl
, -1);
1148 ok(ret
, "ImageList_Remove(-1) failed\n");
1149 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 4, 1, ILC_COLOR24
, "7");
1151 ret
= pImageList_Destroy(himl
);
1152 ok(ret
, "ImageList_Destroy failed\n");
1154 /* test ImageList_Create storage allocation */
1156 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 0, 32);
1157 ok(himl
!= 0, "ImageList_Create failed\n");
1158 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 1, 32, ILC_COLOR24
, "init 0 grow 32");
1159 hbm
= create_bitmap(BMP_CX
, BMP_CX
* 9, 0, "9");
1160 ret
= pImageList_Add(himl
, hbm
, NULL
);
1161 ok(ret
== 0, "ImageList_Add returned %d, expected 0\n", ret
);
1162 check_iml_data(himl
, BMP_CX
, BMP_CX
, 1, 34, 32, ILC_COLOR24
, "add 1 x 9");
1164 ret
= pImageList_Destroy(himl
);
1165 ok(ret
, "ImageList_Destroy failed\n");
1167 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 4, 4);
1168 ok(himl
!= 0, "ImageList_Create failed\n");
1169 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 4, ILC_COLOR24
, "init 4 grow 4");
1170 hbm
= create_bitmap(BMP_CX
* 9, BMP_CX
, 0, "9");
1171 ret
= pImageList_Add(himl
, hbm
, NULL
);
1172 ok(ret
== 0, "ImageList_Add returned %d, expected 0\n", ret
);
1173 check_iml_data(himl
, BMP_CX
, BMP_CX
, 9, 15, 4, ILC_COLOR24
, "add 9 x 1");
1174 ret
= pImageList_Add(himl
, hbm
, NULL
);
1175 ok(ret
== 9, "ImageList_Add returned %d, expected 9\n", ret
);
1176 check_iml_data(himl
, BMP_CX
, BMP_CX
, 18, 25, 4, ILC_COLOR24
, "add 9 x 1");
1178 ret
= pImageList_Destroy(himl
);
1179 ok(ret
, "ImageList_Destroy failed\n");
1181 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 207, 209);
1182 ok(himl
!= 0, "ImageList_Create failed\n");
1183 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 208, 209, ILC_COLOR24
, "init 207 grow 209");
1184 ret
= pImageList_Destroy(himl
);
1185 ok(ret
, "ImageList_Destroy failed\n");
1187 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 209, 207);
1188 ok(himl
!= 0, "ImageList_Create failed\n");
1189 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 210, 207, ILC_COLOR24
, "init 209 grow 207");
1190 ret
= pImageList_Destroy(himl
);
1191 ok(ret
, "ImageList_Destroy failed\n");
1193 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 14, 4);
1194 ok(himl
!= 0, "ImageList_Create failed\n");
1195 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 15, 4, ILC_COLOR24
, "init 14 grow 4");
1196 ret
= pImageList_Destroy(himl
);
1197 ok(ret
, "ImageList_Destroy failed\n");
1199 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 5, 9);
1200 ok(himl
!= 0, "ImageList_Create failed\n");
1201 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 6, 9, ILC_COLOR24
, "init 5 grow 9");
1202 ret
= pImageList_Destroy(himl
);
1203 ok(ret
, "ImageList_Destroy failed\n");
1205 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 9, 5);
1206 ok(himl
!= 0, "ImageList_Create failed\n");
1207 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 10, 5, ILC_COLOR24
, "init 9 grow 5");
1208 ret
= pImageList_Destroy(himl
);
1209 ok(ret
, "ImageList_Destroy failed\n");
1211 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 2, 4);
1212 ok(himl
!= 0, "ImageList_Create failed\n");
1213 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 3, 4, ILC_COLOR24
, "init 2 grow 4");
1214 ret
= pImageList_Destroy(himl
);
1215 ok(ret
, "ImageList_Destroy failed\n");
1217 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
, 4, 2);
1218 ok(himl
!= 0, "ImageList_Create failed\n");
1219 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 2, ILC_COLOR24
, "init 4 grow 2");
1220 ret
= pImageList_Destroy(himl
);
1221 ok(ret
, "ImageList_Destroy failed\n");
1223 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR8
, 4, 2);
1224 ok(himl
!= 0, "ImageList_Create failed\n");
1225 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 2, ILC_COLOR8
, "bpp 8");
1226 ret
= pImageList_Destroy(himl
);
1227 ok(ret
, "ImageList_Destroy failed\n");
1229 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
, 4, 2);
1230 ok(himl
!= 0, "ImageList_Create failed\n");
1231 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 2, ILC_COLOR4
, "bpp 4");
1232 ret
= pImageList_Destroy(himl
);
1233 ok(ret
, "ImageList_Destroy failed\n");
1235 himl
= pImageList_Create(BMP_CX
, BMP_CX
, 0, 4, 2);
1236 ok(himl
!= 0, "ImageList_Create failed\n");
1237 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 2, ILC_COLOR4
, "bpp default");
1238 icon
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1239 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 0, "Failed to add icon.\n");
1240 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 1, "Failed to add icon.\n");
1241 DestroyIcon( icon
);
1242 check_iml_data(himl
, BMP_CX
, BMP_CX
, 2, 5, 2, ILC_COLOR4
, "bpp default");
1243 ret
= pImageList_Destroy(himl
);
1244 ok(ret
, "ImageList_Destroy failed\n");
1246 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR24
|ILC_MASK
, 4, 2);
1247 ok(himl
!= 0, "ImageList_Create failed\n");
1248 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 2, ILC_COLOR24
|ILC_MASK
, "bpp 24 + mask");
1249 icon
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1250 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 0, "Failed to add icon.\n");
1251 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 1, "Failed to add icon.\n");
1252 DestroyIcon( icon
);
1253 check_iml_data(himl
, BMP_CX
, BMP_CX
, 2, 5, 2, ILC_COLOR24
|ILC_MASK
, "bpp 24 + mask");
1254 ret
= pImageList_Destroy(himl
);
1255 ok(ret
, "ImageList_Destroy failed\n");
1257 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
|ILC_MASK
, 4, 2);
1258 ok(himl
!= 0, "ImageList_Create failed\n");
1259 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 5, 2, ILC_COLOR4
|ILC_MASK
, "bpp 4 + mask");
1260 icon
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1261 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 0, "Failed to add icon.\n");
1262 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 1, "Failed to add icon.\n");
1263 DestroyIcon( icon
);
1264 check_iml_data(himl
, BMP_CX
, BMP_CX
, 2, 5, 2, ILC_COLOR4
|ILC_MASK
, "bpp 4 + mask");
1265 ret
= pImageList_Destroy(himl
);
1266 ok(ret
, "ImageList_Destroy failed\n");
1268 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
|ILC_MASK
, 2, 99);
1269 ok(himl
!= 0, "ImageList_Create failed\n");
1270 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 3, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99");
1271 icon
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1272 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 0, "Failed to add icon.\n");
1273 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 1, "Failed to add icon.\n");
1274 check_iml_data(himl
, BMP_CX
, BMP_CX
, 2, 3, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99 2 icons");
1275 ok( pImageList_ReplaceIcon(himl
, -1, icon
) == 2, "Failed to add icon\n");
1276 DestroyIcon( icon
);
1277 check_iml_data(himl
, BMP_CX
, BMP_CX
, 3, 104, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99 3 icons");
1278 ok( pImageList_Remove(himl
, -1) == TRUE
, "Failed to remove icon.\n");
1279 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 100, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99 empty");
1280 ok( pImageList_SetImageCount(himl
, 22) == TRUE
, "Failed to set image count.\n");
1281 check_iml_data(himl
, BMP_CX
, BMP_CX
, 22, 23, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99 set count 22");
1282 ok( pImageList_SetImageCount(himl
, 0) == TRUE
, "Failed to set image count.\n");
1283 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 1, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99 set count 0");
1284 ok( pImageList_SetImageCount(himl
, 42) == TRUE
, "Failed to set image count.\n");
1285 check_iml_data(himl
, BMP_CX
, BMP_CX
, 42, 43, 99, ILC_COLOR4
|ILC_MASK
, "init 2 grow 99 set count 42");
1286 ret
= pImageList_Destroy(himl
);
1287 ok(ret
, "ImageList_Destroy failed\n");
1289 for (grow
= 1; grow
<= 16; grow
++)
1291 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
|ILC_MASK
, 2, grow
);
1292 ok(himl
!= 0, "ImageList_Create failed\n");
1293 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 3, grow
, ILC_COLOR4
|ILC_MASK
, "grow test");
1294 ret
= pImageList_Destroy(himl
);
1295 ok(ret
, "ImageList_Destroy failed\n");
1298 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
|ILC_MASK
, 2, -20);
1299 ok(himl
!= 0, "ImageList_Create failed\n");
1300 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 3, -20, ILC_COLOR4
|ILC_MASK
, "init 2 grow -20");
1301 ret
= pImageList_Destroy(himl
);
1302 ok(ret
, "ImageList_Destroy failed\n");
1304 /* Version 6 implementation hangs on large grow values. */
1307 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
|ILC_MASK
, 2, 65536+12);
1308 ok(himl
!= 0, "ImageList_Create failed\n");
1309 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 3, 65536+12, ILC_COLOR4
|ILC_MASK
, "init 2 grow 65536+12");
1310 ret
= pImageList_Destroy(himl
);
1311 ok(ret
, "ImageList_Destroy failed\n");
1313 himl
= pImageList_Create(BMP_CX
, BMP_CX
, ILC_COLOR4
|ILC_MASK
, 2, 65535);
1314 ok(himl
!= 0, "ImageList_Create failed\n");
1315 check_iml_data(himl
, BMP_CX
, BMP_CX
, 0, 3, 65535, ILC_COLOR4
|ILC_MASK
, "init 2 grow 65535");
1316 ret
= pImageList_Destroy(himl
);
1317 ok(ret
, "ImageList_Destroy failed\n");
1321 static void test_shell_imagelist(void)
1323 HRESULT (WINAPI
*pSHGetImageList
)(INT
, REFIID
, void**);
1324 IImageList
*iml
= NULL
;
1331 /* Try to load function from shell32 */
1332 hShell32
= LoadLibraryA("shell32.dll");
1333 pSHGetImageList
= (void*)GetProcAddress(hShell32
, (LPCSTR
) 727);
1335 if (!pSHGetImageList
)
1337 win_skip("SHGetImageList not available, skipping test\n");
1338 FreeLibrary(hShell32
);
1342 /* Get system image list */
1343 hr
= pSHGetImageList(SHIL_SYSSMALL
, &IID_IImageList
, (void**)&iml
);
1344 ok(SUCCEEDED(hr
), "SHGetImageList failed, hr=%lx\n", hr
);
1347 FreeLibrary(hShell32
);
1351 IImageList_GetImageCount(iml
, &out
);
1352 ok(out
> 0, "IImageList_GetImageCount returned out <= 0\n");
1354 /* Fetch the small icon size */
1355 cx
= GetSystemMetrics(SM_CXSMICON
);
1356 cy
= GetSystemMetrics(SM_CYSMICON
);
1358 /* Check icon size matches */
1359 IImageList_GetImageRect(iml
, 0, &rect
);
1360 ok(((rect
.right
== cx
) && (rect
.bottom
== cy
)),
1361 "IImageList_GetImageRect returned r:%ld,b:%ld\n",
1362 rect
.right
, rect
.bottom
);
1364 IImageList_Release(iml
);
1365 FreeLibrary(hShell32
);
1368 static HBITMAP
create_test_bitmap(HDC hdc
, UINT width
, UINT height
, WORD bpp
, const UINT32
*bits
)
1371 UINT32
*buffer
= NULL
;
1372 UINT stride
= ((width
* bpp
+ 31) >> 3) & ~3;
1373 BITMAPINFO bitmapInfo
= { { sizeof(BITMAPINFOHEADER
), width
, - height
, 1, bpp
, BI_RGB
, 0, 0, 0, 0, 0 } };
1375 hBitmap
= CreateDIBSection(hdc
, &bitmapInfo
, DIB_RGB_COLORS
, (void**)&buffer
, NULL
, 0);
1376 ok(hBitmap
!= NULL
&& buffer
!= NULL
, "CreateDIBSection failed.\n");
1378 if(!hBitmap
|| !buffer
)
1380 DeleteObject(hBitmap
);
1384 memcpy(buffer
, bits
, stride
* height
);
1389 static BOOL
colour_match(UINT32 x
, UINT32 y
)
1391 const INT32 tolerance
= 8;
1393 const INT32 dr
= abs((INT32
)(x
& 0x000000FF) - (INT32
)(y
& 0x000000FF));
1394 const INT32 dg
= abs((INT32
)((x
& 0x0000FF00) >> 8) - (INT32
)((y
& 0x0000FF00) >> 8));
1395 const INT32 db
= abs((INT32
)((x
& 0x00FF0000) >> 16) - (INT32
)((y
& 0x00FF0000) >> 16));
1396 const INT32 da
= abs((INT32
)((x
& 0xFF000000) >> 24) - (INT32
)((y
& 0xFF000000) >> 24));
1398 return (dr
<= tolerance
&& dg
<= tolerance
&& db
<= tolerance
&& da
<= tolerance
);
1401 static void check_ImageList_DrawIndirect(IMAGELISTDRAWPARAMS
*ildp
, UINT32
*bits
,
1402 UINT32 expected
, int line
)
1404 bits
[0] = 0xFFFFFFFF;
1405 pImageList_DrawIndirect(ildp
);
1406 ok(colour_match(bits
[0], expected
),
1407 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1408 bits
[0], expected
, line
);
1412 static void check_ImageList_DrawIndirect_fStyle(HDC hdc
, HIMAGELIST himl
, UINT32
*bits
, int i
,
1413 UINT fStyle
, UINT32 expected
, int line
)
1415 IMAGELISTDRAWPARAMS ildp
= {sizeof(IMAGELISTDRAWPARAMS
), himl
, i
, hdc
,
1416 0, 0, 0, 0, 0, 0, CLR_NONE
, CLR_NONE
, fStyle
, 0, ILS_NORMAL
, 0, 0x00000000};
1417 check_ImageList_DrawIndirect(&ildp
, bits
, expected
, line
);
1420 static void check_ImageList_DrawIndirect_ILD_ROP(HDC hdc
, HIMAGELIST himl
, UINT32
*bits
, int i
,
1421 DWORD dwRop
, UINT32 expected
, int line
)
1423 IMAGELISTDRAWPARAMS ildp
= {sizeof(IMAGELISTDRAWPARAMS
), himl
, i
, hdc
,
1424 0, 0, 0, 0, 0, 0, CLR_NONE
, CLR_NONE
, ILD_IMAGE
| ILD_ROP
, dwRop
, ILS_NORMAL
, 0, 0x00000000};
1425 check_ImageList_DrawIndirect(&ildp
, bits
, expected
, line
);
1428 static void check_ImageList_DrawIndirect_fState(HDC hdc
, HIMAGELIST himl
, UINT32
*bits
, int i
, UINT fStyle
,
1429 UINT fState
, DWORD Frame
, UINT32 expected
, int line
)
1431 IMAGELISTDRAWPARAMS ildp
= {sizeof(IMAGELISTDRAWPARAMS
), himl
, i
, hdc
,
1432 0, 0, 0, 0, 0, 0, CLR_NONE
, CLR_NONE
, fStyle
, 0, fState
, Frame
, 0x00000000};
1433 check_ImageList_DrawIndirect(&ildp
, bits
, expected
, line
);
1436 static void check_ImageList_DrawIndirect_broken(HDC hdc
, HIMAGELIST himl
, UINT32
*bits
, int i
,
1437 UINT fStyle
, UINT fState
, DWORD Frame
, UINT32 expected
,
1438 UINT32 broken_expected
, int line
)
1440 IMAGELISTDRAWPARAMS ildp
= {sizeof(IMAGELISTDRAWPARAMS
), himl
, i
, hdc
,
1441 0, 0, 0, 0, 0, 0, CLR_NONE
, CLR_NONE
, fStyle
, 0, fState
, Frame
, 0x00000000};
1442 bits
[0] = 0xFFFFFFFF;
1443 pImageList_DrawIndirect(&ildp
);
1444 ok(colour_match(bits
[0], expected
) ||
1445 broken(colour_match(bits
[0], broken_expected
)),
1446 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1447 bits
[0], expected
, line
);
1450 static void check_ImageList_DrawIndirect_grayscale(HDC hdc
, HIMAGELIST himl
, UINT32
*dst_bits
, const UINT32
*bitmap_bits
,
1451 int index
, UINT width
, UINT height
, int line
)
1454 BOOL has_alpha
= FALSE
;
1455 IMAGELISTDRAWPARAMS ildp
= { sizeof(IMAGELISTDRAWPARAMS
), himl
, index
, hdc
,
1456 0, 0, 0, 0, 0, 0, CLR_NONE
, CLR_NONE
, ILD_NORMAL
, 0, ILS_SATURATE
, 0, 0x00000000 };
1457 memset(dst_bits
, 0, width
* height
* sizeof(*dst_bits
));
1458 pImageList_DrawIndirect(&ildp
);
1460 for (i
= 0; i
< width
* height
; i
++)
1461 if ((has_alpha
= ((bitmap_bits
[i
] & 0xFF000000) != 0))) break;
1463 for (i
= 0; i
< width
* height
; i
++)
1465 UINT32 expected
, expected_winxp
;
1466 UINT32 red
= (bitmap_bits
[i
] & 0x00FF0000) >> 16;
1467 UINT32 green
= (bitmap_bits
[i
] & 0x0000FF00) >> 8;
1468 UINT32 blue
= (bitmap_bits
[i
] & 0x000000FF) >> 0;
1469 UINT32 gray
= (red
* 299 + green
* 587 + blue
* 114 + 500) / 1000;
1470 UINT32 gray_winxp
= (red
+ green
+ blue
) / 3;
1473 UINT32 alpha
= (bitmap_bits
[i
] & 0xFF000000) >> 24;
1474 gray
= gray
* alpha
/ 0xff * alpha
/ 0xff;
1475 gray_winxp
= gray_winxp
* alpha
/ 0xff * 0x96 / 0xff;
1476 expected
= (alpha
<< 24) | (gray
<< 16) | (gray
<< 8) | gray
;
1477 expected_winxp
= ((alpha
* 0x96 / 0xff) << 24) | (gray_winxp
<< 16) | (gray_winxp
<< 8) | gray_winxp
;
1481 expected
= ((UINT32
)0xFF << 24) | (gray
<< 16) | (gray
<< 8) | gray
;
1482 expected_winxp
= (gray_winxp
<< 16) | (gray_winxp
<< 8) | gray_winxp
;
1485 ok(colour_match(dst_bits
[i
], expected
) || broken(colour_match(dst_bits
[i
], expected_winxp
)),
1486 "ImageList_DrawIndirect: got Pixel(%d,%d) %08X, Expected a close match to %08X from line %d\n",
1487 i
% width
, i
/ width
, dst_bits
[i
], expected
, line
);
1491 static void test_ImageList_DrawIndirect(void)
1493 const UINT32 bits_image
[] = { 0x00ABCDEF, 0x00ABCDEF };
1494 const UINT32 bits_alpha
[] = { 0x89ABCDEF, 0x89ABCDEF };
1495 const UINT32 bits_transparent
[] = { 0x00ABCDEF, 0x89ABCDEF };
1497 const UINT32 bits_4x4
[] = { 0x00ABCDEF, 0x89ABCDEF, 0xFFABCDEF, 0xFEDCBA98,
1498 0x00345678, 0x12345678, 0xFF345678, 0x87654321,
1499 0x00987654, 0xBA987654, 0xFF987654, 0x456789AB,
1500 0x00000000, 0xFF000000, 0xFFFFFFFF, 0x00FFFFFF };
1502 HIMAGELIST himl
= NULL
;
1505 HBITMAP hbmOld
= NULL
, hbmDst
= NULL
;
1506 HBITMAP hbmMask
= NULL
, hbmInverseMask
= NULL
;
1507 HBITMAP hbmImage
= NULL
, hbmAlphaImage
= NULL
, hbmTransparentImage
= NULL
, hbm4x4
= NULL
;
1508 int iImage
= -1, iAlphaImage
= -1, iTransparentImage
= -1;
1510 UINT32 maskBits
= 0x00000000, inverseMaskBits
= 0xFFFFFFFF;
1515 BITMAPINFO bitmapInfo
= {{sizeof(BITMAPINFOHEADER
), 2, 1, 1, 32, BI_RGB
,
1518 hdcDst
= CreateCompatibleDC(0);
1519 ok(hdcDst
!= 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
1523 hbmMask
= CreateBitmap(2, 1, 1, 1, &maskBits
);
1524 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1526 hbmInverseMask
= CreateBitmap(2, 1, 1, 1, &inverseMaskBits
);
1527 ok(hbmInverseMask
!= 0, "CreateBitmap failed\n");
1529 himl
= pImageList_Create(2, 1, ILC_COLOR32
, 0, 1);
1530 ok(himl
!= 0, "ImageList_Create failed\n");
1532 hr
= pHIMAGELIST_QueryInterface(himl
, &IID_IImageList
, (void **) &imgl
);
1533 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
1535 /* Add a no-alpha image */
1536 hbmImage
= create_test_bitmap(hdcDst
, 2, 1, 32, bits_image
);
1537 ok(hbmImage
!= NULL
, "Failed to create test bitmap.\n");
1539 iImage
= pImageList_Add(himl
, hbmImage
, hbmMask
);
1540 ok(iImage
!= -1, "ImageList_Add failed\n");
1542 hr
= IImageList_GetItemFlags(imgl
, 1000, &flags
);
1543 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
1545 hr
= IImageList_GetItemFlags(imgl
, 1000, NULL
);
1546 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
1548 hr
= IImageList_GetItemFlags(imgl
, iImage
, &flags
);
1549 ok(hr
== S_OK
, "Failed to get item flags, hr %#lx.\n", hr
);
1550 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
1552 /* Add an alpha image */
1553 hbmAlphaImage
= create_test_bitmap(hdcDst
, 2, 1, 32, bits_alpha
);
1554 ok(hbmAlphaImage
!= NULL
, "Failed to create test bitmap.\n");
1556 iAlphaImage
= pImageList_Add(himl
, hbmAlphaImage
, hbmMask
);
1557 ok(iAlphaImage
!= -1, "ImageList_Add failed\n");
1559 hr
= IImageList_GetItemFlags(imgl
, iAlphaImage
, &flags
);
1560 ok(hr
== S_OK
, "Failed to get item flags, hr %#lx.\n", hr
);
1561 ok(flags
& ILIF_ALPHA
, "Unexpected flags %#lx.\n", flags
);
1563 /* Add a transparent alpha image */
1564 hbmTransparentImage
= create_test_bitmap(hdcDst
, 2, 1, 32, bits_transparent
);
1565 ok(hbmTransparentImage
!= NULL
, "Failed to create test bitmap.\n");
1567 iTransparentImage
= pImageList_Add(himl
, hbmTransparentImage
, hbmMask
);
1568 ok(iTransparentImage
!= -1, "ImageList_Add failed\n");
1570 hr
= IImageList_GetItemFlags(imgl
, iTransparentImage
, &flags
);
1571 ok(hr
== S_OK
, "Failed to get item flags, hr %#lx.\n", hr
);
1572 ok(flags
& ILIF_ALPHA
, "Unexpected flags %#lx.\n", flags
);
1575 bitmapInfo
.bmiHeader
.biBitCount
= 32;
1576 hbmDst
= CreateDIBSection(hdcDst
, &bitmapInfo
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1577 ok (hbmDst
&& bits
, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1578 hbmOld
= SelectObject(hdcDst
, hbmDst
);
1580 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iImage
, ILD_NORMAL
, 0x00ABCDEF, __LINE__
);
1581 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iImage
, ILD_TRANSPARENT
, 0x00ABCDEF, __LINE__
);
1582 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iImage
, ILD_MASK
, 0x00ABCDEF, __LINE__
);
1583 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iImage
, ILD_IMAGE
, 0x00ABCDEF, __LINE__
);
1584 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iImage
, ILD_PRESERVEALPHA
, 0x00ABCDEF, __LINE__
);
1586 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iAlphaImage
, ILD_NORMAL
, 0xFFD3E5F7, __LINE__
);
1587 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iAlphaImage
, ILD_TRANSPARENT
, 0xFFD3E5F7, __LINE__
);
1589 /* broken on winxp */
1590 todo_wine
check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iAlphaImage
, ILD_BLEND25
, ILS_NORMAL
, 0, 0xFFE8F1FA, 0xFFD4D9DD, __LINE__
);
1591 todo_wine
check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iAlphaImage
, ILD_BLEND50
, ILS_NORMAL
, 0, 0xFFE8F1FA, 0xFFB4BDC4, __LINE__
);
1593 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iAlphaImage
, ILD_MASK
, 0xFFD3E5F7, __LINE__
);
1594 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iAlphaImage
, ILD_IMAGE
, 0xFFD3E5F7, __LINE__
);
1596 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iAlphaImage
, ILD_PRESERVEALPHA
, 0x895D6F81, __LINE__
);
1597 check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iAlphaImage
, ILD_PRESERVEALPHA
, ILS_ALPHA
, 127, 0xFFE9F2FB, 0xFFAEB7C0, __LINE__
);
1598 check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iAlphaImage
, ILD_PRESERVEALPHA
, ILS_SATURATE
, 0, 0xFFAFAFAF, 0xFFF0F0F0, __LINE__
);
1600 check_ImageList_DrawIndirect_fStyle(hdcDst
, himl
, bits
, iTransparentImage
, ILD_NORMAL
, 0xFFFFFFFF, __LINE__
);
1602 check_ImageList_DrawIndirect_ILD_ROP(hdcDst
, himl
, bits
, iImage
, SRCCOPY
, 0x00ABCDEF, __LINE__
);
1603 check_ImageList_DrawIndirect_ILD_ROP(hdcDst
, himl
, bits
, iImage
, SRCINVERT
, 0xFF543210, __LINE__
);
1605 /* ILD_ROP is ignored when the image has an alpha channel */
1606 check_ImageList_DrawIndirect_ILD_ROP(hdcDst
, himl
, bits
, iAlphaImage
, SRCCOPY
, 0xFFD3E5F7, __LINE__
);
1607 check_ImageList_DrawIndirect_ILD_ROP(hdcDst
, himl
, bits
, iAlphaImage
, SRCINVERT
, 0xFFD3E5F7, __LINE__
);
1609 check_ImageList_DrawIndirect_grayscale(hdcDst
, himl
, bits
, bits_image
, iImage
, 2, 1, __LINE__
);
1610 check_ImageList_DrawIndirect_grayscale(hdcDst
, himl
, bits
, bits_alpha
, iAlphaImage
, 2, 1, __LINE__
);
1611 check_ImageList_DrawIndirect_grayscale(hdcDst
, himl
, bits
, bits_transparent
, iTransparentImage
, 2, 1, __LINE__
);
1613 check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iImage
, ILD_NORMAL
, ILS_GLOW
, 0, 0x00ABCDEF, 0xFFABCDEF, __LINE__
);
1614 check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iImage
, ILD_NORMAL
, ILS_SHADOW
, 0, 0x00ABCDEF, 0xFFABCDEF, __LINE__
);
1616 check_ImageList_DrawIndirect_fState(hdcDst
, himl
, bits
, iImage
, ILD_NORMAL
, ILS_ALPHA
, 127, 0xFFD5E6F7, __LINE__
);
1617 check_ImageList_DrawIndirect_broken(hdcDst
, himl
, bits
, iAlphaImage
, ILD_NORMAL
, ILS_ALPHA
, 127, 0xFFE9F2FB, 0xFFAEB7C0, __LINE__
);
1618 check_ImageList_DrawIndirect_fState(hdcDst
, himl
, bits
, iAlphaImage
, ILD_NORMAL
, ILS_NORMAL
, 127, 0xFFD3E5F7, __LINE__
);
1620 /* 4x4 bitmap tests */
1621 SelectObject(hdcDst
, hbmOld
);
1622 DeleteObject(hbmDst
);
1623 bitmapInfo
.bmiHeader
.biWidth
= 4;
1624 bitmapInfo
.bmiHeader
.biHeight
= -4;
1625 hbmDst
= CreateDIBSection(hdcDst
, &bitmapInfo
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1626 ok (hbmDst
&& bits
, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1627 SelectObject(hdcDst
, hbmDst
);
1629 hbm4x4
= create_test_bitmap(hdcDst
, 4, 4, 32, bits_4x4
);
1630 ok(hbm4x4
!= NULL
, "Failed to create a test bitmap.\n");
1632 ret
= pImageList_SetIconSize(himl
, 4, 4);
1633 ok(ret
, "ImageList_SetIconSize failed\n");
1635 ret
= pImageList_Add(himl
, hbm4x4
, NULL
);
1636 ok(ret
!= -1, "ImageList_Add failed\n");
1638 check_ImageList_DrawIndirect_grayscale(hdcDst
, himl
, bits
, bits_4x4
, 0, 4, 4, __LINE__
);
1641 SelectObject(hdcDst
, hbmOld
);
1643 DeleteObject(hbmDst
);
1648 DeleteObject(hbmMask
);
1650 DeleteObject(hbmInverseMask
);
1653 DeleteObject(hbmImage
);
1655 DeleteObject(hbmAlphaImage
);
1656 if(hbmTransparentImage
)
1657 DeleteObject(hbmTransparentImage
);
1659 DeleteObject(hbm4x4
);
1663 ret
= pImageList_Destroy(himl
);
1664 ok(ret
, "ImageList_Destroy failed\n");
1668 static void test_iimagelist(void)
1670 IImageList
*imgl
, *imgl2
;
1671 IImageList2
*imagelist
;
1678 if (!pHIMAGELIST_QueryInterface
)
1680 win_skip("XP imagelist functions not available\n");
1684 /* test reference counting on destruction */
1685 imgl
= (IImageList
*)createImageList(32, 32);
1686 ret
= IImageList_AddRef(imgl
);
1687 ok(ret
== 2, "Expected 2, got %ld\n", ret
);
1688 ret
= pImageList_Destroy((HIMAGELIST
)imgl
);
1689 ok(ret
== TRUE
, "Expected TRUE, got %ld\n", ret
);
1690 ret
= pImageList_Destroy((HIMAGELIST
)imgl
);
1691 ok(ret
== TRUE
, "Expected TRUE, got %ld\n", ret
);
1692 ret
= pImageList_Destroy((HIMAGELIST
)imgl
);
1693 ok(ret
== FALSE
, "Expected FALSE, got %ld\n", ret
);
1695 imgl
= (IImageList
*)createImageList(32, 32);
1696 ret
= IImageList_AddRef(imgl
);
1697 ok(ret
== 2, "Expected 2, got %ld\n", ret
);
1698 ret
= pImageList_Destroy((HIMAGELIST
)imgl
);
1699 ok(ret
== TRUE
, "Expected TRUE, got %ld\n", ret
);
1700 ret
= IImageList_Release(imgl
);
1701 ok(ret
== 0, "Expected 0, got %ld\n", ret
);
1702 ret
= pImageList_Destroy((HIMAGELIST
)imgl
);
1703 ok(ret
== FALSE
, "Expected FALSE, got %ld\n", ret
);
1705 /* ref counting, HIMAGELIST_QueryInterface adds a reference */
1706 imgl
= (IImageList
*)createImageList(32, 32);
1707 hr
= pHIMAGELIST_QueryInterface((HIMAGELIST
)imgl
, &IID_IImageList
, (void**)&imgl2
);
1708 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
1709 ok(imgl2
== imgl
, "got different pointer\n");
1710 ret
= IImageList_Release(imgl
);
1711 ok(ret
== 1, "got %lu\n", ret
);
1712 IImageList_Release(imgl
);
1714 if (!pImageList_CoCreateInstance
)
1716 win_skip("Vista imagelist functions not available\n");
1720 hr
= pImageList_CoCreateInstance(&CLSID_ImageList
, NULL
, &IID_IImageList
, (void **) &imgl
);
1721 ok(SUCCEEDED(hr
), "ImageList_CoCreateInstance failed, hr=%lx\n", hr
);
1724 IImageList_Release(imgl
);
1726 himl
= createImageList(32, 32);
1731 hr
= pHIMAGELIST_QueryInterface(himl
, &IID_IImageList
, (void **) &imgl
);
1732 ok(SUCCEEDED(hr
), "HIMAGELIST_QueryInterface failed, hr=%lx\n", hr
);
1735 IImageList_Release(imgl
);
1737 pImageList_Destroy(himl
);
1740 hr
= pImageList_CoCreateInstance(&CLSID_ImageList
, NULL
, &IID_IImageList2
, (void**)&imagelist
);
1743 win_skip("IImageList2 is not supported.\n");
1747 hr
= IImageList2_Initialize(imagelist
, BMP_CX
, BMP_CX
, ILC_COLOR24
, 1, 1);
1748 ok(hr
== S_OK
, "got %#lx\n", hr
);
1750 check_iml_data((HIMAGELIST
)imagelist
, BMP_CX
, BMP_CX
, 0, 2, 1, ILC_COLOR24
, "IImageList2 0");
1752 hr
= IImageList2_Remove(imagelist
, 0);
1753 ok(hr
== E_INVALIDARG
, "got %#lx\n", hr
);
1754 hr
= IImageList2_Remove(imagelist
, -1);
1755 ok(hr
== S_OK
, "got %#lx\n", hr
);
1757 hbm
= CreateBitmap(BMP_CX
, BMP_CX
, 1, 1, NULL
);
1760 hr
= IImageList2_Add(imagelist
, hbm
, 0, &ret2
);
1761 ok(hr
== S_OK
, "got %#lx\n", hr
);
1762 ok(ret2
== 0, "got %d\n", ret2
);
1764 check_iml_data((HIMAGELIST
)imagelist
, BMP_CX
, BMP_CX
, 1, 2, 4, ILC_COLOR24
, "IImageList2 1");
1767 hr
= IImageList2_Add(imagelist
, hbm
, 0, &ret2
);
1768 ok(hr
== S_OK
, "got %#lx\n", hr
);
1769 ok(ret2
== 1, "got %d\n", ret2
);
1771 check_iml_data((HIMAGELIST
)imagelist
, BMP_CX
, BMP_CX
, 2, 7, 4, ILC_COLOR24
, "IImageList2 2");
1773 hr
= IImageList2_Remove(imagelist
, 0);
1774 ok(hr
== S_OK
, "got %#lx\n", hr
);
1776 check_iml_data((HIMAGELIST
)imagelist
, BMP_CX
, BMP_CX
, 1, 7, 4, ILC_COLOR24
, "IImageList2 1");
1778 hr
= IImageList2_Remove(imagelist
, -1);
1779 ok(hr
== S_OK
, "got %#lx\n", hr
);
1781 check_iml_data((HIMAGELIST
)imagelist
, BMP_CX
, BMP_CX
, 0, 4, 1, ILC_COLOR24
, "IImageList2 0");
1783 hr
= IImageList2_Remove(imagelist
, 0);
1784 ok(hr
== E_INVALIDARG
, "got %#lx\n", hr
);
1788 IImageList2_Release(imagelist
);
1791 static void test_IImageList_Add_Remove(void)
1803 /* create an imagelist to play with */
1804 himl
= pImageList_Create(84, 84, ILC_COLOR16
, 0, 3);
1805 ok(himl
!= 0,"failed to create imagelist\n");
1807 imgl
= (IImageList
*) himl
;
1809 /* load the icons to add to the image list */
1810 hicon1
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1811 ok(hicon1
!= 0, "no hicon1\n");
1812 hicon2
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1813 ok(hicon2
!= 0, "no hicon2\n");
1814 hicon3
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1815 ok(hicon3
!= 0, "no hicon3\n");
1817 /* remove when nothing exists */
1818 hr
= IImageList_Remove(imgl
, 0);
1819 ok(hr
== E_INVALIDARG
, "got 0x%08lx\n", hr
);
1821 /* removing everything from an empty imagelist should succeed */
1822 hr
= IImageList_Remove(imgl
, -1);
1823 ok(hr
== S_OK
, "removed nonexistent icon\n");
1827 ok( IImageList_ReplaceIcon(imgl
, -1, hicon1
, &ret
) == S_OK
&& (ret
== 0),"failed to add icon1\n");
1829 ok( IImageList_ReplaceIcon(imgl
, -1, hicon2
, &ret
) == S_OK
&& (ret
== 1),"failed to add icon2\n");
1831 ok( IImageList_ReplaceIcon(imgl
, -1, hicon3
, &ret
) == S_OK
&& (ret
== 2),"failed to add icon3\n");
1833 /* remove an index out of range */
1834 ok( IImageList_Remove(imgl
, 4711) == E_INVALIDARG
, "got 0x%08lx\n", hr
);
1837 ok( IImageList_Remove(imgl
,0) == S_OK
, "can't remove 0\n");
1838 ok( IImageList_Remove(imgl
,0) == S_OK
, "can't remove 0\n");
1839 ok( IImageList_Remove(imgl
,0) == S_OK
, "can't remove 0\n");
1841 /* remove one extra */
1842 ok( IImageList_Remove(imgl
, 0) == E_INVALIDARG
, "got 0x%08lx\n", hr
);
1844 IImageList_Release(imgl
);
1845 ok(DestroyIcon(hicon1
),"icon 1 wasn't deleted\n");
1846 ok(DestroyIcon(hicon2
),"icon 2 wasn't deleted\n");
1847 ok(DestroyIcon(hicon3
),"icon 3 wasn't deleted\n");
1850 static void test_IImageList_Get_SetImageCount(void)
1857 /* create an imagelist to play with */
1858 himl
= pImageList_Create(84, 84, ILC_COLOR16
, 0, 3);
1859 ok(himl
!= 0,"failed to create imagelist\n");
1861 imgl
= (IImageList
*) himl
;
1863 /* check SetImageCount/GetImageCount */
1864 hr
= IImageList_SetImageCount(imgl
, 3);
1865 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
1867 hr
= IImageList_GetImageCount(imgl
, &ret
);
1868 ok(hr
== S_OK
&& ret
== 3, "invalid image count after increase\n");
1869 hr
= IImageList_SetImageCount(imgl
, 1);
1870 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
1872 hr
= IImageList_GetImageCount(imgl
, &ret
);
1873 ok(hr
== S_OK
&& ret
== 1, "invalid image count after decrease to 1\n");
1874 hr
= IImageList_SetImageCount(imgl
, 0);
1875 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
1877 hr
= IImageList_GetImageCount(imgl
, &ret
);
1878 ok(hr
== S_OK
&& ret
== 0, "invalid image count after decrease to 0\n");
1880 IImageList_Release(imgl
);
1883 static void test_IImageList_Draw(void)
1892 IMAGELISTDRAWPARAMS imldp
;
1898 hwndfortest
= create_window();
1899 hdc
= GetDC(hwndfortest
);
1900 ok(hdc
!=NULL
, "couldn't get DC\n");
1902 /* create an imagelist to play with */
1903 himl
= pImageList_Create(48, 48, ILC_COLOR16
, 0, 3);
1904 ok(himl
!=0,"failed to create imagelist\n");
1906 imgl
= (IImageList
*) himl
;
1908 /* load the icons to add to the image list */
1909 hbm1
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
1910 ok(hbm1
!= 0, "no bitmap 1\n");
1911 hbm2
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
1912 ok(hbm2
!= 0, "no bitmap 2\n");
1913 hbm3
= CreateBitmap(48, 48, 1, 1, bitmap_bits
);
1914 ok(hbm3
!= 0, "no bitmap 3\n");
1918 ok( IImageList_Add(imgl
, hbm1
, 0, &ret
) == S_OK
&& (ret
== 0), "failed to add bitmap 1\n");
1920 ok( IImageList_Add(imgl
, hbm2
, 0, &ret
) == S_OK
&& (ret
== 1), "failed to add bitmap 2\n");
1922 ok( IImageList_SetImageCount(imgl
, 3) == S_OK
, "Setimage count failed\n");
1923 ok( IImageList_Replace(imgl
, 2, hbm3
, 0) == S_OK
, "failed to replace bitmap 3\n");
1927 /* crashes on native */
1928 IImageList_Draw(imgl
, NULL
);
1931 memset(&imldp
, 0, sizeof (imldp
));
1932 hr
= IImageList_Draw(imgl
, &imldp
);
1933 ok( hr
== E_INVALIDARG
, "got 0x%08lx\n", hr
);
1935 imldp
.cbSize
= IMAGELISTDRAWPARAMS_V3_SIZE
;
1939 force_redraw(hwndfortest
);
1941 imldp
.fStyle
= SRCCOPY
;
1942 imldp
.rgbBk
= CLR_DEFAULT
;
1943 imldp
.rgbFg
= CLR_DEFAULT
;
1946 ok( IImageList_Draw(imgl
, &imldp
) == S_OK
, "should succeed\n");
1948 ok( IImageList_Draw(imgl
, &imldp
) == S_OK
, "should succeed\n");
1950 ok( IImageList_Draw(imgl
, &imldp
) == S_OK
, "should succeed\n");
1952 ok( IImageList_Draw(imgl
, &imldp
) == E_INVALIDARG
, "should fail\n");
1955 ok( IImageList_Remove(imgl
, 0) == S_OK
, "removing 1st bitmap\n");
1956 ok( IImageList_Remove(imgl
, 0) == S_OK
, "removing 2nd bitmap\n");
1957 ok( IImageList_Remove(imgl
, 0) == S_OK
, "removing 3rd bitmap\n");
1960 IImageList_Release(imgl
);
1962 /* bitmaps should not be deleted by the imagelist */
1963 ok(DeleteObject(hbm1
),"bitmap 1 can't be deleted\n");
1964 ok(DeleteObject(hbm2
),"bitmap 2 can't be deleted\n");
1965 ok(DeleteObject(hbm3
),"bitmap 3 can't be deleted\n");
1967 ReleaseDC(hwndfortest
, hdc
);
1968 DestroyWindow(hwndfortest
);
1971 static void test_IImageList_Merge(void)
1973 HIMAGELIST himl1
, himl2
;
1974 IImageList
*imgl1
, *imgl2
, *merge
;
1976 HWND hwnd
= create_window();
1980 himl1
= pImageList_Create(32,32,0,0,3);
1981 ok(himl1
!= NULL
,"failed to create himl1\n");
1983 himl2
= pImageList_Create(32,32,0,0,3);
1984 ok(himl2
!= NULL
,"failed to create himl2\n");
1986 hicon1
= CreateIcon(hinst
, 32, 32, 1, 1, icon_bits
, icon_bits
);
1987 ok(hicon1
!= NULL
, "failed to create hicon1\n");
1989 if (!himl1
|| !himl2
|| !hicon1
)
1992 /* cast to IImageList */
1993 imgl1
= (IImageList
*) himl1
;
1994 imgl2
= (IImageList
*) himl2
;
1997 ok( IImageList_ReplaceIcon(imgl2
, -1, hicon1
, &ret
) == S_OK
&& (ret
== 0),"add icon1 to himl2 failed\n");
2001 /* null cases that crash on native */
2002 IImageList_Merge(imgl1
, -1, NULL
, 0, 0, 0, &IID_IImageList
, (void**)&merge
);
2003 IImageList_Merge(imgl1
, -1, (IUnknown
*) imgl2
, 0, 0, 0, &IID_IImageList
, NULL
);
2006 /* If himl1 has no images, merge still succeeds */
2007 hr
= IImageList_Merge(imgl1
, -1, (IUnknown
*) imgl2
, 0, 0, 0, &IID_IImageList
, (void **) &merge
);
2008 ok(hr
== S_OK
, "merge himl1,-1 failed\n");
2009 if (hr
== S_OK
) IImageList_Release(merge
);
2011 hr
= IImageList_Merge(imgl1
, 0, (IUnknown
*) imgl2
, 0, 0, 0, &IID_IImageList
, (void **) &merge
);
2012 ok(hr
== S_OK
, "merge himl1,0 failed\n");
2013 if (hr
== S_OK
) IImageList_Release(merge
);
2015 /* Same happens if himl2 is empty */
2016 IImageList_Release(imgl2
);
2017 himl2
= pImageList_Create(32,32,0,0,3);
2018 ok(himl2
!= NULL
,"failed to recreate himl2\n");
2020 imgl2
= (IImageList
*) himl2
;
2022 hr
= IImageList_Merge(imgl1
, -1, (IUnknown
*) imgl2
, -1, 0, 0, &IID_IImageList
, (void **) &merge
);
2023 ok(hr
== S_OK
, "merge himl2,-1 failed\n");
2024 if (hr
== S_OK
) IImageList_Release(merge
);
2026 hr
= IImageList_Merge(imgl1
, -1, (IUnknown
*) imgl2
, 0, 0, 0, &IID_IImageList
, (void **) &merge
);
2027 ok(hr
== S_OK
, "merge himl2,0 failed\n");
2028 if (hr
== S_OK
) IImageList_Release(merge
);
2030 /* Now try merging an image with itself */
2032 ok( IImageList_ReplaceIcon(imgl2
, -1, hicon1
, &ret
) == S_OK
&& (ret
== 0),"re-add icon1 to himl2 failed\n");
2034 hr
= IImageList_Merge(imgl2
, 0, (IUnknown
*) imgl2
, 0, 0, 0, &IID_IImageList
, (void **) &merge
);
2035 ok(hr
== S_OK
, "merge himl2 with itself failed\n");
2036 if (hr
== S_OK
) IImageList_Release(merge
);
2038 /* Try merging 2 different image lists */
2040 ok( IImageList_ReplaceIcon(imgl1
, -1, hicon1
, &ret
) == S_OK
&& (ret
== 0),"add icon1 to himl1 failed\n");
2042 hr
= IImageList_Merge(imgl1
, 0, (IUnknown
*) imgl2
, 0, 0, 0, &IID_IImageList
, (void **) &merge
);
2043 ok(hr
== S_OK
, "merge himl1 with himl2 failed\n");
2044 if (hr
== S_OK
) IImageList_Release(merge
);
2046 hr
= IImageList_Merge(imgl1
, 0, (IUnknown
*) imgl2
, 0, 8, 16, &IID_IImageList
, (void **) &merge
);
2047 ok(hr
== S_OK
, "merge himl1 with himl2 8,16 failed\n");
2048 if (hr
== S_OK
) IImageList_Release(merge
);
2050 IImageList_Release(imgl1
);
2051 IImageList_Release(imgl2
);
2053 DestroyIcon(hicon1
);
2054 DestroyWindow(hwnd
);
2057 static void test_iconsize(void)
2063 himl
= pImageList_Create(16, 16, ILC_COLOR16
, 0, 3);
2064 /* null pointers, not zero imagelist dimensions */
2065 ret
= pImageList_GetIconSize(himl
, NULL
, NULL
);
2066 ok(!ret
, "got %d\n", ret
);
2068 /* doesn't touch return pointers */
2070 ret
= pImageList_GetIconSize(himl
, &cx
, NULL
);
2071 ok(!ret
, "got %d\n", ret
);
2072 ok(cx
== 0x1abe11ed, "got %d\n", cx
);
2075 ret
= pImageList_GetIconSize(himl
, NULL
, &cy
);
2076 ok(!ret
, "got %d\n", ret
);
2077 ok(cy
== 0x1abe11ed, "got %d\n", cy
);
2079 pImageList_Destroy(himl
);
2081 ret
= pImageList_GetIconSize((HIMAGELIST
)0xdeadbeef, &cx
, &cy
);
2082 ok(!ret
, "got %d\n", ret
);
2085 static void test_create_destroy(void)
2092 /* list with zero or negative image dimensions */
2093 himl
= pImageList_Create(0, 0, ILC_COLOR16
, 0, 3);
2094 ok(himl
== NULL
, "got %p\n", himl
);
2096 himl
= pImageList_Create(0, 16, ILC_COLOR16
, 0, 3);
2097 ok(himl
== NULL
, "got %p\n", himl
);
2099 himl
= pImageList_Create(16, 0, ILC_COLOR16
, 0, 3);
2100 ok(himl
== NULL
, "got %p\n", himl
);
2102 himl
= pImageList_Create(16, -1, ILC_COLOR16
, 0, 3);
2103 ok(himl
== NULL
, "got %p\n", himl
);
2105 himl
= pImageList_Create(-1, 16, ILC_COLOR16
, 0, 3);
2106 ok(himl
== NULL
, "got %p\n", himl
);
2108 rc
= pImageList_Destroy((HIMAGELIST
)0xdeadbeef);
2109 ok(rc
== FALSE
, "ImageList_Destroy(0xdeadbeef) should fail and not crash\n");
2111 /* DDB image lists */
2112 himl
= pImageList_Create(0, 14, ILC_COLORDDB
, 4, 4);
2113 ok(himl
!= NULL
, "got %p\n", himl
);
2115 pImageList_GetIconSize(himl
, &cx
, &cy
);
2116 ok (cx
== 0, "Wrong cx (%i)\n", cx
);
2117 ok (cy
== 14, "Wrong cy (%i)\n", cy
);
2118 pImageList_Destroy(himl
);
2120 himl
= pImageList_Create(0, 0, ILC_COLORDDB
, 4, 4);
2121 ok(himl
!= NULL
, "got %p\n", himl
);
2122 pImageList_GetIconSize(himl
, &cx
, &cy
);
2123 ok (cx
== 0, "Wrong cx (%i)\n", cx
);
2124 ok (cy
== 0, "Wrong cy (%i)\n", cy
);
2125 pImageList_Destroy(himl
);
2127 himl
= pImageList_Create(0, 0, ILC_COLORDDB
, 0, 4);
2128 ok(himl
!= NULL
, "got %p\n", himl
);
2129 pImageList_GetIconSize(himl
, &cx
, &cy
);
2130 ok (cx
== 0, "Wrong cx (%i)\n", cx
);
2131 ok (cy
== 0, "Wrong cy (%i)\n", cy
);
2133 pImageList_SetImageCount(himl
, 3);
2134 ret
= pImageList_GetImageCount(himl
);
2135 ok(ret
== 3, "Unexpected image count after increase\n");
2137 /* Trying to actually add an image causes a crash on Windows */
2138 pImageList_Destroy(himl
);
2140 /* Negative values fail */
2141 himl
= pImageList_Create(-1, -1, ILC_COLORDDB
, 4, 4);
2142 ok(himl
== NULL
, "got %p\n", himl
);
2143 himl
= pImageList_Create(-1, 1, ILC_COLORDDB
, 4, 4);
2144 ok(himl
== NULL
, "got %p\n", himl
);
2145 himl
= pImageList_Create(1, -1, ILC_COLORDDB
, 4, 4);
2146 ok(himl
== NULL
, "got %p\n", himl
);
2149 static void check_color_table(const char *name
, HDC hdc
, HIMAGELIST himl
, UINT ilc
,
2150 RGBQUAD
*expect
, RGBQUAD
*broken_expect
)
2154 char bmi_buffer
[FIELD_OFFSET( BITMAPINFO
, bmiColors
[256] )];
2155 BITMAPINFO
*bmi
= (BITMAPINFO
*)bmi_buffer
;
2156 int i
, depth
= ilc
& 0xfe;
2158 ret
= pImageList_GetImageInfo(himl
, 0, &info
);
2159 ok(ret
, "got %d\n", ret
);
2160 ok(info
.hbmImage
!= NULL
, "got %p\n", info
.hbmImage
);
2162 memset(bmi_buffer
, 0, sizeof(bmi_buffer
));
2163 bmi
->bmiHeader
.biSize
= sizeof(bmi
->bmiHeader
);
2164 ret
= GetDIBits(hdc
, info
.hbmImage
, 0, 0, NULL
, bmi
, DIB_RGB_COLORS
);
2165 ok(ret
, "got %d\n", ret
);
2166 ok(bmi
->bmiHeader
.biBitCount
== depth
, "got %d\n", bmi
->bmiHeader
.biBitCount
);
2168 ret
= GetDIBits(hdc
, info
.hbmImage
, 0, 0, NULL
, bmi
, DIB_RGB_COLORS
);
2169 ok(ret
, "got %d\n", ret
);
2170 ok(bmi
->bmiHeader
.biBitCount
== depth
, "got %d\n", bmi
->bmiHeader
.biBitCount
);
2172 for (i
= 0; i
< (1 << depth
); i
++)
2173 ok((bmi
->bmiColors
[i
].rgbRed
== expect
[i
].rgbRed
&&
2174 bmi
->bmiColors
[i
].rgbGreen
== expect
[i
].rgbGreen
&&
2175 bmi
->bmiColors
[i
].rgbBlue
== expect
[i
].rgbBlue
) ||
2176 (broken_expect
&& broken(bmi
->bmiColors
[i
].rgbRed
== broken_expect
[i
].rgbRed
&&
2177 bmi
->bmiColors
[i
].rgbGreen
== broken_expect
[i
].rgbGreen
&&
2178 bmi
->bmiColors
[i
].rgbBlue
== broken_expect
[i
].rgbBlue
)),
2179 "%d: %s: got color[%d] %02x %02x %02x expect %02x %02x %02x\n", depth
, name
, i
,
2180 bmi
->bmiColors
[i
].rgbRed
, bmi
->bmiColors
[i
].rgbGreen
, bmi
->bmiColors
[i
].rgbBlue
,
2181 expect
[i
].rgbRed
, expect
[i
].rgbGreen
, expect
[i
].rgbBlue
);
2184 static void get_default_color_table(HDC hdc
, int bpp
, RGBQUAD
*table
)
2186 char bmi_buffer
[FIELD_OFFSET( BITMAPINFO
, bmiColors
[256] )];
2187 BITMAPINFO
*bmi
= (BITMAPINFO
*)bmi_buffer
;
2191 PALETTEENTRY entries
[256];
2196 tmp
= CreateBitmap( 1, 1, 1, 1, NULL
);
2197 memset(bmi_buffer
, 0, sizeof(bmi_buffer
));
2198 bmi
->bmiHeader
.biSize
= sizeof(bmi
->bmiHeader
);
2199 bmi
->bmiHeader
.biHeight
= 1;
2200 bmi
->bmiHeader
.biWidth
= 1;
2201 bmi
->bmiHeader
.biBitCount
= bpp
;
2202 bmi
->bmiHeader
.biPlanes
= 1;
2203 bmi
->bmiHeader
.biCompression
= BI_RGB
;
2204 GetDIBits( hdc
, tmp
, 0, 0, NULL
, bmi
, DIB_RGB_COLORS
);
2206 memcpy(table
, bmi
->bmiColors
, (1 << bpp
) * sizeof(RGBQUAD
));
2207 table
[7] = bmi
->bmiColors
[8];
2208 table
[8] = bmi
->bmiColors
[7];
2209 DeleteObject( tmp
);
2213 pal
= CreateHalftonePalette(hdc
);
2214 GetPaletteEntries(pal
, 0, 256, entries
);
2215 for (i
= 0; i
< 256; i
++)
2217 table
[i
].rgbRed
= entries
[i
].peRed
;
2218 table
[i
].rgbGreen
= entries
[i
].peGreen
;
2219 table
[i
].rgbBlue
= entries
[i
].peBlue
;
2220 table
[i
].rgbReserved
= 0;
2226 ok(0, "unhandled depth %d\n", bpp
);
2230 static void test_color_table(UINT ilc
)
2234 char bmi_buffer
[FIELD_OFFSET( BITMAPINFO
, bmiColors
[256] )];
2235 BITMAPINFO
*bmi
= (BITMAPINFO
*)bmi_buffer
;
2236 HDC hdc
= CreateCompatibleDC(0);
2237 HBITMAP dib4
, dib8
, dib32
;
2238 RGBQUAD rgb
[256], default_table
[256];
2240 get_default_color_table(hdc
, ilc
& 0xfe, default_table
);
2242 himl
= pImageList_Create(16, 16, ilc
, 0, 3);
2243 ok(himl
!= NULL
, "got %p\n", himl
);
2245 memset(bmi_buffer
, 0, sizeof(bmi_buffer
));
2246 bmi
->bmiHeader
.biSize
= sizeof(bmi
->bmiHeader
);
2247 bmi
->bmiHeader
.biHeight
= 16;
2248 bmi
->bmiHeader
.biWidth
= 16;
2249 bmi
->bmiHeader
.biBitCount
= 8;
2250 bmi
->bmiHeader
.biPlanes
= 1;
2251 bmi
->bmiHeader
.biCompression
= BI_RGB
;
2252 bmi
->bmiColors
[0].rgbRed
= 0xff;
2253 bmi
->bmiColors
[1].rgbGreen
= 0xff;
2254 bmi
->bmiColors
[2].rgbBlue
= 0xff;
2256 dib8
= CreateDIBSection(hdc
, bmi
, DIB_RGB_COLORS
, NULL
, NULL
, 0);
2258 bmi
->bmiHeader
.biBitCount
= 4;
2259 bmi
->bmiColors
[0].rgbRed
= 0xff;
2260 bmi
->bmiColors
[0].rgbGreen
= 0x00;
2261 bmi
->bmiColors
[0].rgbBlue
= 0xff;
2262 bmi
->bmiColors
[1].rgbRed
= 0xff;
2263 bmi
->bmiColors
[1].rgbGreen
= 0xff;
2264 bmi
->bmiColors
[1].rgbBlue
= 0x00;
2265 bmi
->bmiColors
[2].rgbRed
= 0x00;
2266 bmi
->bmiColors
[2].rgbGreen
= 0xff;
2267 bmi
->bmiColors
[2].rgbBlue
= 0xff;
2269 dib4
= CreateDIBSection(hdc
, bmi
, DIB_RGB_COLORS
, NULL
, NULL
, 0);
2271 bmi
->bmiHeader
.biBitCount
= 32;
2273 dib32
= CreateDIBSection(hdc
, bmi
, DIB_RGB_COLORS
, NULL
, NULL
, 0);
2275 /* add 32 first then 8. This won't set the color table */
2276 ret
= pImageList_Add(himl
, dib32
, NULL
);
2277 ok(ret
== 0, "got %d\n", ret
);
2278 ret
= pImageList_Add(himl
, dib8
, NULL
);
2279 ok(ret
== 1, "got %d\n", ret
);
2281 check_color_table("add 32, 8", hdc
, himl
, ilc
, default_table
, NULL
);
2283 /* since the previous _Adds didn't set the color table, this one will */
2284 ret
= pImageList_Remove(himl
, -1);
2285 ok(ret
, "got %d\n", ret
);
2286 ret
= pImageList_Add(himl
, dib8
, NULL
);
2287 ok(ret
== 0, "got %d\n", ret
);
2289 memset(rgb
, 0, sizeof(rgb
));
2290 rgb
[0].rgbRed
= 0xff;
2291 rgb
[1].rgbGreen
= 0xff;
2292 rgb
[2].rgbBlue
= 0xff;
2293 check_color_table("remove all, add 8", hdc
, himl
, ilc
, rgb
, default_table
);
2295 /* remove all, add 4. Color table remains the same since it's implicitly
2296 been set by the previous _Add */
2297 ret
= pImageList_Remove(himl
, -1);
2298 ok(ret
, "got %d\n", ret
);
2299 ret
= pImageList_Add(himl
, dib4
, NULL
);
2300 ok(ret
== 0, "got %d\n", ret
);
2301 check_color_table("remove all, add 4", hdc
, himl
, ilc
, rgb
, default_table
);
2303 pImageList_Destroy(himl
);
2304 himl
= pImageList_Create(16, 16, ilc
, 0, 3);
2305 ok(himl
!= NULL
, "got %p\n", himl
);
2308 ret
= pImageList_Add(himl
, dib4
, NULL
);
2309 ok(ret
== 0, "got %d\n", ret
);
2311 memset(rgb
, 0, 16 * sizeof(rgb
[0]));
2312 rgb
[0].rgbRed
= 0xff;
2313 rgb
[0].rgbBlue
= 0xff;
2314 rgb
[1].rgbRed
= 0xff;
2315 rgb
[1].rgbGreen
= 0xff;
2316 rgb
[2].rgbGreen
= 0xff;
2317 rgb
[2].rgbBlue
= 0xff;
2318 memcpy(rgb
+ 16, default_table
+ 16, 240 * sizeof(rgb
[0]));
2320 check_color_table("add 4", hdc
, himl
, ilc
, rgb
, default_table
);
2322 pImageList_Destroy(himl
);
2323 himl
= pImageList_Create(16, 16, ilc
, 0, 3);
2324 ok(himl
!= NULL
, "got %p\n", himl
);
2326 /* set color table, add 8 */
2327 ret
= pImageList_Remove(himl
, -1);
2328 ok(ret
, "got %d\n", ret
);
2329 memset(rgb
, 0, sizeof(rgb
));
2330 rgb
[0].rgbRed
= 0xcc;
2331 rgb
[1].rgbBlue
= 0xcc;
2332 ret
= pImageList_SetColorTable(himl
, 0, 2, rgb
);
2333 ok(ret
== 2, "got %d\n", ret
);
2334 /* the table is set, so this doesn't change it */
2335 ret
= pImageList_Add(himl
, dib8
, NULL
);
2336 ok(ret
== 0, "got %d\n", ret
);
2338 memcpy(rgb
+ 2, default_table
+ 2, 254 * sizeof(rgb
[0]));
2339 check_color_table("SetColorTable", hdc
, himl
, ilc
, rgb
, NULL
);
2341 DeleteObject(dib32
);
2345 pImageList_Destroy(himl
);
2348 static void test_copy(void)
2350 HIMAGELIST dst
, src
;
2354 dst
= pImageList_Create(5, 11, ILC_COLOR
, 1, 1);
2355 count
= pImageList_GetImageCount(dst
);
2356 ok(!count
, "ImageList not empty.\n");
2357 src
= createImageList(7, 13);
2358 count
= pImageList_GetImageCount(src
);
2359 ok(count
> 2, "Tests need an ImageList with more than 2 images\n");
2361 /* ImageList_Copy() cannot copy between two ImageLists */
2362 ret
= pImageList_Copy(dst
, 0, src
, 2, ILCF_MOVE
);
2363 ok(!ret
, "ImageList_Copy() should have returned FALSE\n");
2364 count
= pImageList_GetImageCount(dst
);
2365 ok(count
== 0, "Expected no image in dst ImageList, got %d\n", count
);
2367 pImageList_Destroy(dst
);
2368 pImageList_Destroy(src
);
2371 static void test_loadimage(void)
2376 list
= pImageList_LoadImageW( hinst
, MAKEINTRESOURCEW(IDB_BITMAP_128x15
), 16, 1, CLR_DEFAULT
,
2377 IMAGE_BITMAP
, LR_CREATEDIBSECTION
);
2378 ok( list
!= NULL
, "got %p\n", list
);
2379 flags
= pImageList_GetFlags( list
);
2380 ok( flags
== (ILC_COLOR4
| ILC_MASK
), "got %08lx\n", flags
);
2381 pImageList_Destroy( list
);
2383 list
= pImageList_LoadImageW( hinst
, MAKEINTRESOURCEW(IDB_BITMAP_128x15
), 16, 1, CLR_NONE
,
2384 IMAGE_BITMAP
, LR_CREATEDIBSECTION
);
2385 ok( list
!= NULL
, "got %p\n", list
);
2386 flags
= pImageList_GetFlags( list
);
2387 ok( flags
== ILC_COLOR4
, "got %08lx\n", flags
);
2388 pImageList_Destroy( list
);
2391 #define GetAValue(argb) ((BYTE) ((argb) >> 24))
2393 static void get_image_bits(HIMAGELIST himl
, int index
, int width
, int height
, UINT32
*bits
)
2397 BITMAPINFO bitmap_info
= {{sizeof(BITMAPINFOHEADER
), width
, height
, 1, 32, BI_RGB
, 0, 0, 0, 0, 0}};
2399 HDC hdc_dst
= CreateCompatibleDC(0);
2400 hbm_dst
= CreateDIBSection(hdc_dst
, &bitmap_info
, DIB_RGB_COLORS
, &bitmap_bits
, NULL
, 0);
2401 SelectObject(hdc_dst
, hbm_dst
);
2403 pImageList_Draw(himl
, index
, hdc_dst
, 0, 0, ILD_TRANSPARENT
);
2404 memcpy(bits
, bitmap_bits
, (size_t)(width
* height
* 32 / 8));
2406 DeleteObject(hbm_dst
);
2410 static void test_alpha(void)
2412 /* each line is a 2*1 bitmap */
2413 const static UINT32 test_bitmaps
[] =
2415 0x00654321, 0x00ABCDEF,
2416 0x00654321, 0x00654321,
2417 0x00ABCDEF, 0x00654321,
2418 0x00ABCDEF, 0x00ABCDEF,
2419 0x00654321, 0x01ABCDEF,
2420 0x01654321, 0x00ABCDEF,
2421 0x00654321, 0xFFABCDEF,
2422 0x00654321, 0x89ABCDEF,
2423 0xFF654321, 0x00ABCDEF,
2424 0xFF654321, 0xFFABCDEF,
2425 0xFF654321, 0x89ABCDEF,
2426 0x87654321, 0x00ABCDEF,
2427 0x87654321, 0xFFABCDEF,
2428 0x87654321, 0x89ABCDEF
2430 const static BYTE mask_bits
= 0xAA;
2434 HBITMAP hbm_test
, hbm_mask
;
2438 hdc
= CreateCompatibleDC(0);
2439 himl
= pImageList_Create(2, 1, ILC_COLOR32
| ILC_MASK
, 0, 15);
2441 for (i
= 0; i
< ARRAY_SIZE(test_bitmaps
); i
+= 2)
2443 hbm_test
= create_test_bitmap(hdc
, 2, 1, 32, test_bitmaps
+ i
);
2444 ret
= pImageList_AddMasked(himl
, hbm_test
, RGB(0x65,0x43,0x21));
2445 ok(ret
== i
/ 2, "ImageList_AddMasked returned %d, expected %d\n", ret
, i
/ 2);
2446 DeleteObject(hbm_test
);
2448 get_image_bits(himl
, i
/ 2, 2, 1, bits
);
2449 ok(GetAValue(bits
[0]) == GetAValue(test_bitmaps
[i
]) && GetAValue(bits
[1]) == GetAValue(test_bitmaps
[i
+ 1]),
2450 "Bitmap [%08X, %08X] returned alpha value [%02X, %02X], expected [%02X, %02X]\n",
2451 test_bitmaps
[i
], test_bitmaps
[i
+ 1], GetAValue(bits
[0]), GetAValue(bits
[1]),
2452 GetAValue(test_bitmaps
[i
]), GetAValue(test_bitmaps
[i
+ 1]));
2454 /* If all alpha values are zero, the image is considered to have no alpha and gets masked */
2455 if (!GetAValue(bits
[0]) && !GetAValue(bits
[1]))
2456 ok(bits
[0] == (test_bitmaps
[i
] == 0x654321 ? 0 : test_bitmaps
[i
]) &&
2457 bits
[1] == (test_bitmaps
[i
+ 1] == 0x654321 ? 0 : test_bitmaps
[i
+ 1]),
2458 "Bitmap [%08X, %08X] returned [%08X, %08X], expected [%08X, %08X]\n",
2459 test_bitmaps
[i
], test_bitmaps
[i
+ 1], bits
[0], bits
[1],
2460 test_bitmaps
[i
] == 0x654321 ? 0 : test_bitmaps
[i
],
2461 test_bitmaps
[i
+ 1] == 0x654321 ? 0 : test_bitmaps
[i
+ 1]);
2464 pImageList_Destroy(himl
);
2465 hbm_mask
= CreateBitmap(2, 1, 1, 1, &mask_bits
);
2466 himl
= pImageList_Create(2, 1, ILC_COLOR32
| ILC_MASK
, 0, 15);
2468 for (i
= 0; i
< ARRAY_SIZE(test_bitmaps
); i
+= 2)
2470 hbm_test
= create_test_bitmap(hdc
, 2, 1, 32, test_bitmaps
+ i
);
2471 ret
= pImageList_Add(himl
, hbm_test
, hbm_mask
);
2472 ok(ret
== i
/ 2, "ImageList_Add returned %d, expected %d\n", ret
, i
/ 2);
2473 DeleteObject(hbm_test
);
2475 get_image_bits(himl
, i
/ 2, 2, 1, bits
);
2476 ok(GetAValue(bits
[0]) == GetAValue(test_bitmaps
[i
]) && GetAValue(bits
[1]) == GetAValue(test_bitmaps
[i
+ 1]),
2477 "Bitmap [%08X, %08X] returned alpha value [%02X, %02X], expected [%02X, %02X]\n",
2478 test_bitmaps
[i
], test_bitmaps
[i
+ 1], GetAValue(bits
[0]), GetAValue(bits
[1]),
2479 GetAValue(test_bitmaps
[i
]), GetAValue(test_bitmaps
[i
+ 1]));
2481 /* If all alpha values are zero, the image is considered to have no alpha and gets masked */
2482 if (!GetAValue(bits
[0]) && !GetAValue(bits
[1]))
2483 ok(!bits
[0] && bits
[1] == test_bitmaps
[i
+ 1],
2484 "Bitmap [%08X, %08X] returned [%08X, %08X], expected [%08X, %08X]\n",
2485 test_bitmaps
[i
], test_bitmaps
[i
+ 1], bits
[0], bits
[1], 0, test_bitmaps
[i
+ 1]);
2488 if (GetAValue(bits
[0]) >= 0x80)
2489 ok(bits
[0] & 0x00FFFFFF, "Bitmap [%08X, %08X] has alpha and masked first pixel [%08X]\n",
2490 test_bitmaps
[i
], test_bitmaps
[i
+ 1], bits
[0]);
2494 pImageList_Destroy(himl
);
2495 DeleteObject(hbm_mask
);
2499 static void test_IImageList_Clone(void)
2501 IImageList
*imgl
, *imgl2
;
2506 himl
= pImageList_Create(16, 16, ILC_COLOR16
, 0, 3);
2507 imgl
= (IImageList
*)himl
;
2511 /* crashes on native */
2512 IImageList_Clone(imgl
, &IID_IImageList
, NULL
);
2515 hr
= IImageList_Clone(imgl
, &IID_IImageList
, (void**)&imgl2
);
2516 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
2517 ref
= IImageList_Release(imgl2
);
2518 ok(ref
== 0, "got %lu\n", ref
);
2520 IImageList_Release(imgl
);
2523 static void test_IImageList_GetBkColor(void)
2530 himl
= pImageList_Create(16, 16, ILC_COLOR16
, 0, 3);
2531 imgl
= (IImageList
*)himl
;
2535 /* crashes on native */
2536 IImageList_GetBkColor(imgl
, NULL
);
2539 hr
= IImageList_GetBkColor(imgl
, &color
);
2540 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
2542 IImageList_Release(imgl
);
2545 static void test_IImageList_SetBkColor(void)
2552 himl
= pImageList_Create(16, 16, ILC_COLOR16
, 0, 3);
2553 imgl
= (IImageList
*)himl
;
2557 /* crashes on native */
2558 IImageList_SetBkColor(imgl
, RGB(0, 0, 0), NULL
);
2561 hr
= IImageList_SetBkColor(imgl
, CLR_NONE
, &color
);
2562 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
2564 hr
= IImageList_SetBkColor(imgl
, CLR_NONE
, &color
);
2565 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
2568 hr
= IImageList_GetBkColor(imgl
, &color
);
2569 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
2570 ok(color
== CLR_NONE
, "got %lx\n", color
);
2572 IImageList_Release(imgl
);
2575 static void test_IImageList_GetImageCount(void)
2582 himl
= pImageList_Create(16, 16, ILC_COLOR16
, 0, 3);
2583 imgl
= (IImageList
*)himl
;
2587 /* crashes on native */
2588 IImageList_GetImageCount(imgl
, NULL
);
2592 hr
= IImageList_GetImageCount(imgl
, &count
);
2593 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
2594 ok(count
== 0, "got %d\n", count
);
2596 IImageList_Release(imgl
);
2599 static void test_IImageList_GetIconSize(void)
2606 himl
= pImageList_Create(16, 16, ILC_COLOR16
, 0, 3);
2607 imgl
= (IImageList
*)himl
;
2609 hr
= IImageList_GetIconSize(imgl
, NULL
, NULL
);
2610 ok(hr
== E_INVALIDARG
, "got 0x%08lx\n", hr
);
2612 hr
= IImageList_GetIconSize(imgl
, &cx
, NULL
);
2613 ok(hr
== E_INVALIDARG
, "got 0x%08lx\n", hr
);
2615 hr
= IImageList_GetIconSize(imgl
, NULL
, &cy
);
2616 ok(hr
== E_INVALIDARG
, "got 0x%08lx\n", hr
);
2618 IImageList_Release(imgl
);
2621 static void test_ImageList_WriteEx(void)
2627 himl
= pImageList_Create(24, 24, ILC_COLOR24
, 1, 1);
2628 ok(himl
!= 0, "Failed to create an imagelist.\n");
2630 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
2631 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2633 hr
= pImageList_WriteEx(himl
, ILP_NORMAL
, stream
);
2634 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2636 hr
= pImageList_WriteEx(himl
, ILP_DOWNLEVEL
, stream
);
2637 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2639 IStream_Release(stream
);
2640 pImageList_Destroy(himl
);
2643 static void init_functions(void)
2645 HMODULE hComCtl32
= LoadLibraryA("comctl32.dll");
2647 #define X(f) p##f = (void*)GetProcAddress(hComCtl32, #f);
2648 #define X2(f, ord) p##f = (void*)GetProcAddress(hComCtl32, (const char *)ord);
2649 X(ImageList_Create
);
2650 X(ImageList_Destroy
);
2652 X(ImageList_AddMasked
);
2653 X(ImageList_DrawIndirect
);
2654 X(ImageList_SetImageCount
);
2655 X2(ImageList_SetColorTable
, 390);
2656 X(ImageList_GetFlags
);
2657 X(ImageList_BeginDrag
);
2658 X(ImageList_GetDragImage
);
2659 X(ImageList_EndDrag
);
2660 X(ImageList_GetImageCount
);
2661 X(ImageList_SetDragCursorImage
);
2662 X(ImageList_GetIconSize
);
2663 X(ImageList_SetIconSize
);
2664 X(ImageList_Remove
);
2665 X(ImageList_ReplaceIcon
);
2666 X(ImageList_Replace
);
2668 X(ImageList_GetImageInfo
);
2670 X(ImageList_WriteEx
);
2673 X(ImageList_LoadImageW
);
2674 X(ImageList_CoCreateInstance
);
2675 X(HIMAGELIST_QueryInterface
);
2681 START_TEST(imagelist
)
2683 ULONG_PTR ctx_cookie
;
2688 hinst
= GetModuleHandleA(NULL
);
2690 test_create_destroy();
2695 test_DrawIndirect();
2697 test_merge_colors();
2698 test_imagelist_storage();
2700 test_color_table(ILC_COLOR4
);
2701 test_color_table(ILC_COLOR8
);
2705 /* Now perform v6 tests */
2706 if (!load_v6_module(&ctx_cookie
, &hCtx
))
2711 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
2716 test_DrawIndirect();
2718 test_imagelist_storage();
2720 test_color_table(ILC_COLOR4
);
2721 test_color_table(ILC_COLOR8
);
2726 test_ImageList_DrawIndirect();
2727 test_shell_imagelist();
2730 test_IImageList_Add_Remove();
2731 test_IImageList_Get_SetImageCount();
2732 test_IImageList_Draw();
2733 test_IImageList_Merge();
2734 test_IImageList_Clone();
2735 test_IImageList_GetBkColor();
2736 test_IImageList_SetBkColor();
2737 test_IImageList_GetImageCount();
2738 test_IImageList_GetIconSize();
2739 test_ImageList_WriteEx();
2743 unload_v6_module(ctx_cookie
, hCtx
);