2 * Unit test suite for imagelist control.
4 * Copyright 2004 Michael Stefaniuc
5 * Copyright 2002 Mike McCormack for CodeWeavers
6 * Copyright 2007 Dmitry Timoshkov
7 * Copyright 2009 Owen Rudge for CodeWeavers
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
36 #include "commctrl.h" /* must be included after objbase.h to get ImageList_Write */
38 #include "commoncontrols.h"
41 #include "wine/test.h"
47 #define WAIT Sleep (1000)
48 #define REDRAW(hwnd) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW)
54 #define IMAGELIST_MAGIC (('L' << 8) | 'I')
57 /* Header used by ImageList_Read() and ImageList_Write() */
58 typedef struct _ILHEAD
73 static HIMAGELIST (WINAPI *pImageList_Create)(int, int, UINT, int, int);
74 static int (WINAPI *pImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
75 static BOOL (WINAPI *pImageList_DrawIndirect)(IMAGELISTDRAWPARAMS*);
76 static BOOL (WINAPI *pImageList_SetImageCount)(HIMAGELIST,UINT);
79 static HINSTANCE hinst;
81 /* These macros build cursor/bitmap data in 4x4 pixel blocks */
82 #define B(x,y) ((x?0xf0:0)|(y?0xf:0))
83 #define ROW1(a,b,c,d,e,f,g,h) B(a,b),B(c,d),B(e,f),B(g,h)
84 #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), \
85 ROW1(a,b,c,d,e,f,g,h), ROW1(a,b,c,d,e,f,g,h)
86 #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)
87 #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), \
88 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), \
89 ROW2(a,b,c,d,e,f,g,h,i,j,k,l)
91 static const BYTE empty_bits[48*48/8];
93 static const BYTE icon_bits[32*32/8] =
95 ROW32(0,0,0,0,0,0,0,0),
96 ROW32(0,0,1,1,1,1,0,0),
97 ROW32(0,1,1,1,1,1,1,0),
98 ROW32(0,1,1,0,0,1,1,0),
99 ROW32(0,1,1,0,0,1,1,0),
100 ROW32(0,1,1,1,1,1,1,0),
101 ROW32(0,0,1,1,1,1,0,0),
102 ROW32(0,0,0,0,0,0,0,0)
105 static const BYTE bitmap_bits[48*48/8] =
107 ROW48(0,0,0,0,0,0,0,0,0,0,0,0),
108 ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
109 ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
110 ROW48(0,1,0,0,0,0,0,0,1,0,1,0),
111 ROW48(0,1,0,0,0,0,0,1,0,0,1,0),
112 ROW48(0,1,0,0,0,0,1,0,0,0,1,0),
113 ROW48(0,1,0,0,0,1,0,0,0,0,1,0),
114 ROW48(0,1,0,0,1,0,0,0,0,0,1,0),
115 ROW48(0,1,0,1,0,0,0,0,0,0,1,0),
116 ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
117 ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
118 ROW48(0,0,0,0,0,0,0,0,0,0,0,0)
121 static HIMAGELIST createImageList(int cx, int cy)
123 /* Create an ImageList and put an image into it */
124 HIMAGELIST himl = ImageList_Create(cx, cy, ILC_COLOR, 1, 1);
125 HBITMAP hbm = CreateBitmap(48, 48, 1, 1, bitmap_bits);
126 ImageList_Add(himl, hbm, NULL);
130 static HWND create_a_window(void)
132 char className[] = "bmwnd";
133 char winName[] = "Test Bitmap";
135 static int registered = 0;
141 cls.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
142 cls.lpfnWndProc = DefWindowProcA;
146 cls.hIcon = LoadIconA (0, IDI_APPLICATION);
147 cls.hCursor = LoadCursorA (0, IDC_ARROW);
148 cls.hbrBackground = GetStockObject (WHITE_BRUSH);
149 cls.lpszMenuName = 0;
150 cls.lpszClassName = className;
152 RegisterClassA (&cls);
157 hWnd = CreateWindowA (className, winName,
158 WS_OVERLAPPEDWINDOW ,
159 CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
163 ShowWindow (hWnd, SW_SHOW);
171 static HDC show_image(HWND hwnd, HIMAGELIST himl, int idx, int size,
172 LPCSTR loc, BOOL clear)
176 if (!himl) return NULL;
178 SetWindowText(hwnd, loc);
180 ImageList_Draw(himl, idx, hdc, 0, 0, ILD_TRANSPARENT);
187 BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
188 ReleaseDC(hwnd, hdc);
195 /* Useful for checking differences */
197 static void dump_bits(const BYTE *p, const BYTE *q, int size)
203 for (i = 0; i < size * 2; i++)
206 for (j = 0; j < size; j++)
207 printf("%c%c", p[j] & 0xf0 ? 'X' : ' ', p[j] & 0xf ? 'X' : ' ');
209 for (j = 0; j < size; j++)
210 printf("%c%c", q[j] & 0xf0 ? 'X' : ' ', q[j] & 0xf ? 'X' : ' ');
219 static void check_bits(HWND hwnd, HIMAGELIST himl, int idx, int size,
220 const BYTE *checkbits, LPCSTR loc)
223 BYTE bits[100*100/8];
230 memset(bits, 0, sizeof(bits));
231 hdc = show_image(hwnd, himl, idx, size, loc, FALSE);
233 c = GetPixel(hdc, 0, 0);
235 for (y = 0; y < size; y ++)
237 for (x = 0; x < size; x++)
240 if (GetPixel(hdc, x, y) != c) bits[i] |= (0x80 >> (x & 0x7));
244 BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
245 ReleaseDC(hwnd, hdc);
247 ok (memcmp(bits, checkbits, (size * size)/8) == 0,
248 "%s: bits different\n", loc);
249 if (memcmp(bits, checkbits, (size * size)/8))
250 dump_bits(bits, checkbits, size);
254 static void testHotspot (void)
265 #define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
266 static const struct hotspot hotspots[HOTSPOTS_MAX] = {
273 HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
274 HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
275 HWND hwnd = create_a_window();
278 for (i = 0; i < HOTSPOTS_MAX; i++) {
279 for (j = 0; j < HOTSPOTS_MAX; j++) {
280 int dx1 = hotspots[i].dx;
281 int dy1 = hotspots[i].dy;
282 int dx2 = hotspots[j].dx;
283 int dy2 = hotspots[j].dy;
284 int correctx, correcty, newx, newy;
289 ret = ImageList_BeginDrag(himl1, 0, dx1, dy1);
290 ok(ret != 0, "BeginDrag failed for { %d, %d }\n", dx1, dy1);
291 sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
292 show_image(hwnd, himl1, 0, max(SIZEX1, SIZEY1), loc, TRUE);
294 /* check merging the dragged image with a second image */
295 ret = ImageList_SetDragCursorImage(himl2, 0, dx2, dy2);
296 ok(ret != 0, "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
298 sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
299 show_image(hwnd, himl2, 0, max(SIZEX2, SIZEY2), loc, TRUE);
301 /* check new hotspot, it should be the same like the old one */
302 himlNew = ImageList_GetDragImage(NULL, &ppt);
303 ok(ppt.x == dx1 && ppt.y == dy1,
304 "Expected drag hotspot [%d,%d] got [%d,%d]\n",
305 dx1, dy1, ppt.x, ppt.y);
306 /* check size of new dragged image */
307 ImageList_GetIconSize(himlNew, &newx, &newy);
308 correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
309 correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
310 ok(newx == correctx && newy == correcty,
311 "Expected drag image size [%d,%d] got [%d,%d]\n",
312 correctx, correcty, newx, newy);
313 sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
314 show_image(hwnd, himlNew, 0, max(correctx, correcty), loc, TRUE);
323 ImageList_Destroy(himl2);
324 ImageList_Destroy(himl1);
328 static BOOL DoTest1(void)
336 /* create an imagelist to play with */
337 himl = ImageList_Create(84,84,0x10,0,3);
338 ok(himl!=0,"failed to create imagelist\n");
340 /* load the icons to add to the image list */
341 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
342 ok(hicon1 != 0, "no hicon1\n");
343 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
344 ok(hicon2 != 0, "no hicon2\n");
345 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
346 ok(hicon3 != 0, "no hicon3\n");
348 /* remove when nothing exists */
349 ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
350 /* removing everything from an empty imagelist should succeed */
351 ok(ImageList_RemoveAll(himl),"removed nonexistent icon\n");
354 ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
355 ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
356 ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
358 /* remove an index out of range */
359 ok(!ImageList_Remove(himl,4711),"removed nonexistent icon\n");
362 ok(ImageList_Remove(himl,0),"can't remove 0\n");
363 ok(ImageList_Remove(himl,0),"can't remove 0\n");
364 ok(ImageList_Remove(himl,0),"can't remove 0\n");
366 /* remove one extra */
367 ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
369 /* check SetImageCount/GetImageCount */
370 if (pImageList_SetImageCount)
372 ok(pImageList_SetImageCount(himl, 3), "couldn't increase image count\n");
373 ok(ImageList_GetImageCount(himl) == 3, "invalid image count after increase\n");
374 ok(pImageList_SetImageCount(himl, 1), "couldn't decrease image count\n");
375 ok(ImageList_GetImageCount(himl) == 1, "invalid image count after decrease to 1\n");
376 ok(pImageList_SetImageCount(himl, 0), "couldn't decrease image count\n");
377 ok(ImageList_GetImageCount(himl) == 0, "invalid image count after decrease to 0\n");
381 skip("skipped ImageList_SetImageCount tests\n");
385 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
387 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
388 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
389 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
394 static BOOL DoTest2(void)
402 /* create an imagelist to play with */
403 himl = ImageList_Create(84,84,0x10,0,3);
404 ok(himl!=0,"failed to create imagelist\n");
406 /* load the icons to add to the image list */
407 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
408 ok(hicon1 != 0, "no hicon1\n");
409 hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
410 ok(hicon2 != 0, "no hicon2\n");
411 hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
412 ok(hicon3 != 0, "no hicon3\n");
415 ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
416 ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
417 ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
420 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
422 ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
423 ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
424 ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
429 static BOOL DoTest3(void)
437 IMAGELISTDRAWPARAMS imldp;
441 if (!pImageList_DrawIndirect)
443 win_skip("ImageList_DrawIndirect not available, skipping test\n");
447 hwndfortest = create_a_window();
448 hdc = GetDC(hwndfortest);
449 ok(hdc!=NULL, "couldn't get DC\n");
451 /* create an imagelist to play with */
452 himl = ImageList_Create(48,48,0x10,0,3);
453 ok(himl!=0,"failed to create imagelist\n");
455 /* load the icons to add to the image list */
456 hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
457 ok(hbm1 != 0, "no bitmap 1\n");
458 hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
459 ok(hbm2 != 0, "no bitmap 2\n");
460 hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
461 ok(hbm3 != 0, "no bitmap 3\n");
464 ok(0==ImageList_Add(himl, hbm1, 0),"failed to add bitmap 1\n");
465 ok(1==ImageList_Add(himl, hbm2, 0),"failed to add bitmap 2\n");
467 if (pImageList_SetImageCount)
469 ok(pImageList_SetImageCount(himl,3),"Setimage count failed\n");
470 /*ok(2==ImageList_Add(himl, hbm3, NULL),"failed to add bitmap 3\n"); */
471 ok(ImageList_Replace(himl, 2, hbm3, 0),"failed to replace bitmap 3\n");
474 memset(&imldp, 0, sizeof (imldp));
475 ok(!pImageList_DrawIndirect(&imldp), "zero data succeeded!\n");
476 imldp.cbSize = sizeof (imldp);
477 ok(!pImageList_DrawIndirect(&imldp), "zero hdc succeeded!\n");
479 ok(!pImageList_DrawIndirect(&imldp),"zero himl succeeded!\n");
481 if (!pImageList_DrawIndirect(&imldp))
483 /* Earlier versions of native comctl32 use a smaller structure */
484 imldp.cbSize -= 3 * sizeof(DWORD);
485 ok(pImageList_DrawIndirect(&imldp),"DrawIndirect should succeed\n");
490 imldp.fStyle = SRCCOPY;
491 imldp.rgbBk = CLR_DEFAULT;
492 imldp.rgbFg = CLR_DEFAULT;
495 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
497 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
499 ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
501 ok(!pImageList_DrawIndirect(&imldp),"should fail\n");
504 ok(ImageList_Remove(himl, 0), "removing 1st bitmap\n");
505 ok(ImageList_Remove(himl, 0), "removing 2nd bitmap\n");
506 ok(ImageList_Remove(himl, 0), "removing 3rd bitmap\n");
509 ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
511 /* bitmaps should not be deleted by the imagelist */
512 ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
513 ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
514 ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
516 ReleaseDC(hwndfortest, hdc);
517 DestroyWindow(hwndfortest);
522 static void testMerge(void)
524 HIMAGELIST himl1, himl2, hmerge;
526 HWND hwnd = create_a_window();
528 himl1 = ImageList_Create(32,32,0,0,3);
529 ok(himl1 != NULL,"failed to create himl1\n");
531 himl2 = ImageList_Create(32,32,0,0,3);
532 ok(himl2 != NULL,"failed to create himl2\n");
534 hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
535 ok(hicon1 != NULL, "failed to create hicon1\n");
537 if (!himl1 || !himl2 || !hicon1)
540 ok(0==ImageList_AddIcon(himl2, hicon1),"add icon1 to himl2 failed\n");
541 check_bits(hwnd, himl2, 0, 32, icon_bits, "add icon1 to himl2");
543 /* If himl1 has no images, merge still succeeds */
544 hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
545 ok(hmerge != NULL, "merge himl1,-1 failed\n");
546 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,-1");
547 if (hmerge) ImageList_Destroy(hmerge);
549 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
550 ok(hmerge != NULL,"merge himl1,0 failed\n");
551 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,0");
552 if (hmerge) ImageList_Destroy(hmerge);
554 /* Same happens if himl2 is empty */
555 ImageList_Destroy(himl2);
556 himl2 = ImageList_Create(32,32,0,0,3);
557 ok(himl2 != NULL,"failed to recreate himl2\n");
561 hmerge = ImageList_Merge(himl1, -1, himl2, -1, 0, 0);
562 ok(hmerge != NULL, "merge himl2,-1 failed\n");
563 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,-1");
564 if (hmerge) ImageList_Destroy(hmerge);
566 hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
567 ok(hmerge != NULL, "merge himl2,0 failed\n");
568 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,0");
569 if (hmerge) ImageList_Destroy(hmerge);
571 /* Now try merging an image with itself */
572 ok(0==ImageList_AddIcon(himl2, hicon1),"re-add icon1 to himl2 failed\n");
574 hmerge = ImageList_Merge(himl2, 0, himl2, 0, 0, 0);
575 ok(hmerge != NULL, "merge himl2 with itself failed\n");
576 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2 with itself");
577 if (hmerge) ImageList_Destroy(hmerge);
579 /* Try merging 2 different image lists */
580 ok(0==ImageList_AddIcon(himl1, hicon1),"add icon1 to himl1 failed\n");
582 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
583 ok(hmerge != NULL, "merge himl1 with himl2 failed\n");
584 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2");
585 if (hmerge) ImageList_Destroy(hmerge);
587 hmerge = ImageList_Merge(himl1, 0, himl2, 0, 8, 16);
588 ok(hmerge != NULL, "merge himl1 with himl2 8,16 failed\n");
589 check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2, 8,16");
590 if (hmerge) ImageList_Destroy(hmerge);
592 ImageList_Destroy(himl1);
593 ImageList_Destroy(himl2);
598 /*********************** imagelist storage test ***************************/
605 char *iml_data; /* written imagelist data */
609 static HRESULT STDMETHODCALLTYPE Test_Stream_QueryInterface(
618 static ULONG STDMETHODCALLTYPE Test_Stream_AddRef(
625 static ULONG STDMETHODCALLTYPE Test_Stream_Release(
632 static HRESULT STDMETHODCALLTYPE Test_Stream_Read(
642 static BOOL allocate_storage(struct my_IStream *my_is, ULONG add)
644 my_is->iml_data_size += add;
646 if (!my_is->iml_data)
647 my_is->iml_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, my_is->iml_data_size);
649 my_is->iml_data = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, my_is->iml_data, my_is->iml_data_size);
651 return my_is->iml_data ? TRUE : FALSE;
654 static HRESULT STDMETHODCALLTYPE Test_Stream_Write(
660 struct my_IStream *my_is = (struct my_IStream *)This;
661 ULONG current_iml_data_size = my_is->iml_data_size;
663 if (!allocate_storage(my_is, cb)) return E_FAIL;
665 memcpy(my_is->iml_data + current_iml_data_size, pv, cb);
666 if (pcbWritten) *pcbWritten = cb;
671 static HRESULT STDMETHODCALLTYPE Test_Stream_Seek(
673 LARGE_INTEGER dlibMove,
675 ULARGE_INTEGER* plibNewPosition)
681 static HRESULT STDMETHODCALLTYPE Test_Stream_SetSize(
683 ULARGE_INTEGER libNewSize)
689 static HRESULT STDMETHODCALLTYPE Test_Stream_CopyTo(
693 ULARGE_INTEGER* pcbRead,
694 ULARGE_INTEGER* pcbWritten)
700 static HRESULT STDMETHODCALLTYPE Test_Stream_Commit(
702 DWORD grfCommitFlags)
708 static HRESULT STDMETHODCALLTYPE Test_Stream_Revert(
715 static HRESULT STDMETHODCALLTYPE Test_Stream_LockRegion(
717 ULARGE_INTEGER libOffset,
725 static HRESULT STDMETHODCALLTYPE Test_Stream_UnlockRegion(
727 ULARGE_INTEGER libOffset,
735 static HRESULT STDMETHODCALLTYPE Test_Stream_Stat(
744 static HRESULT STDMETHODCALLTYPE Test_Stream_Clone(
752 static const IStreamVtbl Test_Stream_Vtbl =
754 Test_Stream_QueryInterface,
764 Test_Stream_LockRegion,
765 Test_Stream_UnlockRegion,
770 static struct my_IStream Test_Stream = { { &Test_Stream_Vtbl }, 0, 0 };
772 static INT DIB_GetWidthBytes( int width, int bpp )
778 case 1: words = (width + 31) / 32; break;
779 case 4: words = (width + 7) / 8; break;
780 case 8: words = (width + 3) / 4; break;
782 case 16: words = (width + 1) / 2; break;
783 case 24: words = (width * 3 + 3)/4; break;
784 case 32: words = width; break;
788 trace("Unknown depth %d, please report.\n", bpp );
795 static void check_bitmap_data(const char *bm_data, ULONG bm_data_size,
796 INT width, INT height, INT bpp,
799 const BITMAPFILEHEADER *bmfh = (const BITMAPFILEHEADER *)bm_data;
800 const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)(bm_data + sizeof(*bmfh));
801 ULONG hdr_size, image_size;
803 hdr_size = sizeof(*bmfh) + sizeof(*bmih);
804 if (bmih->biBitCount <= 8) hdr_size += (1 << bpp) * sizeof(RGBQUAD);
806 ok(bmfh->bfType == (('M' << 8) | 'B'), "wrong bfType 0x%02x\n", bmfh->bfType);
807 ok(bmfh->bfSize == hdr_size, "wrong bfSize 0x%02x\n", bmfh->bfSize);
808 ok(bmfh->bfReserved1 == 0, "wrong bfReserved1 0x%02x\n", bmfh->bfReserved1);
809 ok(bmfh->bfReserved2 == 0, "wrong bfReserved2 0x%02x\n", bmfh->bfReserved2);
810 ok(bmfh->bfOffBits == hdr_size, "wrong bfOffBits 0x%02x\n", bmfh->bfOffBits);
812 ok(bmih->biSize == sizeof(*bmih), "wrong biSize %d\n", bmih->biSize);
813 ok(bmih->biWidth == width, "wrong biWidth %d (expected %d)\n", bmih->biWidth, width);
814 ok(bmih->biHeight == height, "wrong biHeight %d (expected %d)\n", bmih->biHeight, height);
815 ok(bmih->biPlanes == 1, "wrong biPlanes %d\n", bmih->biPlanes);
816 ok(bmih->biBitCount == bpp, "wrong biBitCount %d\n", bmih->biBitCount);
818 image_size = DIB_GetWidthBytes(bmih->biWidth, bmih->biBitCount) * bmih->biHeight;
819 ok(bmih->biSizeImage == image_size, "wrong biSizeImage %u\n", bmih->biSizeImage);
824 sprintf(fname, "bmp_%s.bmp", comment);
825 f = fopen(fname, "wb");
826 fwrite(bm_data, 1, bm_data_size, f);
832 static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max)
834 ILHEAD *ilh = (ILHEAD *)ilh_data;
836 ok(ilh->usMagic == IMAGELIST_MAGIC, "wrong usMagic %4x (expected %02x)\n", ilh->usMagic, IMAGELIST_MAGIC);
837 ok(ilh->usVersion == 0x101, "wrong usVersion %x (expected 0x101)\n", ilh->usVersion);
838 ok(ilh->cCurImage == cur, "wrong cCurImage %d (expected %d)\n", ilh->cCurImage, cur);
839 ok(ilh->cMaxImage == max, "wrong cMaxImage %d (expected %d)\n", ilh->cMaxImage, max);
840 ok(ilh->cGrow == 4, "wrong cGrow %d (expected 4)\n", ilh->cGrow);
841 ok(ilh->cx == cx, "wrong cx %d (expected %d)\n", ilh->cx, cx);
842 ok(ilh->cy == cy, "wrong cy %d (expected %d)\n", ilh->cy, cy);
843 ok(ilh->bkcolor == CLR_NONE, "wrong bkcolor %x\n", ilh->bkcolor);
844 ok(ilh->flags == ILC_COLOR24, "wrong flags %04x\n", ilh->flags);
845 ok(ilh->ovls[0] == -1 ||
846 ilh->ovls[0] == 0, /* win95 */
847 "wrong ovls[0] %04x\n", ilh->ovls[0]);
848 ok(ilh->ovls[1] == -1 ||
849 ilh->ovls[1] == 0, /* win95 */
850 "wrong ovls[1] %04x\n", ilh->ovls[1]);
851 ok(ilh->ovls[2] == -1 ||
852 ilh->ovls[2] == 0, /* win95 */
853 "wrong ovls[2] %04x\n", ilh->ovls[2]);
854 ok(ilh->ovls[3] == -1 ||
855 ilh->ovls[3] == 0, /* win95 */
856 "wrong ovls[3] %04x\n", ilh->ovls[3]);
859 static HBITMAP create_bitmap(INT cx, INT cy, COLORREF color, const char *comment)
862 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
863 BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
864 HBITMAP hbmp, hbmp_old;
866 RECT rc = { 0, 0, cx, cy };
868 hdc = CreateCompatibleDC(0);
870 memset(bmi, 0, sizeof(*bmi));
871 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
872 bmi->bmiHeader.biHeight = cx;
873 bmi->bmiHeader.biWidth = cy;
874 bmi->bmiHeader.biBitCount = 24;
875 bmi->bmiHeader.biPlanes = 1;
876 bmi->bmiHeader.biCompression = BI_RGB;
877 hbmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
879 hbmp_old = SelectObject(hdc, hbmp);
881 hbrush = CreateSolidBrush(color);
882 FillRect(hdc, &rc, hbrush);
883 DeleteObject(hbrush);
885 DrawText(hdc, comment, -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
887 SelectObject(hdc, hbmp_old);
893 static void image_list_init(HIMAGELIST himl)
899 #define add_bitmap(grey) \
900 sprintf(comment, "%d", n++); \
901 hbm = create_bitmap(BMP_CX, BMP_CX, RGB((grey),(grey),(grey)), comment); \
902 ImageList_Add(himl, hbm, NULL);
904 add_bitmap(255); add_bitmap(170); add_bitmap(85); add_bitmap(0);
905 add_bitmap(0); add_bitmap(85); add_bitmap(170); add_bitmap(255);
906 add_bitmap(255); add_bitmap(170); add_bitmap(85); add_bitmap(0);
907 add_bitmap(0); add_bitmap(85); add_bitmap(170); add_bitmap(255);
908 add_bitmap(255); add_bitmap(170); add_bitmap(85); add_bitmap(0);
909 add_bitmap(0); add_bitmap(85); add_bitmap(170); add_bitmap(255);
913 #define iml_clear_stream_data() \
914 HeapFree(GetProcessHeap(), 0, Test_Stream.iml_data); \
915 Test_Stream.iml_data = NULL; \
916 Test_Stream.iml_data_size = 0;
918 static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max,
919 INT width, INT height, INT bpp, const char *comment)
923 ret = ImageList_GetImageCount(himl);
924 ok(ret == cur, "expected cur %d got %d\n", cur, ret);
926 ret = ImageList_GetIconSize(himl, &cxx, &cyy);
927 ok(ret, "ImageList_GetIconSize failed\n");
928 ok(cxx == cx, "wrong cx %d (expected %d)\n", cxx, cx);
929 ok(cyy == cy, "wrong cy %d (expected %d)\n", cyy, cy);
931 iml_clear_stream_data();
932 ret = ImageList_Write(himl, &Test_Stream.is);
933 ok(ret, "ImageList_Write failed\n");
935 ok(Test_Stream.iml_data != 0, "ImageList_Write didn't write any data\n");
936 ok(Test_Stream.iml_data_size > sizeof(ILHEAD), "ImageList_Write wrote not enough data\n");
938 check_ilhead_data(Test_Stream.iml_data, cx, cy, cur, max);
939 check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD),
940 Test_Stream.iml_data_size - sizeof(ILHEAD),
941 width, height, bpp, comment);
944 static void test_imagelist_storage(void)
949 himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 1, 1);
950 ok(himl != 0, "ImageList_Create failed\n");
952 check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, BMP_CX * 4, BMP_CX * 1, 24, "empty");
954 image_list_init(himl);
955 check_iml_data(himl, BMP_CX, BMP_CX, 24, 27, BMP_CX * 4, BMP_CX * 7, 24, "orig");
957 ret = ImageList_Remove(himl, 4);
958 ok(ret, "ImageList_Remove failed\n");
959 check_iml_data(himl, BMP_CX, BMP_CX, 23, 27, BMP_CX * 4, BMP_CX * 7, 24, "1");
961 ret = ImageList_Remove(himl, 5);
962 ok(ret, "ImageList_Remove failed\n");
963 check_iml_data(himl, BMP_CX, BMP_CX, 22, 27, BMP_CX * 4, BMP_CX * 7, 24, "2");
965 ret = ImageList_Remove(himl, 6);
966 ok(ret, "ImageList_Remove failed\n");
967 check_iml_data(himl, BMP_CX, BMP_CX, 21, 27, BMP_CX * 4, BMP_CX * 7, 24, "3");
969 ret = ImageList_Remove(himl, 7);
970 ok(ret, "ImageList_Remove failed\n");
971 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, BMP_CX * 4, BMP_CX * 7, 24, "4");
973 ret = ImageList_Remove(himl, -2);
974 ok(!ret, "ImageList_Remove(-2) should fail\n");
975 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, BMP_CX * 4, BMP_CX * 7, 24, "5");
977 ret = ImageList_Remove(himl, 20);
978 ok(!ret, "ImageList_Remove(20) should fail\n");
979 check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, BMP_CX * 4, BMP_CX * 7, 24, "6");
981 ret = ImageList_Remove(himl, -1);
982 ok(ret, "ImageList_Remove(-1) failed\n");
983 check_iml_data(himl, BMP_CX, BMP_CX, 0, 4, BMP_CX * 4, BMP_CX * 1, 24, "7");
985 ret = ImageList_Destroy(himl);
986 ok(ret, "ImageList_Destroy failed\n");
988 iml_clear_stream_data();
991 static void test_shell_imagelist(void)
993 BOOL (WINAPI *pSHGetImageList)(INT, REFIID, void**);
994 IImageList *iml = NULL;
1000 /* Try to load function from shell32 */
1001 hShell32 = LoadLibrary("shell32.dll");
1002 pSHGetImageList = (void*)GetProcAddress(hShell32, (LPCSTR) 727);
1004 if (!pSHGetImageList)
1006 win_skip("SHGetImageList not available, skipping test\n");
1010 /* Get system image list */
1011 hr = (pSHGetImageList)(SHIL_LARGE, &IID_IImageList, (void**)&iml);
1013 todo_wine ok(SUCCEEDED(hr), "SHGetImageList failed, hr=%x\n", hr);
1018 IImageList_GetImageCount(iml, &out);
1019 todo_wine ok(out > 0, "IImageList_GetImageCount returned out <= 0\n");
1021 /* right and bottom should be 32x32 for large icons, or 48x48 if larger
1022 icons enabled in control panel */
1023 IImageList_GetImageRect(iml, 0, &rect);
1024 todo_wine ok((((rect.right == 32) && (rect.bottom == 32)) ||
1025 ((rect.right == 48) && (rect.bottom == 48))),
1026 "IImageList_GetImageRect returned r:%d,b:%d\n",
1027 rect.right, rect.bottom);
1029 IImageList_Release(iml);
1030 FreeLibrary(hShell32);
1033 static HBITMAP create_test_bitmap(HDC hdc, int bpp, UINT32 pixel1, UINT32 pixel2)
1036 UINT32 *buffer = NULL;
1037 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, bpp, BI_RGB,
1040 hBitmap = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, NULL, 0);
1041 ok(hBitmap != NULL && buffer != NULL, "CreateDIBSection failed.\n");
1043 if(!hBitmap || !buffer)
1045 DeleteObject(hBitmap);
1055 static BOOL colour_match(UINT32 x, UINT32 y)
1057 const INT32 tolerance = 8;
1059 const INT32 dr = abs((INT32)(x & 0x000000FF) - (INT32)(y & 0x000000FF));
1060 const INT32 dg = abs((INT32)((x & 0x0000FF00) >> 8) - (INT32)((y & 0x0000FF00) >> 8));
1061 const INT32 db = abs((INT32)((x & 0x00FF0000) >> 16) - (INT32)((y & 0x00FF0000) >> 16));
1063 return (dr <= tolerance && dg <= tolerance && db <= tolerance);
1066 static void check_ImageList_DrawIndirect(IMAGELISTDRAWPARAMS *ildp, UINT32 *bits,
1067 UINT32 expected, int line)
1069 bits[0] = 0x00FFFFFF;
1070 pImageList_DrawIndirect(ildp);
1071 ok(colour_match(bits[0], expected),
1072 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1073 bits[0] & 0x00FFFFFF, expected, line);
1077 static void check_ImageList_DrawIndirect_fStyle(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1078 UINT fStyle, UINT32 expected, int line)
1080 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1081 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, ILS_NORMAL, 0, 0x00000000};
1082 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1085 static void check_ImageList_DrawIndirect_ILD_ROP(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1086 DWORD dwRop, UINT32 expected, int line)
1088 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1089 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_IMAGE | ILD_ROP, dwRop, ILS_NORMAL, 0, 0x00000000};
1090 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1093 static void check_ImageList_DrawIndirect_fState(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i, UINT fStyle,
1094 UINT fState, DWORD Frame, UINT32 expected, int line)
1096 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1097 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1098 check_ImageList_DrawIndirect(&ildp, bits, expected, line);
1101 static void check_ImageList_DrawIndirect_broken(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
1102 UINT fStyle, UINT fState, DWORD Frame, UINT32 expected,
1103 UINT32 broken_expected, int line)
1105 IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
1106 0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
1107 bits[0] = 0x00FFFFFF;
1108 pImageList_DrawIndirect(&ildp);
1109 ok(colour_match(bits[0], expected) ||
1110 broken(colour_match(bits[0], broken_expected)),
1111 "ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
1112 bits[0] & 0x00FFFFFF, expected, line);
1115 static void test_ImageList_DrawIndirect(void)
1117 HIMAGELIST himl = NULL;
1120 HBITMAP hbmOld = NULL, hbmDst = NULL;
1121 HBITMAP hbmMask = NULL, hbmInverseMask = NULL;
1122 HBITMAP hbmImage = NULL, hbmAlphaImage = NULL, hbmTransparentImage = NULL;
1123 int iImage = -1, iAlphaImage = -1, iTransparentImage = -1;
1125 UINT32 maskBits = 0x00000000, inverseMaskBits = 0xFFFFFFFF;
1127 BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB,
1130 hdcDst = CreateCompatibleDC(0);
1131 ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
1135 hbmMask = CreateBitmap(2, 1, 1, 1, &maskBits);
1136 ok(hbmMask != 0, "CreateBitmap failed\n");
1137 if(!hbmMask) goto cleanup;
1139 hbmInverseMask = CreateBitmap(2, 1, 1, 1, &inverseMaskBits);
1140 ok(hbmInverseMask != 0, "CreateBitmap failed\n");
1141 if(!hbmInverseMask) goto cleanup;
1143 himl = pImageList_Create(2, 1, ILC_COLOR32, 0, 1);
1144 ok(himl != 0, "ImageList_Create failed\n");
1145 if(!himl) goto cleanup;
1147 /* Add a no-alpha image */
1148 hbmImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x00ABCDEF);
1149 if(!hbmImage) goto cleanup;
1151 iImage = pImageList_Add(himl, hbmImage, hbmMask);
1152 ok(iImage != -1, "ImageList_Add failed\n");
1153 if(iImage == -1) goto cleanup;
1155 /* Add an alpha image */
1156 hbmAlphaImage = create_test_bitmap(hdcDst, 32, 0x89ABCDEF, 0x89ABCDEF);
1157 if(!hbmAlphaImage) goto cleanup;
1159 iAlphaImage = pImageList_Add(himl, hbmAlphaImage, hbmMask);
1160 ok(iAlphaImage != -1, "ImageList_Add failed\n");
1161 if(iAlphaImage == -1) goto cleanup;
1163 /* Add a transparent alpha image */
1164 hbmTransparentImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x89ABCDEF);
1165 if(!hbmTransparentImage) goto cleanup;
1167 iTransparentImage = pImageList_Add(himl, hbmTransparentImage, hbmMask);
1168 ok(iTransparentImage != -1, "ImageList_Add failed\n");
1169 if(iTransparentImage == -1) goto cleanup;
1172 bitmapInfo.bmiHeader.biBitCount = 32;
1173 hbmDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1174 ok (hbmDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1175 if (!hbmDst || !bits)
1177 hbmOld = SelectObject(hdcDst, hbmDst);
1179 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_NORMAL, 0x00ABCDEF, __LINE__);
1180 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_TRANSPARENT, 0x00ABCDEF, __LINE__);
1181 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x00D4D9DD, __LINE__);
1182 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, 0x00B4BDC4, __LINE__);
1183 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_MASK, 0x00ABCDEF, __LINE__);
1184 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_IMAGE, 0x00ABCDEF, __LINE__);
1185 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_PRESERVEALPHA, 0x00ABCDEF, __LINE__);
1189 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, 0x00D3E5F7, __LINE__);
1190 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_TRANSPARENT, 0x00D3E5F7, __LINE__);
1191 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x009DA8B1, __LINE__);
1192 check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, 0x008C99A3, __LINE__);
1194 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0x00D3E5F7, __LINE__);
1195 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0x00D3E5F7, __LINE__);
1196 check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__);
1199 todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__);
1201 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCCOPY, 0x00ABCDEF, __LINE__);
1202 check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCINVERT, 0x00543210, __LINE__);
1204 /* ILD_ROP is ignored when the image has an alpha channel */
1205 todo_wine check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCCOPY, 0x00D3E5F7, __LINE__);
1206 todo_wine check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCINVERT, 0x00D3E5F7, __LINE__);
1208 todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00CCCCCC, __LINE__);
1209 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00AFAFAF, 0x00F0F0F0, __LINE__);
1211 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_GLOW, 0, 0x00ABCDEF, __LINE__);
1212 check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SHADOW, 0, 0x00ABCDEF, __LINE__);
1214 todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00D5E6F7, __LINE__);
1215 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00E9F2FB, 0x00AEB7C0, __LINE__);
1216 todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_NORMAL, 127, 0x00E9F2FB, 0x00D3E5F7, __LINE__);
1221 SelectObject(hdcDst, hbmOld);
1223 DeleteObject(hbmDst);
1229 DeleteObject(hbmMask);
1231 DeleteObject(hbmInverseMask);
1234 DeleteObject(hbmImage);
1236 DeleteObject(hbmAlphaImage);
1237 if(hbmTransparentImage)
1238 DeleteObject(hbmTransparentImage);
1242 ret = ImageList_Destroy(himl);
1243 ok(ret, "ImageList_Destroy failed\n");
1247 START_TEST(imagelist)
1249 ULONG_PTR ctx_cookie;
1252 HMODULE hComCtl32 = GetModuleHandle("comctl32.dll");
1253 pImageList_Create = NULL; /* These are not needed for non-v6.0 tests*/
1254 pImageList_Add = NULL;
1255 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
1256 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
1258 desktopDC=GetDC(NULL);
1259 hinst = GetModuleHandleA(NULL);
1261 InitCommonControls();
1268 test_imagelist_storage();
1270 FreeLibrary(hComCtl32);
1272 /* Now perform v6 tests */
1274 if (!load_v6_module(&ctx_cookie, &hCtx))
1277 /* Reload comctl32 */
1278 hComCtl32 = LoadLibraryA("comctl32.dll");
1279 pImageList_Create = (void*)GetProcAddress(hComCtl32, "ImageList_Create");
1280 pImageList_Add = (void*)GetProcAddress(hComCtl32, "ImageList_Add");
1281 pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
1282 pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
1285 test_ImageList_DrawIndirect();
1286 test_shell_imagelist();
1288 unload_v6_module(ctx_cookie, hCtx);