|
9 | 9 | #include "shelltest.h" |
10 | 10 | #include <stdio.h> |
11 | 11 |
|
| 12 | +EXTERN_C BOOL WINAPI SHAreIconsEqual(HICON hIcon1, HICON hIcon2); |
| 13 | + |
| 14 | +static void SafeDestroyIcon(HICON hIco) |
| 15 | +{ |
| 16 | + if (hIco) |
| 17 | + DestroyIcon(hIco); |
| 18 | +} |
| 19 | + |
| 20 | +static UINT GetIcoSize(HICON hIco) |
| 21 | +{ |
| 22 | + ICONINFO info; |
| 23 | + if (!GetIconInfo(hIco, &info)) |
| 24 | + return 0; |
| 25 | + |
| 26 | + BITMAP bm; |
| 27 | + if (!GetObject(info.hbmColor ? info.hbmColor : info.hbmMask, sizeof(bm), &bm)) |
| 28 | + bm.bmWidth = 0; |
| 29 | + DeleteObject(info.hbmMask); |
| 30 | + DeleteObject(info.hbmColor); |
| 31 | + return bm.bmWidth; |
| 32 | +} |
| 33 | + |
12 | 34 | typedef struct |
13 | 35 | { |
14 | 36 | PCWSTR pszFilePath; |
@@ -122,3 +144,66 @@ START_TEST(ExtractIconEx) |
122 | 144 | DeleteFileA(FileName[0]); |
123 | 145 | DeleteFileA(FileName[1]); |
124 | 146 | } |
| 147 | + |
| 148 | +static HRESULT SHDEI(LPCWSTR pszIconFile, int Index = 0, UINT GIL = 0, UINT Size = 0) |
| 149 | +{ |
| 150 | + HICON hIco = NULL; |
| 151 | + HRESULT hr = SHDefExtractIcon(pszIconFile, Index, GIL, &hIco, NULL, Size); |
| 152 | + if (hr == S_OK) |
| 153 | + { |
| 154 | + hr = GetIcoSize(hIco); |
| 155 | + SafeDestroyIcon(hIco); |
| 156 | + } |
| 157 | + return hr; |
| 158 | +} |
| 159 | + |
| 160 | +START_TEST(SHDefExtractIcon) |
| 161 | +{ |
| 162 | + HRESULT hr; |
| 163 | + int SysBigIconSize = GetSystemMetrics(SM_CXICON); |
| 164 | + |
| 165 | + // Modern Windows requires the system image list to be initialized for GIL_SIMULATEDOC to work! |
| 166 | + SHFILEINFOW shfi; |
| 167 | + SHGetFileInfoW(L"x", 0, &shfi, sizeof(shfi), SHGFI_SYSICONINDEX | SHGFI_USEFILEATTRIBUTES); |
| 168 | + |
| 169 | + WCHAR path[MAX_PATH]; |
| 170 | + GetSystemDirectoryW(path, _countof(path)); |
| 171 | + PathAppendW(path, L"user32.dll"); |
| 172 | + int index = 1; |
| 173 | + |
| 174 | + ok(SHDEI(path, index, 0, 0) == SysBigIconSize, "0 size must match GetSystemMetrics\n"); |
| 175 | + ok(SHDEI(path, index, 0, SysBigIconSize * 2) == SysBigIconSize * 2, "Resize failed\n"); |
| 176 | + |
| 177 | + HICON hIcoLarge, hIcoSmall; |
| 178 | + if (SHDefExtractIcon(path, index, 0, &hIcoLarge, &hIcoSmall, 0) != S_OK) |
| 179 | + hIcoLarge = hIcoSmall = NULL; |
| 180 | + ok(hIcoLarge && hIcoSmall && !SHAreIconsEqual(hIcoLarge, hIcoSmall), "Large+Small failed\n"); |
| 181 | + SafeDestroyIcon(hIcoLarge); |
| 182 | + SafeDestroyIcon(hIcoSmall); |
| 183 | + |
| 184 | + static const int sizes[] = { 0, SysBigIconSize * 2 }; |
| 185 | + for (UINT i = 0; i < _countof(sizes); ++i) |
| 186 | + { |
| 187 | + HICON hIcoNormal, hIcoSimDoc; |
| 188 | + if (FAILED(hr = SHDefExtractIcon(path, index, 0, &hIcoNormal, NULL, sizes[i]))) |
| 189 | + hIcoNormal = NULL; |
| 190 | + if (FAILED(hr = SHDefExtractIcon(path, index, GIL_SIMULATEDOC, &hIcoSimDoc, NULL, sizes[i]))) |
| 191 | + hIcoSimDoc = NULL; |
| 192 | + ok(hIcoNormal && hIcoSimDoc && !SHAreIconsEqual(hIcoNormal, hIcoSimDoc), "GIL_SIMULATEDOC failed\n"); |
| 193 | + SafeDestroyIcon(hIcoNormal); |
| 194 | + SafeDestroyIcon(hIcoSimDoc); |
| 195 | + } |
| 196 | + |
| 197 | + GetTempPathW(_countof(path), path); |
| 198 | + GetTempFileNameW(path, L"TEST", 0, path); |
| 199 | + ok(SHDEI(path) == S_FALSE, "Empty file should return S_FALSE\n"); |
| 200 | + HANDLE hFile = CreateFileW(path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); |
| 201 | + if (hFile != INVALID_HANDLE_VALUE) |
| 202 | + { |
| 203 | + DWORD io; |
| 204 | + WriteFile(hFile, "!", 1, &io, NULL); |
| 205 | + CloseHandle(hFile); |
| 206 | + ok(SHDEI(path) == S_FALSE, "File without icons should return S_FALSE\n"); |
| 207 | + } |
| 208 | + DeleteFile(path); |
| 209 | +} |
0 commit comments