7945113d828263c0d22fe81c3144992efed02c47
[reactos.git] / rostests / apitests / user32 / GetIconInfo.c
1 #include <wine/test.h>
2 #include <wingdi.h>
3 #include <winuser.h>
4
5 #include "resource.h"
6
7 // FIXME user32
8
9 void
10 Test_GetIconInfo(BOOL fIcon, DWORD screen_bpp)
11 {
12 HICON hicon;
13 ICONINFO iconinfo, iconinfo2;
14 BITMAP bitmap;
15
16 iconinfo.fIcon = fIcon;
17 iconinfo.xHotspot = 0;
18 iconinfo.yHotspot = 0;
19 iconinfo.hbmMask = NULL;
20 iconinfo.hbmColor = NULL;
21
22 hicon = CreateIconIndirect(&iconinfo);
23 ok(hicon == 0, "should fail\n");
24
25 iconinfo.hbmMask = CreateBitmap(8, 16, 1, 1, NULL);
26 hicon = CreateIconIndirect(&iconinfo);
27 ok(hicon != 0, "should not fail\n");
28
29 ok(GetIconInfo(hicon, &iconinfo2), "\n");
30 ok(iconinfo2.fIcon == iconinfo.fIcon, "\n");
31 if (fIcon)
32 {
33 ok(iconinfo2.xHotspot == 4, "%ld\n", iconinfo2.xHotspot);
34 ok(iconinfo2.yHotspot == 4, "%ld\n", iconinfo2.yHotspot);
35 }
36 else
37 {
38 ok(iconinfo2.xHotspot == 0, "%ld\n", iconinfo2.xHotspot);
39 ok(iconinfo2.yHotspot == 0, "%ld\n", iconinfo2.yHotspot);
40 }
41 ok(iconinfo2.hbmMask != NULL, "\n");
42 ok(iconinfo2.hbmMask != iconinfo.hbmMask, "\n");
43 ok(iconinfo2.hbmColor == NULL, "\n");
44 DeleteObject(iconinfo2.hbmMask);
45
46 ok(GetIconInfo(hicon, &iconinfo2), "\n");
47 ok(iconinfo2.fIcon == iconinfo.fIcon, "\n");
48 if (fIcon)
49 {
50 ok(iconinfo2.xHotspot == 4, "%ld\n", iconinfo2.xHotspot);
51 ok(iconinfo2.yHotspot == 4, "%ld\n", iconinfo2.yHotspot);
52 }
53 else
54 {
55 ok(iconinfo2.xHotspot == 0, "%ld\n", iconinfo2.xHotspot);
56 ok(iconinfo2.yHotspot == 0, "%ld\n", iconinfo2.yHotspot);
57 }
58 ok(iconinfo2.hbmMask != NULL, "\n");
59 ok(iconinfo2.hbmMask != iconinfo.hbmMask, "\n");
60 ok(iconinfo2.hbmColor == NULL, "\n");
61 DeleteObject(iconinfo2.hbmMask);
62 ok(DestroyIcon(hicon), "\n");
63
64 iconinfo.hbmColor = CreateBitmap(2, 2, 1, 1, NULL);
65 hicon = CreateIconIndirect(&iconinfo);
66 ok(hicon != 0, "should not fail\n");
67
68 ok(GetIconInfo(hicon, &iconinfo2), "\n");
69 ok(iconinfo2.fIcon == iconinfo.fIcon, "\n");
70 if (fIcon)
71 {
72 ok(iconinfo2.xHotspot == 4, "%ld\n", iconinfo2.xHotspot);
73 ok(iconinfo2.yHotspot == 8, "%ld\n", iconinfo2.yHotspot);
74 }
75 else
76 {
77 ok(iconinfo2.xHotspot == 0, "%ld\n", iconinfo2.xHotspot);
78 ok(iconinfo2.yHotspot == 0, "%ld\n", iconinfo2.yHotspot);
79 }
80 ok(iconinfo2.hbmMask != NULL, "\n");
81 ok(iconinfo2.hbmMask != iconinfo.hbmMask, "\n");
82 ok(iconinfo2.hbmColor != NULL, "\n");
83 ok(iconinfo2.hbmColor != iconinfo.hbmColor, "\n");
84
85 ok(GetObject(iconinfo2.hbmMask, sizeof(bitmap), &bitmap), "GetObject failed\n");
86 ok(bitmap.bmType == 0, "\n");
87 ok(bitmap.bmWidth == 8, "\n");
88 ok(bitmap.bmHeight == 16, "\n");
89 ok(bitmap.bmWidthBytes == 2, "\n");
90 ok(bitmap.bmPlanes == 1, "\n");
91 ok(bitmap.bmBitsPixel == 1, "\n");
92 ok(bitmap.bmBits == NULL, "\n");
93
94 ok(GetObject(iconinfo2.hbmColor, sizeof(bitmap), &bitmap), "GetObject failed\n");
95 ok(bitmap.bmType == 0, "\n");
96 ok(bitmap.bmWidth == 8, "\n");
97 ok(bitmap.bmHeight == 16, "\n");
98 ok(bitmap.bmWidthBytes == 8 * bitmap.bmBitsPixel / 8, "\n");
99 ok(bitmap.bmPlanes == 1, "\n");
100 ok(bitmap.bmBitsPixel == screen_bpp, "\n");
101 ok(bitmap.bmBits == NULL, "\n");
102 DeleteObject(iconinfo2.hbmMask);
103 DeleteObject(iconinfo2.hbmColor);
104 ok(DestroyIcon(hicon), "\n");
105
106 DeleteObject(iconinfo.hbmMask);
107 iconinfo.hbmMask = NULL;
108 hicon = CreateIconIndirect(&iconinfo);
109 ok(hicon == 0, "should fail\n");
110
111 DeleteObject(iconinfo.hbmColor);
112 iconinfo.hbmColor = CreateCompatibleBitmap(GetDC(0), 16, 16);
113 hicon = CreateIconIndirect(&iconinfo);
114 ok(hicon == 0, "should fail\n");
115
116 iconinfo.hbmMask = CreateCompatibleBitmap(GetDC(0), 8, 16);
117 hicon = CreateIconIndirect(&iconinfo);
118 ok(hicon != 0, "should not fail\n");
119
120 ok(GetIconInfo(hicon, &iconinfo2), "\n");
121
122 ok(GetObject(iconinfo2.hbmMask, sizeof(bitmap), &bitmap), "GetObject failed\n");
123 ok(bitmap.bmType == 0, "\n");
124 ok(bitmap.bmWidth == 8, "%ld\n", bitmap.bmWidth);
125 ok(bitmap.bmHeight == 16, "%ld\n", bitmap.bmHeight);
126 ok(bitmap.bmWidthBytes == 2, "%ld\n", bitmap.bmWidthBytes);
127 ok(bitmap.bmPlanes == 1, "%d\n", bitmap.bmPlanes);
128 ok(bitmap.bmBitsPixel == 1, "%d\n", bitmap.bmBitsPixel);
129 ok(bitmap.bmBits == NULL, "\n");
130
131 ok(GetObject(iconinfo2.hbmColor, sizeof(bitmap), &bitmap), "GetObject failed\n");
132 ok(bitmap.bmType == 0, "\n");
133 ok(bitmap.bmWidth == 8, "%ld\n", bitmap.bmWidth);
134 ok(bitmap.bmHeight == 16, "%ld\n", bitmap.bmHeight);
135 ok(bitmap.bmWidthBytes == screen_bpp, "%ld\n", bitmap.bmWidthBytes);
136 ok(bitmap.bmPlanes == 1, "%d\n", bitmap.bmPlanes);
137 ok(bitmap.bmBitsPixel == screen_bpp, "%d\n", bitmap.bmBitsPixel);
138 ok(bitmap.bmBits == NULL, "\n");
139 DeleteObject(iconinfo2.hbmMask);
140 DeleteObject(iconinfo2.hbmColor);
141 ok(DestroyIcon(hicon), "\n");
142 }
143
144
145 START_TEST(GetIconInfo)
146 {
147 HCURSOR hcursor;
148 ICONINFO iconinfo2;
149 BITMAP bitmap;
150 DWORD data[] = {0, 0, 0, 0, 0, 0};
151 DWORD bpp, screenbpp, creationbpp;
152 DEVMODEW dm;
153
154 /* Test icons behaviour regarding display settings */
155 EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &dm);
156 screenbpp = dm.dmBitsPerPel;
157
158 Test_GetIconInfo(0, screenbpp);
159 Test_GetIconInfo(1, screenbpp);
160
161 hcursor = LoadCursor(GetModuleHandle(NULL), "TESTCURSOR");
162 ok(hcursor != 0, "should not fail, error %ld\n", GetLastError());
163 ok(GetIconInfo(hcursor, &iconinfo2), "\n");
164 ok(iconinfo2.fIcon == 0, "\n");
165 ok(iconinfo2.xHotspot == 8, "%ld\n", iconinfo2.xHotspot);
166 ok(iconinfo2.yHotspot == 29, "%ld\n", iconinfo2.yHotspot);
167 ok(iconinfo2.hbmMask != NULL, "\n");
168 ok(iconinfo2.hbmColor != NULL, "\n");
169 /* Delete objects */
170 DeleteObject(iconinfo2.hbmColor);
171 DeleteObject(iconinfo2.hbmMask);
172 /* Delete cursor */
173 DestroyCursor(hcursor);
174
175 /* To sum it up:
176 * There are two criteria when using icons: performance and aesthetics (=alpha channel).
177 * Performance asks for bit parity with the screen display.
178 * Aesthetics needs a 32bpp bitmap.
179 * The behaviour is basically : aesthetics first if already loaded.
180 * ie: if the 32bpp bitmap were already loaded because of previous display settings, always use it.
181 * Otherwise, use the bitmap matching the screen bit depth.
182 */
183
184 /* if we use LR_SHARED here, and reverse the loop (32->16), then hbmColor.bmBitsPixel is always 32. */
185 for(creationbpp = 16; creationbpp <=32; creationbpp += 8)
186 {
187 dm.dmBitsPerPel = creationbpp;
188 if(ChangeDisplaySettingsExW(NULL, &dm, NULL, 0, NULL) != DISP_CHANGE_SUCCESSFUL)
189 {
190 skip("Unable to change bpp to %lu.\n", creationbpp);
191 continue;
192 }
193 hcursor = LoadImage(GetModuleHandle(NULL),
194 MAKEINTRESOURCE(IDI_TEST),
195 IMAGE_ICON,
196 0,
197 0,
198 LR_DEFAULTCOLOR);
199 ok(hcursor != 0, "should not fail\n");
200
201 /* If we reverse the loop here (32->16 bpp), then hbmColor.bmBitsPixel is always 32 */
202 for(bpp = 16; bpp <=32; bpp += 8)
203 {
204 dm.dmBitsPerPel = bpp;
205 if(ChangeDisplaySettingsExW(NULL, &dm, NULL, 0, NULL) != DISP_CHANGE_SUCCESSFUL)
206 {
207 skip("Unable to change bpp to %lu.\n", bpp);
208 continue;
209 }
210 ok(GetIconInfo(hcursor, &iconinfo2), "\n");
211 ok(iconinfo2.fIcon == 1, "\n");
212 ok(iconinfo2.xHotspot == 24, "%ld\n", iconinfo2.xHotspot);
213 ok(iconinfo2.yHotspot == 24, "%ld\n", iconinfo2.yHotspot);
214 ok(iconinfo2.hbmMask != NULL, "\n");
215 ok(iconinfo2.hbmColor != NULL, "\n");
216
217 ok(GetObject(iconinfo2.hbmMask, sizeof(bitmap), &bitmap), "GetObject failed\n");
218 ok(bitmap.bmType == 0, "\n");
219 ok(bitmap.bmWidth == 48, "%ld\n", bitmap.bmWidth);
220 ok(bitmap.bmHeight == 48, "\n");
221 ok(bitmap.bmWidthBytes == 6, "\n");
222 ok(bitmap.bmPlanes == 1, "\n");
223 ok(bitmap.bmBitsPixel == 1, "\n");
224 ok(bitmap.bmBits == NULL, "\n");
225
226 ok(GetObject(iconinfo2.hbmColor, sizeof(bitmap), &bitmap), "GetObject failed\n");
227 ok(bitmap.bmType == 0, "\n");
228 ok(bitmap.bmWidth == 48, "\n");
229 ok(bitmap.bmHeight == 48, "\n");
230 ok(bitmap.bmWidthBytes == 48 * bitmap.bmBitsPixel / 8, "\n");
231 ok(bitmap.bmPlanes == 1, "\n");
232 ok(bitmap.bmBitsPixel == (creationbpp == 32 ? 32 : bpp), "creationbpp: %lu, bpp: %lu:\n", creationbpp, bpp);
233 ok(bitmap.bmBits == NULL, "\n");
234
235 /* Delete objects */
236 DeleteObject(iconinfo2.hbmColor);
237 DeleteObject(iconinfo2.hbmMask);
238 }
239 ok(DestroyIcon(hcursor), "\n");
240 }
241 /* Restore display settings */
242 dm.dmBitsPerPel = screenbpp;
243 if(ChangeDisplaySettingsExW(NULL, &dm, NULL, 0, NULL) != DISP_CHANGE_SUCCESSFUL)
244 trace("Unable to go back to previous display settings. Sorry.\n");
245
246 hcursor = CreateCursor(NULL, 1, 2, 4, 4, data, data);
247 ok(hcursor != 0, "should not fail\n");
248 ok(GetIconInfo(hcursor, &iconinfo2), "\n");
249 ok(iconinfo2.fIcon == 0, "\n");
250 ok(iconinfo2.xHotspot == 1, "%ld\n", iconinfo2.xHotspot);
251 ok(iconinfo2.yHotspot == 2, "%ld\n", iconinfo2.yHotspot);
252 ok(iconinfo2.hbmMask != NULL, "\n");
253 ok(iconinfo2.hbmColor == NULL, "\n");
254
255 ok(GetObject(iconinfo2.hbmMask, sizeof(bitmap), &bitmap), "GetObject failed\n");
256 ok(bitmap.bmType == 0, "\n");
257 ok(bitmap.bmWidth == 4, "%ld\n", bitmap.bmWidth);
258 ok(bitmap.bmHeight == 8, "%ld\n", bitmap.bmHeight);
259 ok(bitmap.bmWidthBytes == 2, "%ld\n", bitmap.bmWidthBytes);
260 ok(bitmap.bmPlanes == 1, "\n");
261 ok(bitmap.bmBitsPixel == 1, "\n");
262 ok(bitmap.bmBits == NULL, "\n");
263
264 /* Delete objects */
265 DeleteObject(iconinfo2.hbmColor);
266 DeleteObject(iconinfo2.hbmMask);
267 /* Delete cursor */
268 DestroyCursor(hcursor);
269 }
270
271