Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
These are fixes for https://bugs.winehq.org/show_bug.cgi?id=24721.
dlls/shell32/iconcache.c | 114 +++++++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 57 deletions(-)
diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c index 8b864df5e8..562f9b243c 100644 --- a/dlls/shell32/iconcache.c +++ b/dlls/shell32/iconcache.c @@ -61,8 +61,7 @@ typedef struct
static HDPA sic_hdpa; static INIT_ONCE sic_init_once = INIT_ONCE_STATIC_INIT; -static HIMAGELIST ShellSmallIconList; -static HIMAGELIST ShellBigIconList; +static HIMAGELIST shell_imagelists[SHIL_SMALL+1];
static CRITICAL_SECTION SHELL32_SicCS; static CRITICAL_SECTION_DEBUG critsect_debug = @@ -158,8 +157,9 @@ static int SIC_LoadOverlayIcon(int icon_idx); * Creates a new icon as a copy of the passed-in icon, overlaid with a * shortcut image. */ -static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large) -{ ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo; +static HICON SIC_OverlayShortcutImage(HICON SourceIcon, int type) +{ + ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo; HICON ShortcutIcon, TargetIcon; BITMAP SourceBitmapInfo, ShortcutBitmapInfo; HDC SourceDC = NULL, @@ -186,21 +186,16 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large) resource id, but not all icons are present yet so we can't use icon indices */
- if (s_imgListIdx != -1) - { - if (large) - ShortcutIcon = ImageList_GetIcon(ShellBigIconList, s_imgListIdx, ILD_TRANSPARENT); - else - ShortcutIcon = ImageList_GetIcon(ShellSmallIconList, s_imgListIdx, ILD_TRANSPARENT); - } else - ShortcutIcon = NULL; - - if (NULL == ShortcutIcon - || ! GetIconInfo(ShortcutIcon, &ShortcutIconInfo) - || 0 == GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo)) - { - return NULL; - } + if (s_imgListIdx != -1) + ShortcutIcon = ImageList_GetIcon(shell_imagelists[type], s_imgListIdx, ILD_TRANSPARENT); + else + ShortcutIcon = NULL; + + if (NULL == ShortcutIcon || ! GetIconInfo(ShortcutIcon, &ShortcutIconInfo) + || 0 == GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo)) + { + return NULL; + }
TargetIconInfo = SourceIconInfo; TargetIconInfo.hbmMask = NULL; @@ -308,7 +303,8 @@ fail: * appends an icon pair to the end of the cache */ static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags) -{ LPSIC_ENTRY lpsice; +{ + LPSIC_ENTRY lpsice; INT ret, index, index1; WCHAR path[MAX_PATH]; TRACE("%s %i %p %p\n", debugstr_w(sSourceFile), dwSourceIndex, hSmallIcon ,hBigIcon); @@ -333,8 +329,8 @@ static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallI } else { - index = ImageList_AddIcon (ShellSmallIconList, hSmallIcon); - index1= ImageList_AddIcon (ShellBigIconList, hBigIcon); + index = ImageList_AddIcon(shell_imagelists[SHIL_SMALL], hSmallIcon); + index1 = ImageList_AddIcon(shell_imagelists[SHIL_LARGE], hBigIcon);
if (index!=index1) { @@ -350,12 +346,9 @@ static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallI
static BOOL get_imagelist_icon_size(int list, SIZE *size) { - HIMAGELIST image_list; - if (list < SHIL_LARGE || list > SHIL_SMALL) return FALSE; - image_list = (list == SHIL_LARGE) ? ShellBigIconList : ShellSmallIconList;
- return ImageList_GetIconSize( image_list, &size->cx, &size->cy ); + return ImageList_GetIconSize( shell_imagelists[list], &size->cx, &size->cy ); }
/**************************************************************************** @@ -364,7 +357,7 @@ static BOOL get_imagelist_icon_size(int list, SIZE *size) * NOTES * gets small/big icon by number from a file */ -static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags) +static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD flags) { HICON hiconLarge=0; HICON hiconSmall=0; @@ -384,10 +377,11 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags) return -1; }
- if (0 != (dwFlags & GIL_FORSHORTCUT)) - { - hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE); - hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE); + if (flags & GIL_FORSHORTCUT) + { + hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, SHIL_LARGE); + hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, SHIL_SMALL); + if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut) { DestroyIcon( hiconLarge ); @@ -400,14 +394,14 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags) WARN("Failed to create shortcut overlaid icons\n"); if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut); if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut); - dwFlags &= ~ GIL_FORSHORTCUT; + flags &= ~ GIL_FORSHORTCUT; } - } + }
- ret = SIC_IconAppend( sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags ); - DestroyIcon( hiconLarge ); - DestroyIcon( hiconSmall ); - return ret; + ret = SIC_IconAppend( sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, flags ); + DestroyIcon( hiconLarge ); + DestroyIcon( hiconSmall ); + return ret; }
static int get_shell_icon_size(void) @@ -436,6 +430,7 @@ static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context HICON hSm, hLg; int cx_small, cy_small; int cx_large, cy_large; + unsigned int i;
if (!IsProcessDPIAware()) { @@ -460,11 +455,11 @@ static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context return(FALSE); }
- ShellSmallIconList = ImageList_Create(cx_small,cy_small,ILC_COLOR32|ILC_MASK,0,0x20); - ShellBigIconList = ImageList_Create(cx_large,cy_large,ILC_COLOR32|ILC_MASK,0,0x20); + shell_imagelists[SHIL_SMALL] = ImageList_Create(cx_small, cy_small, ILC_COLOR32 | ILC_MASK, 0, 0x20); + shell_imagelists[SHIL_LARGE] = ImageList_Create(cx_large, cy_large, ILC_COLOR32 | ILC_MASK, 0, 0x20);
- ImageList_SetBkColor(ShellSmallIconList, CLR_NONE); - ImageList_SetBkColor(ShellBigIconList, CLR_NONE); + for (i = 0; i < ARRAY_SIZE(shell_imagelists); i++) + ImageList_SetBkColor(shell_imagelists[i], CLR_NONE);
/* Load the document icon, which is used as the default if an icon isn't found. */ hSm = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), @@ -480,10 +475,10 @@ static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context
SIC_IconAppend (swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0); SIC_IconAppend (swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0); - - TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
- return TRUE; + TRACE("small list=%p, large list=%p\n", shell_imagelists[SHIL_SMALL], shell_imagelists[SHIL_LARGE]); + + return TRUE; } /************************************************************************* * SIC_Destroy @@ -499,19 +494,22 @@ static INT CALLBACK sic_free( LPVOID ptr, LPVOID lparam )
void SIC_Destroy(void) { - TRACE("\n"); + unsigned int i;
- EnterCriticalSection(&SHELL32_SicCS); + TRACE("\n");
- if (sic_hdpa) DPA_DestroyCallback(sic_hdpa, sic_free, NULL ); + EnterCriticalSection(&SHELL32_SicCS);
- if (ShellSmallIconList) - ImageList_Destroy(ShellSmallIconList); - if (ShellBigIconList) - ImageList_Destroy(ShellBigIconList); + if (sic_hdpa) DPA_DestroyCallback(sic_hdpa, sic_free, NULL );
- LeaveCriticalSection(&SHELL32_SicCS); - DeleteCriticalSection(&SHELL32_SicCS); + for (i = 0; i < ARRAY_SIZE(shell_imagelists); i++) + { + if (shell_imagelists[i]) + ImageList_Destroy(shell_imagelists[i]); + } + + LeaveCriticalSection(&SHELL32_SicCS); + DeleteCriticalSection(&SHELL32_SicCS); }
/***************************************************************************** @@ -621,14 +619,16 @@ static int SIC_LoadOverlayIcon(int icon_idx) * imglist[1|2] [OUT] pointer which receives imagelist handles * */ -BOOL WINAPI Shell_GetImageLists(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList) +BOOL WINAPI Shell_GetImageLists(HIMAGELIST *large_list, HIMAGELIST *small_list) { - TRACE("(%p,%p)\n",lpBigList,lpSmallList); + TRACE("(%p, %p)\n", large_list, small_list); + InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL ); - if (lpBigList) *lpBigList = ShellBigIconList; - if (lpSmallList) *lpSmallList = ShellSmallIconList; + if (large_list) *large_list = shell_imagelists[SHIL_LARGE]; + if (small_list) *small_list = shell_imagelists[SHIL_SMALL]; return TRUE; } + /************************************************************************* * PidlToSicIndex [INTERNAL] *
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/shell32/iconcache.c | 162 ++++++++++++++++++++++++----------------------- 1 file changed, 83 insertions(+), 79 deletions(-)
diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c index 562f9b243c..e62e872f14 100644 --- a/dlls/shell32/iconcache.c +++ b/dlls/shell32/iconcache.c @@ -298,50 +298,51 @@ fail:
/***************************************************************************** * SIC_IconAppend [internal] - * - * NOTES - * appends an icon pair to the end of the cache */ -static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags) +static INT SIC_IconAppend (const WCHAR *sourcefile, INT src_index, HICON *hicons, DWORD flags) { - LPSIC_ENTRY lpsice; - INT ret, index, index1; - WCHAR path[MAX_PATH]; - TRACE("%s %i %p %p\n", debugstr_w(sSourceFile), dwSourceIndex, hSmallIcon ,hBigIcon); + INT ret, index, index1; + WCHAR path[MAX_PATH]; + SIC_ENTRY *entry; + unsigned int i;
- lpsice = SHAlloc(sizeof(SIC_ENTRY)); + TRACE("%s %i %p %#x\n", debugstr_w(sourcefile), src_index, hicons, flags);
- GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL); - lpsice->sSourceFile = heap_alloc( (strlenW(path)+1)*sizeof(WCHAR) ); - strcpyW( lpsice->sSourceFile, path ); + entry = SHAlloc(sizeof(*entry));
- lpsice->dwSourceIndex = dwSourceIndex; - lpsice->dwFlags = dwFlags; + GetFullPathNameW(sourcefile, MAX_PATH, path, NULL); + entry->sSourceFile = heap_alloc( (strlenW(path)+1)*sizeof(WCHAR) ); + strcpyW( entry->sSourceFile, path );
- EnterCriticalSection(&SHELL32_SicCS); + entry->dwSourceIndex = src_index; + entry->dwFlags = flags;
- index = DPA_InsertPtr(sic_hdpa, 0x7fff, lpsice); - if ( INVALID_INDEX == index ) - { - heap_free(lpsice->sSourceFile); - SHFree(lpsice); - ret = INVALID_INDEX; - } - else - { - index = ImageList_AddIcon(shell_imagelists[SHIL_SMALL], hSmallIcon); - index1 = ImageList_AddIcon(shell_imagelists[SHIL_LARGE], hBigIcon); + EnterCriticalSection(&SHELL32_SicCS);
- if (index!=index1) - { - FIXME("iconlists out of sync 0x%x 0x%x\n", index, index1); - } - lpsice->dwListIndex = index; - ret = lpsice->dwListIndex; - } + index = DPA_InsertPtr(sic_hdpa, 0x7fff, entry); + if ( INVALID_INDEX == index ) + { + heap_free(entry->sSourceFile); + SHFree(entry); + ret = INVALID_INDEX; + } + else + { + index = -1; + for (i = 0; i < ARRAY_SIZE(shell_imagelists); i++) + { + index1 = ImageList_AddIcon(shell_imagelists[i], hicons[i]); + if (index != -1 && index1 != index) + WARN("Imagelists out of sync, list %d.\n", i); + index = index1; + }
- LeaveCriticalSection(&SHELL32_SicCS); - return ret; + entry->dwListIndex = index; + ret = entry->dwListIndex; + } + + LeaveCriticalSection(&SHELL32_SicCS); + return ret; }
static BOOL get_imagelist_icon_size(int list, SIZE *size) @@ -355,52 +356,55 @@ static BOOL get_imagelist_icon_size(int list, SIZE *size) * SIC_LoadIcon [internal] * * NOTES - * gets small/big icon by number from a file + * gets icons by index from the file */ -static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD flags) +static INT SIC_LoadIcon (const WCHAR *sourcefile, INT index, DWORD flags) { - HICON hiconLarge=0; - HICON hiconSmall=0; - HICON hiconLargeShortcut; - HICON hiconSmallShortcut; - int ret; - SIZE size; - - get_imagelist_icon_size( SHIL_LARGE, &size ); - PrivateExtractIconsW( sSourceFile, dwSourceIndex, size.cx, size.cy, &hiconLarge, 0, 1, 0 ); - get_imagelist_icon_size( SHIL_SMALL, &size ); - PrivateExtractIconsW( sSourceFile, dwSourceIndex, size.cx, size.cy, &hiconSmall, 0, 1, 0 ); - - if ( !hiconLarge || !hiconSmall) - { - WARN("failure loading icon %i from %s (%p %p)\n", dwSourceIndex, debugstr_w(sSourceFile), hiconLarge, hiconSmall); - return -1; - } + HICON hicons[SHIL_SMALL+1] = { 0 }; + HICON hshortcuts[ARRAY_SIZE(hicons)] = { 0 }; + unsigned int i; + SIZE size; + int ret; + + for (i = 0; i < ARRAY_SIZE(hicons); i++) + { + get_imagelist_icon_size( i, &size ); + if (!PrivateExtractIconsW( sourcefile, index, size.cx, size.cy, &hicons[i], 0, 1, 0 )) + WARN("Failed to load icon %d from %s.\n", index, debugstr_w(sourcefile)); + }
if (flags & GIL_FORSHORTCUT) { - hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, SHIL_LARGE); - hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, SHIL_SMALL); + BOOL failed = FALSE;
- if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut) - { - DestroyIcon( hiconLarge ); - DestroyIcon( hiconSmall ); - hiconLarge = hiconLargeShortcut; - hiconSmall = hiconSmallShortcut; - } - else - { - WARN("Failed to create shortcut overlaid icons\n"); - if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut); - if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut); - flags &= ~ GIL_FORSHORTCUT; - } + for (i = 0; i < ARRAY_SIZE(hshortcuts); i++) + { + if (!(hshortcuts[i] = SIC_OverlayShortcutImage(hicons[i], i))) + { + WARN("Failed to create shortcut overlaid icons.\n"); + failed = TRUE; + } + } + + if (failed) + { + for (i = 0; i < ARRAY_SIZE(hshortcuts); i++) + DestroyIcon(hshortcuts[i]); + flags &= ~GIL_FORSHORTCUT; + } + else + { + for (i = 0; i < ARRAY_SIZE(hicons); i++) + { + DestroyIcon(hicons[i]); + hicons[i] = hshortcuts[i]; + } + } }
- ret = SIC_IconAppend( sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, flags ); - DestroyIcon( hiconLarge ); - DestroyIcon( hiconSmall ); + ret = SIC_IconAppend( sourcefile, index, hicons, flags ); + for (i = 0; i < ARRAY_SIZE(hicons); i++) + DestroyIcon(hicons[i]); return ret; }
@@ -427,7 +431,7 @@ static int get_shell_icon_size(void) */ static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context ) { - HICON hSm, hLg; + HICON hicons[SHIL_SMALL+1]; int cx_small, cy_small; int cx_large, cy_large; unsigned int i; @@ -462,19 +466,19 @@ static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context ImageList_SetBkColor(shell_imagelists[i], CLR_NONE);
/* Load the document icon, which is used as the default if an icon isn't found. */ - hSm = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), + hicons[SHIL_SMALL] = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), IMAGE_ICON, cx_small, cy_small, LR_SHARED); - hLg = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), + hicons[SHIL_LARGE] = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), IMAGE_ICON, cx_large, cy_large, LR_SHARED);
- if (!hSm || !hLg) + if (!hicons[SHIL_SMALL] || !hicons[SHIL_LARGE]) { FIXME("Failed to load IDI_SHELL_DOCUMENT icon!\n"); return FALSE; }
- SIC_IconAppend (swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0); - SIC_IconAppend (swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0); + SIC_IconAppend (swShell32Name, IDI_SHELL_DOCUMENT-1, hicons, 0); + SIC_IconAppend (swShell32Name, -IDI_SHELL_DOCUMENT, hicons, 0);
TRACE("small list=%p, large list=%p\n", shell_imagelists[SHIL_SMALL], shell_imagelists[SHIL_LARGE]);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/shell32/iconcache.c | 27 +++++++++++++++++++++++++++ dlls/shell32/shellord.c | 28 ---------------------------- 2 files changed, 27 insertions(+), 28 deletions(-)
diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c index e62e872f14..23e820322e 100644 --- a/dlls/shell32/iconcache.c +++ b/dlls/shell32/iconcache.c @@ -1022,3 +1022,30 @@ HRESULT WINAPI SHGetStockIconInfo(SHSTOCKICONID id, UINT flags, SHSTOCKICONINFO
return S_OK; } + +/************************************************************************* + * SHGetImageList (SHELL32.727) + * + * Returns a copy of a shell image list. + * + * NOTES + * Windows XP features 4 sizes of image list, and Vista 5. Wine currently + * only supports the traditional small and large image lists, so requests + * for the others will currently fail. + */ +HRESULT WINAPI SHGetImageList(int iImageList, REFIID riid, void **ppv) +{ + /* Wine currently only maintains large and small image lists */ + if ((iImageList != SHIL_LARGE) && (iImageList != SHIL_SMALL) && (iImageList != SHIL_SYSSMALL)) + { + FIXME("Unsupported image list %i requested\n", iImageList); + return E_FAIL; + } + + InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL ); + + if (iImageList == SHIL_SYSSMALL) + iImageList = SHIL_SMALL; + + return HIMAGELIST_QueryInterface(shell_imagelists[iImageList], riid, ppv); +} diff --git a/dlls/shell32/shellord.c b/dlls/shell32/shellord.c index 058e57e5b5..6fc49dcd59 100644 --- a/dlls/shell32/shellord.c +++ b/dlls/shell32/shellord.c @@ -2133,31 +2133,3 @@ BOOL WINAPI LinkWindow_UnregisterClass(void) void WINAPI SHFlushSFCache(void) { } - -/************************************************************************* - * SHGetImageList (SHELL32.727) - * - * Returns a copy of a shell image list. - * - * NOTES - * Windows XP features 4 sizes of image list, and Vista 5. Wine currently - * only supports the traditional small and large image lists, so requests - * for the others will currently fail. - */ -HRESULT WINAPI SHGetImageList(int iImageList, REFIID riid, void **ppv) -{ - HIMAGELIST hLarge, hSmall; - HIMAGELIST hNew; - - /* Wine currently only maintains large and small image lists */ - if ((iImageList != SHIL_LARGE) && (iImageList != SHIL_SMALL) && (iImageList != SHIL_SYSSMALL)) - { - FIXME("Unsupported image list %i requested\n", iImageList); - return E_FAIL; - } - - Shell_GetImageLists(&hLarge, &hSmall); - hNew = (iImageList == SHIL_LARGE) ? hLarge : hSmall; - - return HIMAGELIST_QueryInterface(hNew, riid, ppv); -}
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/shell32/iconcache.c | 87 +++++++++++++++++++++--------------------- dlls/shell32/tests/shelllink.c | 2 +- 2 files changed, 45 insertions(+), 44 deletions(-)
diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c index 23e820322e..c6baf60292 100644 --- a/dlls/shell32/iconcache.c +++ b/dlls/shell32/iconcache.c @@ -61,7 +61,7 @@ typedef struct
static HDPA sic_hdpa; static INIT_ONCE sic_init_once = INIT_ONCE_STATIC_INIT; -static HIMAGELIST shell_imagelists[SHIL_SMALL+1]; +static HIMAGELIST shell_imagelists[SHIL_EXTRALARGE+1];
static CRITICAL_SECTION SHELL32_SicCS; static CRITICAL_SECTION_DEBUG critsect_debug = @@ -347,7 +347,7 @@ static INT SIC_IconAppend (const WCHAR *sourcefile, INT src_index, HICON *hicons
static BOOL get_imagelist_icon_size(int list, SIZE *size) { - if (list < SHIL_LARGE || list > SHIL_SMALL) return FALSE; + if (list < 0 || list >= ARRAY_SIZE(shell_imagelists)) return FALSE;
return ImageList_GetIconSize( shell_imagelists[list], &size->cx, &size->cy ); } @@ -360,7 +360,7 @@ static BOOL get_imagelist_icon_size(int list, SIZE *size) */ static INT SIC_LoadIcon (const WCHAR *sourcefile, INT index, DWORD flags) { - HICON hicons[SHIL_SMALL+1] = { 0 }; + HICON hicons[ARRAY_SIZE(shell_imagelists)] = { 0 }; HICON hshortcuts[ARRAY_SIZE(hicons)] = { 0 }; unsigned int i; SIZE size; @@ -431,59 +431,61 @@ static int get_shell_icon_size(void) */ static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context ) { - HICON hicons[SHIL_SMALL+1]; - int cx_small, cy_small; - int cx_large, cy_large; - unsigned int i; + HICON hicons[ARRAY_SIZE(shell_imagelists)]; + SIZE sizes[ARRAY_SIZE(shell_imagelists)]; + BOOL failed = FALSE; + unsigned int i;
- if (!IsProcessDPIAware()) - { - cx_large = cy_large = get_shell_icon_size(); - cx_small = GetSystemMetrics( SM_CXSMICON ); - cy_small = GetSystemMetrics( SM_CYSMICON ); - } - else - { - cx_large = GetSystemMetrics( SM_CXICON ); - cy_large = GetSystemMetrics( SM_CYICON ); - cx_small = cx_large / 2; - cy_small = cy_large / 2; - } + if (!IsProcessDPIAware()) + { + sizes[SHIL_LARGE].cx = sizes[SHIL_LARGE].cy = get_shell_icon_size(); + sizes[SHIL_SMALL].cx = GetSystemMetrics( SM_CXSMICON ); + sizes[SHIL_SMALL].cy = GetSystemMetrics( SM_CYSMICON ); + } + else + { + sizes[SHIL_LARGE].cx = GetSystemMetrics( SM_CXICON ); + sizes[SHIL_LARGE].cy = GetSystemMetrics( SM_CYICON ); + sizes[SHIL_SMALL].cx = sizes[SHIL_LARGE].cx / 2; + sizes[SHIL_SMALL].cy = sizes[SHIL_LARGE].cy / 2; + }
- TRACE("large %dx%d small %dx%d\n", cx_large, cy_large, cx_small, cx_small); + sizes[SHIL_EXTRALARGE].cx = (GetSystemMetrics( SM_CXICON ) * 3) / 2; + sizes[SHIL_EXTRALARGE].cy = (GetSystemMetrics( SM_CYICON ) * 3) / 2;
- sic_hdpa = DPA_Create(16); + TRACE("large %dx%d small %dx%d\n", sizes[SHIL_LARGE].cx, sizes[SHIL_LARGE].cy, sizes[SHIL_SMALL].cx, sizes[SHIL_SMALL].cy);
- if (!sic_hdpa) - { - return(FALSE); - } - - shell_imagelists[SHIL_SMALL] = ImageList_Create(cx_small, cy_small, ILC_COLOR32 | ILC_MASK, 0, 0x20); - shell_imagelists[SHIL_LARGE] = ImageList_Create(cx_large, cy_large, ILC_COLOR32 | ILC_MASK, 0, 0x20); + sic_hdpa = DPA_Create(16); + if (!sic_hdpa) + return(FALSE);
- for (i = 0; i < ARRAY_SIZE(shell_imagelists); i++) - ImageList_SetBkColor(shell_imagelists[i], CLR_NONE); + for (i = 0; i < ARRAY_SIZE(shell_imagelists); i++) + { + shell_imagelists[i] = ImageList_Create(sizes[i].cx, sizes[i].cy, ILC_COLOR32 | ILC_MASK, 0, 0x20); + ImageList_SetBkColor(shell_imagelists[i], CLR_NONE);
/* Load the document icon, which is used as the default if an icon isn't found. */ - hicons[SHIL_SMALL] = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), - IMAGE_ICON, cx_small, cy_small, LR_SHARED); - hicons[SHIL_LARGE] = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), - IMAGE_ICON, cx_large, cy_large, LR_SHARED); - - if (!hicons[SHIL_SMALL] || !hicons[SHIL_LARGE]) + if (!(hicons[i] = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), + IMAGE_ICON, sizes[i].cx, sizes[i].cy, LR_SHARED))) { - FIXME("Failed to load IDI_SHELL_DOCUMENT icon!\n"); - return FALSE; + failed = TRUE; } + }
- SIC_IconAppend (swShell32Name, IDI_SHELL_DOCUMENT-1, hicons, 0); - SIC_IconAppend (swShell32Name, -IDI_SHELL_DOCUMENT, hicons, 0); + if (failed) + { + FIXME("Failed to load IDI_SHELL_DOCUMENT icon!\n"); + return FALSE; + } + + SIC_IconAppend(swShell32Name, IDI_SHELL_DOCUMENT - 1, hicons, 0); + SIC_IconAppend(swShell32Name, -IDI_SHELL_DOCUMENT, hicons, 0);
TRACE("small list=%p, large list=%p\n", shell_imagelists[SHIL_SMALL], shell_imagelists[SHIL_LARGE]);
return TRUE; } + /************************************************************************* * SIC_Destroy * @@ -1035,8 +1037,7 @@ HRESULT WINAPI SHGetStockIconInfo(SHSTOCKICONID id, UINT flags, SHSTOCKICONINFO */ HRESULT WINAPI SHGetImageList(int iImageList, REFIID riid, void **ppv) { - /* Wine currently only maintains large and small image lists */ - if ((iImageList != SHIL_LARGE) && (iImageList != SHIL_SMALL) && (iImageList != SHIL_SYSSMALL)) + if (iImageList < 0 || iImageList > SHIL_SYSSMALL) { FIXME("Unsupported image list %i requested\n", iImageList); return E_FAIL; diff --git a/dlls/shell32/tests/shelllink.c b/dlls/shell32/tests/shelllink.c index a9288cc798..2486c96984 100644 --- a/dlls/shell32/tests/shelllink.c +++ b/dlls/shell32/tests/shelllink.c @@ -1417,7 +1417,7 @@ static void test_SHGetImageList(void) for (i = 0; i <= SHIL_LAST; i++) { hr = SHGetImageList( i, &IID_IImageList, (void **)&list ); - todo_wine_if(i == SHIL_EXTRALARGE || i == SHIL_JUMBO) + todo_wine_if(i == SHIL_JUMBO) ok( hr == S_OK || broken( i == SHIL_JUMBO && hr == E_INVALIDARG ), /* XP and 2003 */ "%d: got %08x\n", i, hr );
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/shell32/iconcache.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c index c6baf60292..f26ff0e49d 100644 --- a/dlls/shell32/iconcache.c +++ b/dlls/shell32/iconcache.c @@ -61,7 +61,7 @@ typedef struct
static HDPA sic_hdpa; static INIT_ONCE sic_init_once = INIT_ONCE_STATIC_INIT; -static HIMAGELIST shell_imagelists[SHIL_EXTRALARGE+1]; +static HIMAGELIST shell_imagelists[SHIL_SYSSMALL+1];
static CRITICAL_SECTION SHELL32_SicCS; static CRITICAL_SECTION_DEBUG critsect_debug = @@ -452,6 +452,8 @@ static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context
sizes[SHIL_EXTRALARGE].cx = (GetSystemMetrics( SM_CXICON ) * 3) / 2; sizes[SHIL_EXTRALARGE].cy = (GetSystemMetrics( SM_CYICON ) * 3) / 2; + sizes[SHIL_SYSSMALL].cx = GetSystemMetrics( SM_CXSMICON ); + sizes[SHIL_SYSSMALL].cy = GetSystemMetrics( SM_CYSMICON );
TRACE("large %dx%d small %dx%d\n", sizes[SHIL_LARGE].cx, sizes[SHIL_LARGE].cy, sizes[SHIL_SMALL].cx, sizes[SHIL_SMALL].cy);
@@ -1044,9 +1046,5 @@ HRESULT WINAPI SHGetImageList(int iImageList, REFIID riid, void **ppv) }
InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL ); - - if (iImageList == SHIL_SYSSMALL) - iImageList = SHIL_SMALL; - return HIMAGELIST_QueryInterface(shell_imagelists[iImageList], riid, ppv); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/shell32/iconcache.c | 10 +++++----- dlls/shell32/tests/shelllink.c | 4 +--- 2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c index f26ff0e49d..d55bde9bd7 100644 --- a/dlls/shell32/iconcache.c +++ b/dlls/shell32/iconcache.c @@ -61,7 +61,7 @@ typedef struct
static HDPA sic_hdpa; static INIT_ONCE sic_init_once = INIT_ONCE_STATIC_INIT; -static HIMAGELIST shell_imagelists[SHIL_SYSSMALL+1]; +static HIMAGELIST shell_imagelists[SHIL_LAST+1];
static CRITICAL_SECTION SHELL32_SicCS; static CRITICAL_SECTION_DEBUG critsect_debug = @@ -454,6 +454,7 @@ static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context sizes[SHIL_EXTRALARGE].cy = (GetSystemMetrics( SM_CYICON ) * 3) / 2; sizes[SHIL_SYSSMALL].cx = GetSystemMetrics( SM_CXSMICON ); sizes[SHIL_SYSSMALL].cy = GetSystemMetrics( SM_CYSMICON ); + sizes[SHIL_JUMBO].cx = sizes[SHIL_JUMBO].cy = 256;
TRACE("large %dx%d small %dx%d\n", sizes[SHIL_LARGE].cx, sizes[SHIL_LARGE].cy, sizes[SHIL_SMALL].cx, sizes[SHIL_SMALL].cy);
@@ -1039,11 +1040,10 @@ HRESULT WINAPI SHGetStockIconInfo(SHSTOCKICONID id, UINT flags, SHSTOCKICONINFO */ HRESULT WINAPI SHGetImageList(int iImageList, REFIID riid, void **ppv) { - if (iImageList < 0 || iImageList > SHIL_SYSSMALL) - { - FIXME("Unsupported image list %i requested\n", iImageList); + TRACE("(%d, %s, %p)\n", iImageList, debugstr_guid(riid), ppv); + + if (iImageList < 0 || iImageList > SHIL_LAST) return E_FAIL; - }
InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL ); return HIMAGELIST_QueryInterface(shell_imagelists[iImageList], riid, ppv); diff --git a/dlls/shell32/tests/shelllink.c b/dlls/shell32/tests/shelllink.c index 2486c96984..1e07090dc4 100644 --- a/dlls/shell32/tests/shelllink.c +++ b/dlls/shell32/tests/shelllink.c @@ -1417,9 +1417,7 @@ static void test_SHGetImageList(void) for (i = 0; i <= SHIL_LAST; i++) { hr = SHGetImageList( i, &IID_IImageList, (void **)&list ); - todo_wine_if(i == SHIL_JUMBO) - ok( hr == S_OK || - broken( i == SHIL_JUMBO && hr == E_INVALIDARG ), /* XP and 2003 */ + ok( hr == S_OK || broken( i == SHIL_JUMBO && hr == E_INVALIDARG ), /* XP and 2003 */ "%d: got %08x\n", i, hr ); if (FAILED(hr)) continue; IImageList_GetIconSize( list, &width, &height );