1 2 #include "precomp.h" 3 4 // FIXME user32 5 6 void 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 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