{
0, 0, &SHELL32_SicCS,
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
- 0, 0, { 0, (DWORD)(__FILE__ ": SHELL32_SicCS") }
+ 0, 0, { (DWORD_PTR)(__FILE__ ": SHELL32_SicCS") }
};
static CRITICAL_SECTION SHELL32_SicCS = { &critsect_debug, -1, 0, 0, 0, 0 };
return 0;
}
+/* declare SIC_LoadOverlayIcon() */
+static int SIC_LoadOverlayIcon(int idx);
+
/*****************************************************************************
* SIC_OverlayShortcutImage [internal]
*
* Creates a new icon as a copy of the passed-in icon, overlayed with a
* shortcut image.
*/
-static HICON SIC_OverlayShortcutImage(HICON SourceIcon)
+static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
{ ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo;
HICON ShortcutIcon, TargetIcon;
BITMAP SourceBitmapInfo, ShortcutBitmapInfo;
OldShortcutBitmap = NULL,
OldTargetBitmap = NULL;
+ static int s_imgListIdx = -1;
+
/* Get information about the source icon and shortcut overlay */
if (! GetIconInfo(SourceIcon, &SourceIconInfo)
|| 0 == GetObjectW(SourceIconInfo.hbmColor, sizeof(BITMAP), &SourceBitmapInfo))
{
return NULL;
}
- ShortcutIcon = LoadImageW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_SHORTCUT),
- IMAGE_ICON, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmWidth,
- LR_SHARED);
+
+ /* search for the shortcut icon only once */
+ if (s_imgListIdx == -1)
+ s_imgListIdx = SIC_LoadOverlayIcon(- IDI_SHELL_SHORTCUT);
+ /* FIXME should use icon index 29 instead of the
+ 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))
if (0 != (dwFlags & GIL_FORSHORTCUT))
{
- hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge);
- hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall);
+ hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE);
+ hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE);
if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut)
{
hiconLarge = hiconLargeShortcut;
if ( INVALID_INDEX == index )
{
- ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags);
+ ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags);
}
else
{
}
/*****************************************************************************
* SIC_Initialize [internal]
- *
- * NOTES
- * hack to load the resources from the shell32.dll under a different dll name
- * will be removed when the resource-compiler is ready
*/
BOOL SIC_Initialize(void)
{
HICON hSm, hLg;
- UINT index;
int cx_small, cy_small;
int cx_large, cy_large;
return(FALSE);
}
- ShellSmallIconList = ImageList_Create(16,16,ILC_COLOR32|ILC_MASK,0,0x20);
- ShellBigIconList = ImageList_Create(32,32,ILC_COLOR32|ILC_MASK,0,0x20);
+ 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);
- ImageList_SetBkColor(ShellSmallIconList, CLR_NONE);
- ImageList_SetBkColor(ShellBigIconList, CLR_NONE);
+ ImageList_SetBkColor(ShellSmallIconList, CLR_NONE);
+ ImageList_SetBkColor(ShellBigIconList, CLR_NONE);
- for (index=1; index<39; index++)
- {
- hSm = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(index), IMAGE_ICON, cx_small, cy_small, LR_SHARED);
- hLg = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(index), IMAGE_ICON, cx_large, cy_large, LR_SHARED);
+ /* Load the document icon, which is used as the default if an icon isn't found. */
+ hSm = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT),
+ IMAGE_ICON, cx_small, cy_small, LR_SHARED);
+ hLg = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT),
+ IMAGE_ICON, cx_large, cy_large, LR_SHARED);
- if(!hSm)
- {
- hSm = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(1), IMAGE_ICON, cx_small, cy_small, LR_SHARED);
- hLg = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(1), IMAGE_ICON, cx_large, cy_large, LR_SHARED);
- }
- SIC_IconAppend (swShell32Name, index - 1, hSm, hLg, 0);
- SIC_IconAppend (swShell32Name, -index, hSm, hLg, 0);
- }
+ if (!hSm || !hLg)
+ {
+ 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);
+
TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
return TRUE;
LeaveCriticalSection(&SHELL32_SicCS);
}
+/*****************************************************************************
+ * SIC_LoadOverlayIcon [internal]
+ *
+ * Load a shell overlay icon and return its icon cache index.
+ */
+static int SIC_LoadOverlayIcon(int idx)
+{
+ WCHAR buffer[1024], wszIdx[8];
+ HKEY hKeyShellIcons;
+ LPCWSTR iconPath;
+ int iconIdx;
+
+ static const WCHAR wszShellIcons[] = {
+ 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
+ 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+ 'E','x','p','l','o','r','e','r','\\','S','h','e','l','l',' ','I','c','o','n','s',0
+ };
+ static const WCHAR wszNumFmt[] = {'%','d',0};
+
+ iconPath = swShell32Name; /* default: load icon from shell32.dll */
+ iconIdx = idx;
+
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszShellIcons, 0, KEY_READ, &hKeyShellIcons) == ERROR_SUCCESS)
+ {
+ DWORD count = sizeof(buffer);
+
+ sprintfW(wszIdx, wszNumFmt, idx);
+
+ /* read icon path and index */
+ if (RegQueryValueExW(hKeyShellIcons, wszIdx, NULL, NULL, (LPBYTE)buffer, &count) == ERROR_SUCCESS)
+ {
+ LPWSTR p = strchrW(buffer, ',');
+
+ if (p)
+ *p++ = 0;
+
+ iconPath = buffer;
+ iconIdx = atoiW(p);
+ }
+
+ RegCloseKey(hKeyShellIcons);
+ }
+
+ return SIC_LoadIcon(iconPath, iconIdx, 0);
+}
+
/*************************************************************************
* Shell_GetImageList [SHELL32.71]
*
{
IExtractIconW *ei;
WCHAR szIconFile[MAX_PATH]; /* file containing the icon */
- char szTemp[MAX_PATH];
INT iSourceIndex; /* index or resID(negated) in this file */
BOOL ret = FALSE;
UINT dwFlags = 0;
- HKEY keyCls;
int iShortcutDefaultIndex = INVALID_INDEX;
TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small");
if (SUCCEEDED (IShellFolder_GetUIObjectOf(sh, 0, 1, &pidl, &IID_IExtractIconW, 0, (void **)&ei)))
{
- if (_ILGetExtension(pidl, szTemp, MAX_PATH) &&
- HCR_MapTypeToValueA(szTemp, szTemp, MAX_PATH, TRUE))
- {
- if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_CLASSES_ROOT, szTemp, 0, KEY_QUERY_VALUE, &keyCls))
- {
- if (ERROR_SUCCESS == RegQueryValueExA(keyCls, "IsShortcut", NULL, NULL, NULL, NULL))
- {
- uFlags |= GIL_FORSHORTCUT;
- }
- RegCloseKey(keyCls);
- }
- }
if (SUCCEEDED(IExtractIconW_GetIconLocation(ei, uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags)))
{
*pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex, uFlags);
int *pIndex)
{
int Index;
+ UINT uGilFlags = 0;
TRACE("(SF=%p,pidl=%p,%p)\n",sh,pidl,pIndex);
pdump(pidl);
+ if (SHELL_IsShortcut(pidl))
+ uGilFlags |= GIL_FORSHORTCUT;
+
if (pIndex)
- if (!PidlToSicIndex ( sh, pidl, 1, 0, pIndex))
- *pIndex = -1;
+ if (!PidlToSicIndex ( sh, pidl, 1, uGilFlags, pIndex))
+ *pIndex = -1;
- if (!PidlToSicIndex ( sh, pidl, 0, 0, &Index))
+ if (!PidlToSicIndex ( sh, pidl, 0, uGilFlags, &Index))
return -1;
return Index;
{
HICON hIcon = NULL;
INT len = MultiByteToWideChar(CP_ACP, 0, lpIconPath, -1, NULL, 0);
- LPWSTR lpIconPathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ /* Note that we need to allocate MAX_PATH, since we are supposed to fill
+ * the correct executable if there is no icon in lpIconPath directly.
+ * lpIconPath itself is supposed to be large enough, so make sure lpIconPathW
+ * is large enough too. Yes, I am puking too.
+ */
+ LPWSTR lpIconPathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
TRACE("%p %s %p\n", hInst, debugstr_a(lpIconPath), lpiIcon);
{
MultiByteToWideChar(CP_ACP, 0, lpIconPath, -1, lpIconPathW, len);
hIcon = ExtractAssociatedIconW(hInst, lpIconPathW, lpiIcon);
+ WideCharToMultiByte(CP_ACP, 0, lpIconPathW, -1, lpIconPath, MAX_PATH , NULL, NULL);
HeapFree(GetProcessHeap(), 0, lpIconPathW);
}
return hIcon;
}
+/*************************************************************************
+ * ExtractAssociatedIconW (SHELL32.@)
+ *
+ * Return icon for given file (either from file itself or from associated
+ * executable) and patch parameters if needed.
+ */
HICON WINAPI ExtractAssociatedIconW(HINSTANCE hInst, LPWSTR lpIconPath, LPWORD lpiIcon)
{
HICON hIcon = NULL;