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