shell32: Delay initialization of the icon cache until needed.

This commit is contained in:
Alexandre Julliard 2013-10-17 18:01:04 +02:00
parent 4c6e039aa1
commit 116e33d50a
3 changed files with 61 additions and 65 deletions

View File

@ -59,7 +59,8 @@ typedef struct
DWORD dwAccessTime; DWORD dwAccessTime;
} SIC_ENTRY, * LPSIC_ENTRY; } SIC_ENTRY, * LPSIC_ENTRY;
static HDPA sic_hdpa = 0; static HDPA sic_hdpa;
static INIT_ONCE sic_init_once = INIT_ONCE_STATIC_INIT;
static CRITICAL_SECTION SHELL32_SicCS; static CRITICAL_SECTION SHELL32_SicCS;
static CRITICAL_SECTION_DEBUG critsect_debug = static CRITICAL_SECTION_DEBUG critsect_debug =
@ -336,55 +337,10 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags); return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags);
} }
/*****************************************************************************
* SIC_GetIconIndex [internal]
*
* Parameters
* sSourceFile [IN] filename of file containing the icon
* index [IN] index/resID (negated) in this file
*
* NOTES
* look in the cache for a proper icon. if not available the icon is taken
* from the file and cached
*/
INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
{
SIC_ENTRY sice;
INT ret, index = INVALID_INDEX;
WCHAR path[MAX_PATH];
TRACE("%s %i\n", debugstr_w(sSourceFile), dwSourceIndex);
GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL);
sice.sSourceFile = path;
sice.dwSourceIndex = dwSourceIndex;
sice.dwFlags = dwFlags;
EnterCriticalSection(&SHELL32_SicCS);
if (NULL != DPA_GetPtr (sic_hdpa, 0))
{
/* search linear from position 0*/
index = DPA_Search (sic_hdpa, &sice, 0, SIC_CompareEntries, 0, 0);
}
if ( INVALID_INDEX == index )
{
ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags);
}
else
{
TRACE("-- found\n");
ret = ((LPSIC_ENTRY)DPA_GetPtr(sic_hdpa, index))->dwListIndex;
}
LeaveCriticalSection(&SHELL32_SicCS);
return ret;
}
/***************************************************************************** /*****************************************************************************
* SIC_Initialize [internal] * SIC_Initialize [internal]
*/ */
BOOL SIC_Initialize(void) static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context )
{ {
HICON hSm, hLg; HICON hSm, hLg;
int cx_small, cy_small; int cx_small, cy_small;
@ -397,9 +353,6 @@ BOOL SIC_Initialize(void)
TRACE("\n"); TRACE("\n");
if (sic_hdpa) /* already initialized?*/
return TRUE;
sic_hdpa = DPA_Create(16); sic_hdpa = DPA_Create(16);
if (!sic_hdpa) if (!sic_hdpa)
@ -452,16 +405,61 @@ void SIC_Destroy(void)
if (sic_hdpa) DPA_DestroyCallback(sic_hdpa, sic_free, NULL ); if (sic_hdpa) DPA_DestroyCallback(sic_hdpa, sic_free, NULL );
sic_hdpa = NULL;
ImageList_Destroy(ShellSmallIconList); ImageList_Destroy(ShellSmallIconList);
ShellSmallIconList = 0;
ImageList_Destroy(ShellBigIconList); ImageList_Destroy(ShellBigIconList);
ShellBigIconList = 0;
LeaveCriticalSection(&SHELL32_SicCS); LeaveCriticalSection(&SHELL32_SicCS);
DeleteCriticalSection(&SHELL32_SicCS); DeleteCriticalSection(&SHELL32_SicCS);
} }
/*****************************************************************************
* SIC_GetIconIndex [internal]
*
* Parameters
* sSourceFile [IN] filename of file containing the icon
* index [IN] index/resID (negated) in this file
*
* NOTES
* look in the cache for a proper icon. if not available the icon is taken
* from the file and cached
*/
INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
{
SIC_ENTRY sice;
INT ret, index = INVALID_INDEX;
WCHAR path[MAX_PATH];
TRACE("%s %i\n", debugstr_w(sSourceFile), dwSourceIndex);
GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL);
sice.sSourceFile = path;
sice.dwSourceIndex = dwSourceIndex;
sice.dwFlags = dwFlags;
InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL );
EnterCriticalSection(&SHELL32_SicCS);
if (NULL != DPA_GetPtr (sic_hdpa, 0))
{
/* search linear from position 0*/
index = DPA_Search (sic_hdpa, &sice, 0, SIC_CompareEntries, 0, 0);
}
if ( INVALID_INDEX == index )
{
ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags);
}
else
{
TRACE("-- found\n");
ret = ((LPSIC_ENTRY)DPA_GetPtr(sic_hdpa, index))->dwListIndex;
}
LeaveCriticalSection(&SHELL32_SicCS);
return ret;
}
/***************************************************************************** /*****************************************************************************
* SIC_LoadOverlayIcon [internal] * SIC_LoadOverlayIcon [internal]
* *
@ -509,6 +507,8 @@ static int SIC_LoadOverlayIcon(int icon_idx)
RegCloseKey(hKeyShellIcons); RegCloseKey(hKeyShellIcons);
} }
InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL );
return SIC_LoadIcon(iconPath, iconIdx, 0); return SIC_LoadIcon(iconPath, iconIdx, 0);
} }
@ -520,15 +520,12 @@ static int SIC_LoadOverlayIcon(int icon_idx)
* *
*/ */
BOOL WINAPI Shell_GetImageLists(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList) BOOL WINAPI Shell_GetImageLists(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList)
{ TRACE("(%p,%p)\n",lpBigList,lpSmallList); {
if (lpBigList) TRACE("(%p,%p)\n",lpBigList,lpSmallList);
{ *lpBigList = ShellBigIconList; InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL );
} if (lpBigList) *lpBigList = ShellBigIconList;
if (lpSmallList) if (lpSmallList) *lpSmallList = ShellSmallIconList;
{ *lpSmallList = ShellSmallIconList; return TRUE;
}
return TRUE;
} }
/************************************************************************* /*************************************************************************
* PidlToSicIndex [INTERNAL] * PidlToSicIndex [INTERNAL]
@ -557,6 +554,8 @@ BOOL PidlToSicIndex (
TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small"); TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small");
InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL );
if (SUCCEEDED (IShellFolder_GetUIObjectOf(sh, 0, 1, &pidl, &IID_IExtractIconW, 0, (void **)&ei))) if (SUCCEEDED (IShellFolder_GetUIObjectOf(sh, 0, 1, &pidl, &IID_IExtractIconW, 0, (void **)&ei)))
{ {
if (SUCCEEDED(IExtractIconW_GetIconLocation(ei, uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags))) if (SUCCEEDED(IExtractIconW_GetIconLocation(ei, uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags)))

View File

@ -1273,8 +1273,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
swShell32Name[MAX_PATH - 1] = '\0'; swShell32Name[MAX_PATH - 1] = '\0';
InitCommonControlsEx(NULL); InitCommonControlsEx(NULL);
SIC_Initialize();
InitChangeNotifications(); InitChangeNotifications();
break; break;

View File

@ -47,7 +47,6 @@ extern HIMAGELIST ShellBigIconList DECLSPEC_HIDDEN;
/* Iconcache */ /* Iconcache */
#define INVALID_INDEX -1 #define INVALID_INDEX -1
BOOL SIC_Initialize(void) DECLSPEC_HIDDEN;
void SIC_Destroy(void) DECLSPEC_HIDDEN; void SIC_Destroy(void) DECLSPEC_HIDDEN;
BOOL PidlToSicIndex (IShellFolder * sh, LPCITEMIDLIST pidl, BOOL bBigIcon, UINT uFlags, int * pIndex) DECLSPEC_HIDDEN; BOOL PidlToSicIndex (IShellFolder * sh, LPCITEMIDLIST pidl, BOOL bBigIcon, UINT uFlags, int * pIndex) DECLSPEC_HIDDEN;
INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags ) DECLSPEC_HIDDEN; INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags ) DECLSPEC_HIDDEN;