mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
673 lines
19 KiB
673 lines
19 KiB
//---------------------------------------------------------------------------
|
|
//
|
|
// Copyright (c) Microsoft Corporation 1991-1992
|
|
//
|
|
// File: fileicon.c
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
#include "shellprv.h"
|
|
#pragma hdrstop
|
|
|
|
// REVIEW: More clean up should be done.
|
|
|
|
BOOL _ShellImageListInit(int cxIcon, int cyIcon, int cxSmIcon, int cySmIcon, UINT flags, BOOL fRestore);
|
|
BOOL _ShellImageListTerm(void);
|
|
|
|
// global shell image lists owned by shelldll
|
|
|
|
HIMAGELIST himlIcons = NULL; // ImageList of large icons
|
|
HIMAGELIST himlIconsSmall = NULL; // ImageList of small icons
|
|
int g_ccIcon = 0; // color depth of ImageLists
|
|
int g_MaxIcons = DEF_MAX_ICONS; // panic limit for icons in cache
|
|
int g_lrFlags = 0;
|
|
|
|
TCHAR const g_szMaxCachedIcons[] = TEXT("Max Cached Icons");
|
|
TCHAR const g_szShellIconSize[] = TEXT("Shell Icon Size");
|
|
TCHAR const g_szShellSmallIconSize[] = TEXT("Shell Small Icon Size");
|
|
TCHAR const g_szShellIconDepth[] = TEXT("Shell Icon Bpp");
|
|
TCHAR const g_szShellIcons[] = TEXT("Shell Icons");
|
|
TCHAR const g_szD[] = TEXT("%d");
|
|
|
|
//
|
|
// System imagelist - Don't change the order of this list.
|
|
// If you need to add a new icon, add it to the end of the
|
|
// array, and update shellp.h.
|
|
//
|
|
#pragma data_seg(DATASEG_READONLY)
|
|
UINT const c_SystemImageListIndexes[] = { IDI_DOCUMENT,
|
|
IDI_DOCASSOC,
|
|
IDI_APP,
|
|
IDI_FOLDER,
|
|
IDI_FOLDEROPEN,
|
|
IDI_DRIVE525,
|
|
IDI_DRIVE35,
|
|
IDI_DRIVEREMOVE,
|
|
IDI_DRIVEFIXED,
|
|
IDI_DRIVENET,
|
|
IDI_DRIVENETDISABLED,
|
|
IDI_DRIVECD,
|
|
IDI_DRIVERAM,
|
|
IDI_WORLD,
|
|
IDI_NETWORK,
|
|
IDI_SERVER,
|
|
IDI_PRINTER,
|
|
IDI_MYNETWORK,
|
|
IDI_GROUP,
|
|
|
|
IDI_STPROGS,
|
|
IDI_STDOCS,
|
|
IDI_STSETNGS,
|
|
IDI_STFIND,
|
|
IDI_STHELP,
|
|
IDI_STRUN,
|
|
IDI_STSUSPD,
|
|
IDI_STEJECT,
|
|
IDI_STSHUTD,
|
|
|
|
IDI_SHARE,
|
|
IDI_LINK,
|
|
IDI_READONLY,
|
|
IDI_RECYCLER,
|
|
IDI_RECYCLERFULL,
|
|
IDI_RNA,
|
|
IDI_DESKTOP,
|
|
|
|
IDI_STCPANEL,
|
|
IDI_STSPROGS,
|
|
IDI_STPRNTRS,
|
|
IDI_STFONTS,
|
|
IDI_STTASKBR,
|
|
|
|
IDI_CDAUDIO,
|
|
IDI_TREE,
|
|
IDI_STCPROGS};
|
|
|
|
#pragma data_seg()
|
|
|
|
|
|
int GetRegInt(HKEY hk, LPCTSTR szKey, int def)
|
|
{
|
|
DWORD cb;
|
|
TCHAR ach[20];
|
|
|
|
if (hk == NULL)
|
|
return def;
|
|
|
|
ach[0] = 0;
|
|
cb = SIZEOF(ach);
|
|
RegQueryValueEx(hk, szKey, NULL, NULL, (LPBYTE)ach, &cb);
|
|
|
|
if (ach[0] >= TEXT('0') && ach[0] <= TEXT('9'))
|
|
return (int)StrToLong(ach);
|
|
else
|
|
return def;
|
|
}
|
|
|
|
//
|
|
// get g_MaxIcons from the registry, returning TRUE if it has changed
|
|
//
|
|
BOOL QueryNewMaxIcons(void)
|
|
{
|
|
HKEY hkey;
|
|
int MaxIcons = DEF_MAX_ICONS;
|
|
|
|
if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_EXPLORER, &hkey) == 0)
|
|
{
|
|
MaxIcons = GetRegInt(hkey, g_szMaxCachedIcons, MaxIcons);
|
|
RegCloseKey(hkey);
|
|
|
|
if (MaxIcons < 0)
|
|
MaxIcons = DEF_MAX_ICONS;
|
|
}
|
|
|
|
if (g_MaxIcons != MaxIcons)
|
|
{
|
|
g_MaxIcons = MaxIcons;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Initializes shared resources for Shell_GetIconIndex and others
|
|
//
|
|
BOOL WINAPI FileIconInit( BOOL fRestoreCache )
|
|
{
|
|
BOOL fNotify = FALSE;
|
|
BOOL fInit = FALSE;
|
|
HKEY hkey;
|
|
int cxIcon, cyIcon, ccIcon, cxSmIcon, cySmIcon, res;
|
|
|
|
QueryNewMaxIcons(); // in case the size of the icon cache has changed
|
|
|
|
ccIcon = 0;
|
|
cxIcon = GetSystemMetrics(SM_CXICON);
|
|
cyIcon = GetSystemMetrics(SM_CYICON);
|
|
////cxSmIcon = GetSystemMetrics(SM_CXSMICON);
|
|
////cySmIcon = GetSystemMetrics(SM_CYSMICON);
|
|
cxSmIcon = GetSystemMetrics(SM_CXICON) / 2;
|
|
cySmIcon = GetSystemMetrics(SM_CYICON) / 2;
|
|
|
|
//
|
|
// get the user prefered icon size (and color depth) from the
|
|
// registry.
|
|
//
|
|
if (RegOpenKey(HKEY_CURRENT_USER, REGSTR_PATH_METRICS, &hkey) == 0)
|
|
{
|
|
cxIcon = GetRegInt(hkey, g_szShellIconSize, cxIcon);
|
|
cxSmIcon = GetRegInt(hkey, g_szShellSmallIconSize, cxSmIcon);
|
|
ccIcon = GetRegInt(hkey, g_szShellIconDepth, ccIcon);
|
|
|
|
cyIcon = cxIcon; // icons are always square
|
|
cySmIcon = cxSmIcon;
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
res = (int)GetCurColorRes();
|
|
|
|
if (ccIcon > res)
|
|
ccIcon = 0;
|
|
|
|
if (res <= 8)
|
|
ccIcon = 0; // wouldn't have worked anyway
|
|
|
|
#if 0
|
|
//
|
|
// use a 8bpp imagelist on a HiColor device iff we will
|
|
// be stretching icons.
|
|
//
|
|
if (res > 8 && ccIcon == 0 && (cxIcon != GetSystemMetrics(SM_CXICON) ||
|
|
cxSmIcon != GetSystemMetrics(SM_CXICON)/2))
|
|
{
|
|
ccIcon = 8;
|
|
}
|
|
#endif
|
|
|
|
ENTERCRITICAL
|
|
|
|
//
|
|
// if we already have a icon cache make sure it is the right size etc.
|
|
//
|
|
if (himlIcons)
|
|
{
|
|
// cant change this while running sorry.
|
|
ccIcon = g_ccIcon;
|
|
|
|
if (g_cxIcon == cxIcon &&
|
|
g_cyIcon == cyIcon &&
|
|
g_cxSmIcon == cxSmIcon &&
|
|
g_cySmIcon == cySmIcon &&
|
|
g_ccIcon == ccIcon)
|
|
{
|
|
fInit = TRUE;
|
|
goto Exit;
|
|
}
|
|
|
|
FlushIconCache();
|
|
FlushFileClass();
|
|
|
|
// make sure every one updates.
|
|
fNotify = TRUE;
|
|
}
|
|
|
|
g_cxIcon = cxIcon;
|
|
g_cyIcon = cyIcon;
|
|
g_ccIcon = ccIcon;
|
|
g_cxSmIcon = cxSmIcon;
|
|
g_cySmIcon = cySmIcon;
|
|
|
|
if (res > 4 && g_ccIcon <= 4)
|
|
g_lrFlags = LR_VGACOLOR;
|
|
else
|
|
g_lrFlags = 0;
|
|
|
|
DebugMsg(DM_TRACE, TEXT("IconCache: Size=%dx%d SmSize=%dx%d Bpp=%d"), cxIcon, cyIcon, cxSmIcon, cySmIcon, (ccIcon&ILC_COLOR));
|
|
|
|
if (g_iLastSysIcon == 0) // Keep track of which icons are perm.
|
|
{
|
|
if (fRestoreCache)
|
|
g_iLastSysIcon = II_LASTSYSICON;
|
|
else
|
|
g_iLastSysIcon = (II_OVERLAYLAST - II_OVERLAYFIRST) + 1;
|
|
}
|
|
|
|
// try to restore the icon cache (if we have not loaded it yet)
|
|
if (himlIcons != NULL || !fRestoreCache || !_IconCacheRestore(g_cxIcon, g_cyIcon, g_cxSmIcon, g_cySmIcon, g_ccIcon))
|
|
{
|
|
if (!_ShellImageListInit(g_cxIcon, g_cyIcon, g_cxSmIcon, g_cySmIcon, g_ccIcon, fRestoreCache))
|
|
goto Exit;
|
|
}
|
|
|
|
fInit = TRUE;
|
|
|
|
Exit:
|
|
LEAVECRITICAL
|
|
|
|
if (fInit && fNotify)
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("IconCache: icon size has changed sending SHCNE_UPDATEIMAGE(-1)..."));
|
|
SHChangeNotify(SHCNE_UPDATEIMAGE, SHCNF_DWORD, (LPCVOID)-1, NULL);
|
|
}
|
|
|
|
return fInit;
|
|
}
|
|
|
|
void FileIconTerm(void)
|
|
{
|
|
ENTERCRITICAL
|
|
|
|
_ShellImageListTerm();
|
|
|
|
LEAVECRITICAL
|
|
}
|
|
|
|
/*************************************************************************
|
|
*************************************************************************/
|
|
|
|
BOOL _ShellImageListInit(int cxIcon, int cyIcon, int cxSmIcon, int cySmIcon, UINT flags, BOOL fRestore)
|
|
{
|
|
int i;
|
|
TCHAR szModule[MAX_PATH];
|
|
HKEY hkeyIcons;
|
|
|
|
ASSERTCRITICAL;
|
|
|
|
if (himlIcons == NULL) {
|
|
himlIcons = ImageList_Create(cxIcon, cyIcon, ILC_MASK|ILC_SHARED|flags, 0, 32);
|
|
}
|
|
else {
|
|
ImageList_Remove(himlIcons, -1);
|
|
ImageList_SetIconSize(himlIcons, cxIcon, cyIcon);
|
|
}
|
|
|
|
if (himlIcons == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (himlIconsSmall == NULL) {
|
|
himlIconsSmall = ImageList_Create(cxSmIcon, cySmIcon, ILC_MASK|ILC_SHARED|flags, 0, 32);
|
|
}
|
|
else {
|
|
ImageList_Remove(himlIconsSmall, -1);
|
|
ImageList_SetIconSize(himlIconsSmall, cxSmIcon, cySmIcon);
|
|
}
|
|
|
|
if (himlIconsSmall == NULL) {
|
|
ImageList_Destroy(himlIcons);
|
|
himlIcons = NULL;
|
|
return FALSE;
|
|
}
|
|
|
|
// set the bk colors to COLOR_WINDOW since this is what will
|
|
// be used most of the time as the bk for these lists (cabinet, tray)
|
|
// this avoids having to do ROPs when drawing, thus making it fast
|
|
|
|
ImageList_SetBkColor(himlIcons, GetSysColor(COLOR_WINDOW));
|
|
ImageList_SetBkColor(himlIconsSmall, GetSysColor(COLOR_WINDOW));
|
|
|
|
GetModuleFileName(HINST_THISDLL, szModule, ARRAYSIZE(szModule));
|
|
|
|
// WARNING: this code assumes that these icons are the first in
|
|
// our RC file and are in this order and these indexes correspond
|
|
// to the II_ constants in shell.h.
|
|
|
|
hkeyIcons =
|
|
SHGetExplorerSubHkey(HKEY_LOCAL_MACHINE, g_szShellIcons, FALSE);
|
|
|
|
for (i = 0; i < ARRAYSIZE(c_SystemImageListIndexes); i++) {
|
|
|
|
HICON hIcon=NULL;
|
|
HICON hSmallIcon=NULL;
|
|
int iIndex;
|
|
|
|
//
|
|
// Load all of the icons with fRestore == TRUE, or only the overlays
|
|
// if fRestore == FALSE.
|
|
//
|
|
if (fRestore || (i >= II_OVERLAYFIRST && i <= II_OVERLAYLAST))
|
|
{
|
|
//
|
|
// check to see if icon is overridden in the registry
|
|
//
|
|
if (hkeyIcons)
|
|
{
|
|
TCHAR val[10];
|
|
TCHAR ach[MAX_PATH];
|
|
DWORD cb=MAX_PATH;
|
|
int iIcon;
|
|
|
|
wsprintf(val, g_szD, i);
|
|
|
|
ach[0] = 0;
|
|
RegQueryValueEx(hkeyIcons, val, NULL, NULL, (LPBYTE)ach, &cb);
|
|
|
|
if (ach[0])
|
|
{
|
|
HICON hIcons[2] = {0, 0};
|
|
|
|
iIcon = PathParseIconLocation(ach);
|
|
|
|
ExtractIcons(ach, iIcon,
|
|
MAKELONG(g_cxIcon,g_cxSmIcon),
|
|
MAKELONG(g_cyIcon,g_cySmIcon),
|
|
hIcons, NULL, 2, g_lrFlags);
|
|
|
|
hIcon = hIcons[0];
|
|
hSmallIcon = hIcons[1];
|
|
|
|
if (hIcon)
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("ShellImageListInit: Got default icon #%d from registry: %s,%d"), i, ach, iIcon);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (hIcon == NULL)
|
|
{
|
|
hIcon = LoadImage(HINST_THISDLL, MAKEINTRESOURCE(c_SystemImageListIndexes[i]), IMAGE_ICON, cxIcon, cyIcon, g_lrFlags);
|
|
hSmallIcon = LoadImage(HINST_THISDLL, MAKEINTRESOURCE(c_SystemImageListIndexes[i]), IMAGE_ICON, cxSmIcon, cySmIcon, g_lrFlags);
|
|
}
|
|
|
|
if (hIcon)
|
|
{
|
|
iIndex = SHAddIconsToCache(hIcon, hSmallIcon, szModule, i, 0);
|
|
Assert(iIndex == i); // assume index
|
|
|
|
if (i >= II_OVERLAYFIRST && i <= II_OVERLAYLAST)
|
|
{
|
|
ImageList_SetOverlayImage(himlIcons, iIndex, i - II_OVERLAYFIRST + 1);
|
|
ImageList_SetOverlayImage(himlIconsSmall, iIndex, i - II_OVERLAYFIRST + 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hkeyIcons)
|
|
RegCloseKey(hkeyIcons);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL _ShellImageListTerm(void)
|
|
{
|
|
ENTERCRITICAL
|
|
if (himlIcons) {
|
|
ImageList_Destroy(himlIcons);
|
|
himlIcons = NULL;
|
|
}
|
|
|
|
if (himlIconsSmall) {
|
|
ImageList_Destroy(himlIconsSmall);
|
|
himlIconsSmall = NULL;
|
|
}
|
|
LEAVECRITICAL
|
|
return TRUE;
|
|
}
|
|
|
|
// get a hold of the system image lists
|
|
|
|
BOOL WINAPI Shell_GetImageLists(HIMAGELIST *phiml, HIMAGELIST *phimlSmall)
|
|
{
|
|
FileIconInit( FALSE ); // make sure they are created and the right size.
|
|
|
|
if (phiml)
|
|
*phiml = himlIcons;
|
|
|
|
if (phimlSmall)
|
|
*phimlSmall = himlIconsSmall;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void WINAPI Shell_SysColorChange(void)
|
|
{
|
|
COLORREF clrWindow;
|
|
|
|
ENTERCRITICAL
|
|
clrWindow = GetSysColor(COLOR_WINDOW);
|
|
ImageList_SetBkColor(himlIcons , clrWindow);
|
|
ImageList_SetBkColor(himlIconsSmall, clrWindow);
|
|
LEAVECRITICAL
|
|
}
|
|
|
|
// simulate the document icon by crunching a copy of an icon and putting it in the
|
|
// middle of our default document icon, then add it to the passsed image list
|
|
//
|
|
// in:
|
|
// hIcon icon to use as a basis for the simulation
|
|
//
|
|
// returns:
|
|
// hicon
|
|
|
|
HICON SimulateDocIcon(HIMAGELIST himl, HICON hIcon, BOOL fSmall)
|
|
{
|
|
int cx = fSmall ? g_cxSmIcon : g_cxIcon;
|
|
int cy = fSmall ? g_cxSmIcon : g_cxIcon;
|
|
|
|
HDC hdc;
|
|
HDC hdcMem;
|
|
HBITMAP hbmMask;
|
|
HBITMAP hbmColor;
|
|
HBITMAP hbmT;
|
|
ICONINFO ii;
|
|
UINT iIndex;
|
|
|
|
if (himl == NULL || hIcon == NULL)
|
|
return NULL;
|
|
|
|
hdc = GetDC(NULL);
|
|
hdcMem = CreateCompatibleDC(hdc);
|
|
hbmColor = CreateCompatibleBitmap(hdc, cx, cy);
|
|
hbmMask = CreateBitmap(cx, cy, 1, 1, NULL);
|
|
ReleaseDC(NULL, hdc);
|
|
|
|
hbmT = SelectObject(hdcMem, hbmMask);
|
|
iIndex = Shell_GetCachedImageIndex(c_szShell32Dll, II_DOCNOASSOC, 0);
|
|
ImageList_Draw(himl, iIndex, hdcMem, 0, 0, ILD_MASK);
|
|
|
|
SelectObject(hdcMem, hbmColor);
|
|
ImageList_DrawEx(himl, iIndex, hdcMem, 0, 0, 0, 0, RGB(0,0,0), CLR_DEFAULT, ILD_NORMAL);
|
|
|
|
//BUGBUG this assumes the generic icon is white
|
|
PatBlt(hdcMem, cx/4-1, cy/4-1, cx/2+(fSmall?2:4), cy/2+2, WHITENESS);
|
|
DrawIconEx(hdcMem, cx/4, cy/4, hIcon, cx/2, cy/2, 0, NULL, DI_NORMAL);
|
|
|
|
SelectObject(hdcMem, hbmT);
|
|
DeleteDC(hdcMem);
|
|
|
|
ii.fIcon = TRUE;
|
|
ii.xHotspot = 0;
|
|
ii.yHotspot = 0;
|
|
ii.hbmColor = hbmColor;
|
|
ii.hbmMask = hbmMask;
|
|
hIcon = CreateIconIndirect(&ii);
|
|
|
|
DeleteObject(hbmColor);
|
|
DeleteObject(hbmMask);
|
|
|
|
return hIcon;
|
|
}
|
|
|
|
// add icons to the system imagelist (icon cache) and put the location
|
|
// in the location cache
|
|
//
|
|
// in:
|
|
// hIcon, hIconSmall the icons, hIconSmall can be NULL
|
|
// pszIconPath locations (for location cache)
|
|
// iIconIndex index in pszIconPath (for location cache)
|
|
// uIconFlags GIL_ flags (for location cahce)
|
|
// returns:
|
|
// location in system image list
|
|
//
|
|
int SHAddIconsToCache(HICON hIcon, HICON hIconSmall, LPCTSTR pszIconPath, int iIconIndex, UINT uIconFlags)
|
|
{
|
|
int iImage;
|
|
int iImageSmall;
|
|
int iImageFree;
|
|
|
|
Assert(himlIcons);
|
|
|
|
if (hIcon == NULL)
|
|
{
|
|
SHDefExtractIcon(pszIconPath, iIconIndex, uIconFlags, &hIcon, &hIconSmall, 0);
|
|
}
|
|
|
|
if (hIcon == NULL)
|
|
return -1;
|
|
|
|
if (hIconSmall == NULL)
|
|
hIconSmall = hIcon; // ImageList_AddIcon will shrink for us
|
|
|
|
ENTERCRITICAL
|
|
|
|
iImageFree = GetFreeImageIndex();
|
|
|
|
iImage = ImageList_ReplaceIcon(himlIcons, iImageFree, hIcon);
|
|
|
|
if (iImage >= 0)
|
|
{
|
|
iImageSmall = ImageList_ReplaceIcon(himlIconsSmall, iImageFree, hIconSmall);
|
|
|
|
if (iImageSmall < 0)
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("AddIconsToCache() ImageList_AddIcon failed (small)"));
|
|
// only remove it if it was added at the end otherwise all the
|
|
// index's above iImage will change.
|
|
// ImageList_ReplaceIcon should only fail on the end anyway.
|
|
if (iImageFree == -1)
|
|
ImageList_Remove(himlIcons, iImage); // remove big
|
|
iImage = -1;
|
|
}
|
|
else
|
|
{
|
|
Assert(iImageSmall == iImage);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("AddIconsToCache() ImageList_AddIcon failed"));
|
|
iImage = -1;
|
|
}
|
|
|
|
if (iImage >= 0)
|
|
AddToIconTable(pszIconPath, iIconIndex, uIconFlags, iImage);
|
|
|
|
LEAVECRITICAL
|
|
|
|
if (hIcon)
|
|
DestroyIcon(hIcon);
|
|
|
|
if (hIconSmall && hIcon != hIconSmall)
|
|
DestroyIcon(hIconSmall);
|
|
|
|
return iImage;
|
|
}
|
|
|
|
//
|
|
// default handler to extract a icon from a file
|
|
//
|
|
// supports GIL_SIMULATEDOC
|
|
//
|
|
// returns S_OK if success
|
|
// returns S_FALSE if the file has no icons (or not the asked for icon)
|
|
// returns E_FAIL for files on a slow link.
|
|
// returns E_FAIL if cant access the file
|
|
//
|
|
// BUGBUG: Returning S_FALSE for executables that have no icons causes
|
|
// BUGBUG: us to extract the icon twice, see DefViewX.c / _ILIndexGivenIcon
|
|
//
|
|
// LOWORD(nIconSize) = normal icon size
|
|
// HIWORD(nIconSize) = smal icon size
|
|
//
|
|
HRESULT SHDefExtractIcon(LPCTSTR szIconFile, int iIndex, UINT uFlags,
|
|
HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize)
|
|
{
|
|
HICON hIcons[2] = {0, 0};
|
|
UINT u;
|
|
|
|
#ifdef DEBUG
|
|
TCHAR ach[128];
|
|
GetModuleFileName(HINST_THISDLL, ach, ARRAYSIZE(ach));
|
|
|
|
if (lstrcmpi(szIconFile, ach) == 0 && iIndex >= 0)
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("re-extracting %d from SHELL32.DLL"), iIndex);
|
|
Assert(0);
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// get the icon from the file
|
|
//
|
|
if (PathIsSlow(szIconFile))
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("not extracting icon from '%s' because of slow link"), szIconFile);
|
|
return E_FAIL;
|
|
}
|
|
|
|
//
|
|
// nIconSize == 0 means use the default size.
|
|
// Backup is passing nIconSize == 1 need to support them too.
|
|
//
|
|
if (nIconSize <= 2)
|
|
nIconSize = MAKELONG(g_cxIcon, g_cxSmIcon);
|
|
|
|
if (uFlags & GIL_SIMULATEDOC)
|
|
{
|
|
HICON hIconSmall;
|
|
|
|
u = ExtractIcons(szIconFile, iIndex, g_cxSmIcon, g_cySmIcon,
|
|
&hIconSmall, NULL, 1, g_lrFlags);
|
|
|
|
if (u == -1)
|
|
return E_FAIL;
|
|
|
|
hIcons[0] = SimulateDocIcon(himlIcons, hIconSmall, FALSE);
|
|
hIcons[1] = SimulateDocIcon(himlIconsSmall, hIconSmall, TRUE);
|
|
|
|
if (hIconSmall)
|
|
DestroyIcon(hIconSmall);
|
|
}
|
|
else
|
|
{
|
|
u = ExtractIcons(szIconFile, iIndex, nIconSize, nIconSize,
|
|
hIcons, NULL, 2, g_lrFlags);
|
|
|
|
if (u == -1)
|
|
return E_FAIL;
|
|
}
|
|
|
|
*phiconLarge = hIcons[0];
|
|
*phiconSmall = hIcons[1];
|
|
|
|
return u==0 ? S_FALSE : S_OK;
|
|
}
|
|
|
|
//
|
|
// in:
|
|
// pszIconPath file to get icon from (eg. cabinet.exe)
|
|
// iIconIndex icon index in pszIconPath to get
|
|
// uIconFlags GIL_ values indicating simulate doc icon, etc.
|
|
|
|
int WINAPI Shell_GetCachedImageIndex(LPCTSTR pszIconPath, int iIconIndex, UINT uIconFlags)
|
|
{
|
|
int iImageIndex;
|
|
|
|
if (himlIcons == NULL)
|
|
{
|
|
FileIconInit( FALSE );
|
|
}
|
|
|
|
iImageIndex = LookupIconIndex(PathFindFileName(pszIconPath), iIconIndex, uIconFlags);
|
|
|
|
if (iImageIndex == -1)
|
|
{
|
|
iImageIndex = SHAddIconsToCache(NULL, NULL, pszIconPath, iIconIndex, uIconFlags);
|
|
}
|
|
|
|
return iImageIndex;
|
|
}
|