Source code

Revision control

Copy as Markdown

Other Tools

// SysIconUtils.cpp↩
#include "StdAfx.h"
#ifndef _UNICODE↩
#include "../../../Common/StringConvert.h"
#endif
#include "../../../Windows/FileDir.h"
#include "SysIconUtils.h"
#include <ShlObj.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;↩
}↩
#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);↩
}↩
DWORD_PTR GetRealIconIndex(CFSTR path, DWORD attrib, int &iconIndex)↩
{↩
#ifndef _UNICODE↩
if (!g_IsNT)↩
{↩
SHFILEINFO shellInfo;↩
DWORD_PTR res = ::SHGetFileInfo(fs2fas(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo,↩
sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);↩
iconIndex = shellInfo.iIcon;↩
return res;↩
}↩
else
#endif
{↩
SHFILEINFOW shellInfo;↩
DWORD_PTR res = ::MySHGetFileInfoW(fs2us(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo,↩
sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);↩
iconIndex = shellInfo.iIcon;↩
return res;↩
}↩
}↩
/*↩
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);↩
if (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);↩
if (typeName)↩
*typeName = shellInfo.szTypeName;↩
iconIndex = shellInfo.iIcon;↩
return res;↩
}↩
}↩
*/
static int FindInSorted_Attrib(const CRecordVector<CAttribIconPair> &vect, DWORD attrib, int &insertPos)↩
{↩
unsigned left = 0, right = vect.Size();↩
while (left != right)↩
{↩
unsigned mid = (left + right) / 2;↩
DWORD midAttrib = vect[mid].Attrib;↩
if (attrib == midAttrib)↩
return mid;↩
if (attrib < midAttrib)↩
right = mid;↩
else
left = mid + 1;↩
}↩
insertPos = left;↩
return -1;↩
}↩
static int FindInSorted_Ext(const CObjectVector<CExtIconPair> &vect, const wchar_t *ext, int &insertPos)↩
{↩
unsigned left = 0, right = vect.Size();↩
while (left != right)↩
{↩
unsigned mid = (left + right) / 2;↩
int compare = MyStringCompareNoCase(ext, vect[mid].Ext);↩
if (compare == 0)↩
return mid;↩
if (compare < 0)↩
right = mid;↩
else
left = mid + 1;↩
}↩
insertPos = left;↩
return -1;↩
}↩
int CExtToIconMap::GetIconIndex(DWORD attrib, const wchar_t *fileName /*, UString *typeName */)↩
{↩
int dotPos = -1;↩
unsigned i;↩
for (i = 0;; i++)↩
{↩
wchar_t c = fileName[i];↩
if (c == 0)↩
break;↩
if (c == '.')↩
dotPos = i;↩
}↩
/*↩
if (MyStringCompareNoCase(fileName, L"$Recycle.Bin") == 0)↩
{↩
char s[256];↩
sprintf(s, "SPEC i = %3d, attr = %7x", _attribMap.Size(), attrib);↩
OutputDebugStringA(s);↩
OutputDebugStringW(fileName);↩
}↩
*/
if ((attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 || dotPos < 0)↩
{↩
int insertPos = 0;↩
int index = FindInSorted_Attrib(_attribMap, attrib, insertPos);↩
if (index >= 0)↩
{↩
// if (typeName) *typeName = _attribMap[index].TypeName;↩
return _attribMap[index].IconIndex;↩
}↩
CAttribIconPair pair;↩
GetRealIconIndex(↩
#ifdef UNDER_CE↩
FTEXT("\\")↩
#endif
FTEXT("__DIR__")↩
, attrib, pair.IconIndex↩
// , pair.TypeName↩
);↩
/*↩
char s[256];↩
sprintf(s, "i = %3d, attr = %7x", _attribMap.Size(), attrib);↩
OutputDebugStringA(s);↩
*/
pair.Attrib = attrib;↩
_attribMap.Insert(insertPos, pair);↩
// if (typeName) *typeName = pair.TypeName;↩
return pair.IconIndex;↩
}↩
const wchar_t *ext = fileName + dotPos + 1;↩
int insertPos = 0;↩
int index = FindInSorted_Ext(_extMap, ext, insertPos);↩
if (index >= 0)↩
{↩
const CExtIconPair &pa = _extMap[index];↩
// if (typeName) *typeName = pa.TypeName;↩
return pa.IconIndex;↩
}↩
for (i = 0;; i++)↩
{↩
wchar_t c = ext[i];↩
if (c == 0)↩
break;↩
if (c < L'0' || c > L'9')↩
break;↩
}↩
if (i != 0 && ext[i] == 0)↩
{↩
// GetRealIconIndex is too slow for big number of split extensions: .001, .002, .003↩
if (!SplitIconIndex_Defined)↩
{↩
GetRealIconIndex(↩
#ifdef UNDER_CE↩
FTEXT("\\")↩
#endif
FTEXT("__FILE__.001"), 0, SplitIconIndex);↩
SplitIconIndex_Defined = true;↩
}↩
return SplitIconIndex;↩
}↩
CExtIconPair pair;↩
pair.Ext = ext;↩
GetRealIconIndex(us2fs(fileName + dotPos), attrib, pair.IconIndex);↩
_extMap.Insert(insertPos, pair);↩
// if (typeName) *typeName = pair.TypeName;↩
return pair.IconIndex;↩
}↩
/*↩
int CExtToIconMap::GetIconIndex(DWORD attrib, const UString &fileName)↩
{↩
return GetIconIndex(attrib, fileName, NULL);↩
}↩
*/