// SysIconUtils.cpp #include "StdAfx.h" #ifndef _UNICODE #include "Common/StringConvert.h" #endif #include "SysIconUtils.h" #ifndef _UNICODE extern bool g_IsNT; #endif int GetIconIndexForCSIDL(int csidl) { LPITEMIDLIST pidl = 0; SHGetSpecialFolderLocation(NULL, csidl, &pidl); if (pidl) { SHFILEINFO shellInfo; SHGetFileInfo(LPCTSTR(pidl), FILE_ATTRIBUTE_NORMAL, &shellInfo, sizeof(shellInfo), SHGFI_PIDL | SHGFI_SYSICONINDEX); IMalloc *pMalloc; SHGetMalloc(&pMalloc); if(pMalloc) { pMalloc->Free(pidl); pMalloc->Release(); } return shellInfo.iIcon; } return 0; } DWORD_PTR GetRealIconIndex(LPCTSTR path, DWORD attrib, int &iconIndex) { SHFILEINFO shellInfo; DWORD_PTR res = ::SHGetFileInfo(path, FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); iconIndex = shellInfo.iIcon; return res; } #ifndef _UNICODE typedef int (WINAPI * SHGetFileInfoWP)(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags); struct CSHGetFileInfoInit { SHGetFileInfoWP shGetFileInfoW; CSHGetFileInfoInit() { shGetFileInfoW = (SHGetFileInfoWP) ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetFileInfoW"); } } g_SHGetFileInfoInit; #endif static DWORD_PTR MySHGetFileInfoW(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags) { #ifdef _UNICODE return SHGetFileInfo( #else if (g_SHGetFileInfoInit.shGetFileInfoW == 0) return 0; return g_SHGetFileInfoInit.shGetFileInfoW( #endif pszPath, attrib, psfi, cbFileInfo, uFlags); } #ifndef _UNICODE // static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } DWORD_PTR GetRealIconIndex(LPCWSTR path, DWORD attrib, int &iconIndex) { if(g_IsNT) { SHFILEINFOW shellInfo; DWORD_PTR res = ::MySHGetFileInfoW(path, FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); iconIndex = shellInfo.iIcon; return res; } else return GetRealIconIndex(UnicodeStringToMultiByte(path), attrib, iconIndex); } #endif DWORD_PTR GetRealIconIndex(const UString &fileName, DWORD attrib, int &iconIndex, UString &typeName) { #ifndef _UNICODE if(!g_IsNT) { SHFILEINFO shellInfo; shellInfo.szTypeName[0] = 0; DWORD_PTR res = ::SHGetFileInfoA(GetSystemString(fileName), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME); typeName = GetUnicodeString(shellInfo.szTypeName); iconIndex = shellInfo.iIcon; return res; } else #endif { SHFILEINFOW shellInfo; shellInfo.szTypeName[0] = 0; DWORD_PTR res = ::MySHGetFileInfoW(fileName, FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME); typeName = shellInfo.szTypeName; iconIndex = shellInfo.iIcon; return res; } } int CExtToIconMap::GetIconIndex(DWORD attrib, const UString &fileName, UString &typeName) { int dotPos = fileName.ReverseFind(L'.'); if ((attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 || dotPos < 0) { CAttribIconPair pair; pair.Attrib = attrib; int index = _attribMap.FindInSorted(pair); if (index >= 0) { typeName = _attribMap[index].TypeName; return _attribMap[index].IconIndex; } GetRealIconIndex( #ifdef UNDER_CE L"\\" #endif L"__File__" , attrib, pair.IconIndex, pair.TypeName); _attribMap.AddToSorted(pair); typeName = pair.TypeName; return pair.IconIndex; } CExtIconPair pair; pair.Ext = fileName.Mid(dotPos + 1); int index = _extMap.FindInSorted(pair); if (index >= 0) { typeName = _extMap[index].TypeName; return _extMap[index].IconIndex; } GetRealIconIndex(fileName.Mid(dotPos), attrib, pair.IconIndex, pair.TypeName); _extMap.AddToSorted(pair); typeName = pair.TypeName; return pair.IconIndex; } int CExtToIconMap::GetIconIndex(DWORD attrib, const UString &fileName) { UString typeName; return GetIconIndex(attrib, fileName, typeName); }