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