Fix signed/unsigned comparison warnings.
[wine] / dlls / comctl32 / tests / imagelist.c
1 /* Unit test suite for imagelist control.
2  *
3  * Copyright 2004 Michael Stefaniuc
4  * Copyright 2002 Mike McCormack for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <assert.h>
22 #include <windows.h>
23 #include <commctrl.h>
24
25 #include "wine/test.h"
26
27 static BOOL (WINAPI *pImageList_DrawIndirect)(IMAGELISTDRAWPARAMS*) = NULL;
28
29 static HDC desktopDC;
30
31 static HIMAGELIST createImageList(cx, cy)
32 {
33     /* Create an ImageList and put an image into it */
34     HDC hdc = CreateCompatibleDC(desktopDC);
35     HIMAGELIST himl = ImageList_Create(cx, cy, ILC_COLOR, 1, 1);
36     HBITMAP hbm = CreateCompatibleBitmap(hdc, cx, cy);
37
38     SelectObject(hdc, hbm);
39     ImageList_Add(himl, hbm, NULL);
40     DeleteObject(hbm);
41     DeleteDC(hdc);
42
43     return himl;
44 }
45
46 static void testHotspot (void)
47 {
48     struct hotspot {
49         int dx;
50         int dy;
51     };
52
53 #define SIZEX1 47
54 #define SIZEY1 31
55 #define SIZEX2 11
56 #define SIZEY2 17
57 #define HOTSPOTS_MAX 4       /* Number of entries in hotspots */
58     static const struct hotspot hotspots[HOTSPOTS_MAX] = {
59         { 10, 7 },
60         { SIZEX1, SIZEY1 },
61         { -9, -8 },
62         { -7, 35 }
63     };
64     int i, j, ret;
65     HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
66     HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
67
68     for (i = 0; i < HOTSPOTS_MAX; i++) {
69         for (j = 0; j < HOTSPOTS_MAX; j++) {
70             int dx1 = hotspots[i].dx;
71             int dy1 = hotspots[i].dy;
72             int dx2 = hotspots[j].dx;
73             int dy2 = hotspots[j].dy;
74             int correctx, correcty, newx, newy;
75             HIMAGELIST himlNew;
76             POINT ppt;
77
78             ret = ImageList_BeginDrag(himl1, 0, dx1, dy1);
79             ok(ret != 0, "BeginDrag failed for { %d, %d }\n", dx1, dy1);
80             /* check merging the dragged image with a second image */
81             ret = ImageList_SetDragCursorImage(himl2, 0, dx2, dy2);
82             ok(ret != 0, "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
83                     dx1, dy1, dx2, dy2);
84             /* check new hotspot, it should be the same like the old one */
85             himlNew = ImageList_GetDragImage(NULL, &ppt);
86             ok(ppt.x == dx1 && ppt.y == dy1,
87                     "Expected drag hotspot [%d,%d] got [%ld,%ld]\n",
88                     dx1, dy1, ppt.x, ppt.y);
89             /* check size of new dragged image */
90             ImageList_GetIconSize(himlNew, &newx, &newy);
91             correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
92             correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
93             ok(newx == correctx && newy == correcty,
94                     "Expected drag image size [%d,%d] got [%d,%d]\n",
95                     correctx, correcty, newx, newy);
96             ImageList_EndDrag();
97         }
98     }
99 #undef SIZEX1
100 #undef SIZEY1
101 #undef SIZEX2
102 #undef SIZEY2
103 #undef HOTSPOTS_MAX
104 }
105
106 static HINSTANCE hinst;
107
108 static const BYTE icon_bits[32*32/8];
109 static const BYTE bitmap_bits[48*48/8];
110
111 static BOOL DoTest1(void)
112 {
113     HIMAGELIST himl ;
114
115     HICON hicon1 ;
116     HICON hicon2 ;
117     HICON hicon3 ;
118
119     /* create an imagelist to play with */
120     himl = ImageList_Create(84,84,0x10,0,3);
121     ok(himl!=0,"failed to create imagelist\n");
122
123     /* load the icons to add to the image list */
124     hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
125     ok(hicon1 != 0, "no hicon1\n");
126     hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
127     ok(hicon2 != 0, "no hicon2\n");
128     hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
129     ok(hicon3 != 0, "no hicon3\n");
130
131     /* remove when nothing exists */
132     ok(!ImageList_Remove(himl,0),"removed non-existent icon\n");
133
134     /* add three */
135     ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
136     ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
137     ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
138
139     /* remove three */
140     ok(ImageList_Remove(himl,0),"can't remove 0\n");
141     ok(ImageList_Remove(himl,0),"can't remove 0\n");
142     ok(ImageList_Remove(himl,0),"can't remove 0\n");
143
144     /* remove one extra */
145     ok(!ImageList_Remove(himl,0),"removed non-existent icon\n");
146
147     /* destroy it */
148     ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
149
150     /* icons should be deleted by the imagelist */
151     ok(!DeleteObject(hicon1),"icon 1 wasn't deleted\n");
152     ok(!DeleteObject(hicon2),"icon 2 wasn't deleted\n");
153     ok(!DeleteObject(hicon3),"icon 3 wasn't deleted\n");
154
155     return TRUE;
156 }
157
158 static BOOL DoTest2(void)
159 {
160     HIMAGELIST himl ;
161
162     HICON hicon1 ;
163     HICON hicon2 ;
164     HICON hicon3 ;
165
166     /* create an imagelist to play with */
167     himl = ImageList_Create(84,84,0x10,0,3);
168     ok(himl!=0,"failed to create imagelist\n");
169
170     /* load the icons to add to the image list */
171     hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
172     ok(hicon1 != 0, "no hicon1\n");
173     hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
174     ok(hicon2 != 0, "no hicon2\n");
175     hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
176     ok(hicon3 != 0, "no hicon3\n");
177
178     /* remove when nothing exists */
179     ok(!ImageList_Remove(himl,0),"removed non-existent icon\n");
180
181     /* add three */
182     ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
183     ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
184     ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
185
186     /* destroy it */
187     ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
188
189     /* icons should be deleted by the imagelist */
190     ok(!DeleteObject(hicon1),"icon 1 wasn't deleted\n");
191     ok(!DeleteObject(hicon2),"icon 2 wasn't deleted\n");
192     ok(!DeleteObject(hicon3),"icon 3 wasn't deleted\n");
193
194     return TRUE;
195 }
196
197 static HWND create_a_window(void)
198 {
199     WNDCLASSA cls;
200     char className[] = "bmwnd";
201     char winName[]   = "Test Bitmap";
202     HWND hWnd;
203
204     cls.style         = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
205     cls.lpfnWndProc   = DefWindowProcA;
206     cls.cbClsExtra    = 0;
207     cls.cbWndExtra    = 0;
208     cls.hInstance     = 0;
209     cls.hIcon         = LoadIconA (0, (LPSTR)IDI_APPLICATION);
210     cls.hCursor       = LoadCursorA (0, (LPSTR)IDC_ARROW);
211     cls.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
212     cls.lpszMenuName  = 0;
213     cls.lpszClassName = className;
214
215     RegisterClassA (&cls);
216
217     /* Setup windows */
218     hWnd = CreateWindowA (className, winName, 
219        WS_OVERLAPPEDWINDOW ,
220        CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, 0,
221        0, hinst, 0);
222
223     return hWnd;
224 }
225
226 static BOOL DoTest3(void)
227 {
228     HIMAGELIST himl ;
229
230     HBITMAP hbm1 ;
231     HBITMAP hbm2 ;
232     HBITMAP hbm3 ;
233
234     IMAGELISTDRAWPARAMS imldp;
235     HDC hdc;
236     HWND hwndfortest;
237
238     if (!pImageList_DrawIndirect)
239     {
240         HMODULE hComCtl32 = LoadLibraryA("comctl32.dll");
241         pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
242         if (!pImageList_DrawIndirect)
243         {
244             trace("ImageList_DrawIndirect not available, skipping test\n");
245             return TRUE;
246         }
247     }
248
249     hwndfortest = create_a_window();
250     hdc = GetDC(hwndfortest);
251     ok(hdc!=NULL, "couldn't get DC\n");
252
253     /* create an imagelist to play with */
254     himl = ImageList_Create(48,48,0x10,0,3);
255     ok(himl!=0,"failed to create imagelist\n");
256
257     /* load the icons to add to the image list */
258     hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
259     ok(hbm1 != 0, "no bitmap 1\n");
260     hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
261     ok(hbm2 != 0, "no bitmap 2\n");
262     hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
263     ok(hbm3 != 0, "no bitmap 3\n");
264
265     /* remove when nothing exists */
266     ok(!ImageList_Remove(himl,0),"removed non-existent bitmap\n");
267
268     /* add three */
269     ok(0==ImageList_Add(himl, hbm1, 0),"failed to add bitmap 1\n");
270     ok(1==ImageList_Add(himl, hbm2, 0),"failed to add bitmap 2\n");
271
272     ok(ImageList_SetImageCount(himl,3),"Setimage count failed\n");
273     /*ok(2==ImageList_Add(himl, hbm3, NULL),"failed to add bitmap 3\n"); */
274     ok(ImageList_Replace(himl, 2, hbm3, 0),"failed to replace bitmap 3\n");
275
276     Rectangle(hdc, 100, 100, 74, 74);
277     memset(&imldp, 0, sizeof imldp);
278     ok(!pImageList_DrawIndirect(&imldp), "zero data succeeded!\n");
279     imldp.cbSize = sizeof imldp;
280     ok(!pImageList_DrawIndirect(&imldp), "zero hdc succeeded!\n");
281     imldp.hdcDst = hdc;
282     ok(!pImageList_DrawIndirect(&imldp),"zero himl succeeded!\n");
283     imldp.himl = himl;
284     ok(pImageList_DrawIndirect(&imldp),"should succeeded\n");
285     imldp.fStyle = SRCCOPY;
286     imldp.rgbBk = CLR_DEFAULT;
287     imldp.rgbFg = CLR_DEFAULT;
288     imldp.y = 100;
289     imldp.x = 100;
290     ok(pImageList_DrawIndirect(&imldp),"should succeeded\n");
291     imldp.i ++;
292     ok(pImageList_DrawIndirect(&imldp),"should succeeded\n");
293     imldp.i ++;
294     ok(pImageList_DrawIndirect(&imldp),"should succeeded\n");
295     imldp.i ++;
296     ok(!pImageList_DrawIndirect(&imldp),"should fail\n");
297
298     /* remove three */
299     ok(ImageList_Remove(himl, 0), "removing 1st bitmap\n");
300     ok(ImageList_Remove(himl, 0), "removing 2nd bitmap\n");
301     ok(ImageList_Remove(himl, 0), "removing 3rd bitmap\n");
302
303     /* destroy it */
304     ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
305
306     /* icons should be deleted by the imagelist */
307     ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
308     ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
309     ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
310
311     ReleaseDC(hwndfortest, hdc);
312     DestroyWindow(hwndfortest);
313
314     return TRUE;
315 }
316
317 START_TEST(imagelist)
318 {
319     desktopDC=GetDC(NULL);
320     hinst = GetModuleHandleA(NULL);
321
322     InitCommonControls();
323
324     testHotspot();
325     DoTest1();
326     DoTest2();
327     DoTest3();
328 }