1 // SysIconUtils.h
2
3 #include "StdAfx.h"
4
5 #include "SysIconUtils.h"
6 #ifndef _UNICODE
7 #include "Common/StringConvert.h"
8 #endif
9
10 #ifndef _UNICODE
11 extern bool g_IsNT;
12 #endif
13
GetIconIndexForCSIDL(int csidl)14 int GetIconIndexForCSIDL(int csidl)
15 {
16 #ifdef _WIN32
17 LPITEMIDLIST pidl = 0;
18 SHGetSpecialFolderLocation(NULL, csidl, &pidl);
19 if (pidl)
20 {
21 SHFILEINFO shellInfo;
22 SHGetFileInfo(LPCTSTR(pidl), FILE_ATTRIBUTE_NORMAL,
23 &shellInfo, sizeof(shellInfo),
24 SHGFI_PIDL | SHGFI_SYSICONINDEX);
25 IMalloc *pMalloc;
26 SHGetMalloc(&pMalloc);
27 if(pMalloc)
28 {
29 pMalloc->Free(pidl);
30 pMalloc->Release();
31 }
32 return shellInfo.iIcon;
33 }
34 #endif // FIXME -1 ?
35 return 0;
36 }
37
GetRealIconIndex(LPCTSTR path,DWORD attributes,int & iconIndex)38 DWORD_PTR GetRealIconIndex(LPCTSTR path, DWORD attributes, int &iconIndex)
39 {
40 #ifdef _WIN32
41 SHFILEINFO shellInfo;
42 DWORD_PTR res = ::SHGetFileInfo(path, FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo,
43 sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
44 iconIndex = shellInfo.iIcon;
45 return res;
46 #else
47 return -1;
48 #endif
49 }
50
51
52 #ifdef _WIN32
53
54 #ifndef _UNICODE
55 typedef int (WINAPI * SHGetFileInfoWP)(LPCWSTR pszPath, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags);
56
57 struct CSHGetFileInfoInit
58 {
59 SHGetFileInfoWP shGetFileInfoW;
CSHGetFileInfoInitCSHGetFileInfoInit60 CSHGetFileInfoInit()
61 {
62 shGetFileInfoW = (SHGetFileInfoWP)
63 ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetFileInfoW");
64 }
65 } g_SHGetFileInfoInit;
66 #endif
67
MySHGetFileInfoW(LPCWSTR pszPath,DWORD dwFileAttributes,SHFILEINFOW * psfi,UINT cbFileInfo,UINT uFlags)68 DWORD_PTR MySHGetFileInfoW(LPCWSTR pszPath, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags)
69 {
70 #ifdef _UNICODE
71 return SHGetFileInfoW(
72 #else
73 if (g_SHGetFileInfoInit.shGetFileInfoW == 0)
74 return 0;
75 return g_SHGetFileInfoInit.shGetFileInfoW(
76 #endif
77 pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags);
78 }
79
80 #ifndef _UNICODE
81 // static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
GetRealIconIndex(LPCWSTR path,DWORD attributes,int & iconIndex)82 DWORD_PTR GetRealIconIndex(LPCWSTR path, DWORD attributes, int &iconIndex)
83 {
84 if(g_IsNT)
85 {
86 SHFILEINFOW shellInfo;
87 DWORD_PTR res = ::MySHGetFileInfoW(path, FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo,
88 sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
89 iconIndex = shellInfo.iIcon;
90 return res;
91 }
92 else
93 return GetRealIconIndex(UnicodeStringToMultiByte(path), attributes, iconIndex);
94 }
95 #endif
96
GetRealIconIndex(const UString & fileName,DWORD attributes,int & iconIndex,UString & typeName)97 DWORD_PTR GetRealIconIndex(const UString &fileName, DWORD attributes,
98 int &iconIndex, UString &typeName)
99 {
100 #ifndef _UNICODE
101 if(!g_IsNT)
102 {
103 SHFILEINFO shellInfo;
104 shellInfo.szTypeName[0] = 0;
105 DWORD_PTR res = ::SHGetFileInfoA(GetSystemString(fileName), FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo,
106 sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX
107 | SHGFI_TYPENAME);
108 typeName = GetUnicodeString(shellInfo.szTypeName);
109 iconIndex = shellInfo.iIcon;
110 return res;
111 }
112 else
113 #endif
114 {
115 SHFILEINFOW shellInfo;
116 shellInfo.szTypeName[0] = 0;
117 DWORD_PTR res = ::MySHGetFileInfoW(fileName, FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo,
118 sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX
119 | SHGFI_TYPENAME);
120 typeName = shellInfo.szTypeName;
121 iconIndex = shellInfo.iIcon;
122 return res;
123 }
124 }
125
GetIconIndex(UINT32 attributes,const UString & fileNameSpec,UString & typeName)126 int CExtToIconMap::GetIconIndex(UINT32 attributes, const UString &fileNameSpec, UString &typeName)
127 {
128 UString fileName = fileNameSpec;
129 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
130 {
131 fileName = L"__Fldr__";
132 if (_dirIconIndex < 0)
133 GetRealIconIndex(fileName, attributes, _dirIconIndex, _dirTypeName);
134 typeName = _dirTypeName;
135 return _dirIconIndex;
136 }
137 int dotPos = fileName.ReverseFind('.');
138 if (dotPos < 0)
139 {
140 fileName = L"__File__";
141 if (_noExtIconIndex < 0)
142 {
143 int iconIndexTemp;
144 GetRealIconIndex(fileName, attributes, iconIndexTemp, _noExtTypeName);
145 }
146 typeName = _noExtTypeName;
147 return _noExtIconIndex;
148 }
149 CExtIconPair extIconPair;
150 extIconPair.Ext = fileName.Mid(dotPos + 1);
151 int anIndex = _map.FindInSorted(extIconPair);
152 if (anIndex >= 0)
153 return _map[anIndex].IconIndex;
154 fileName = fileName.Mid(dotPos);
155 GetRealIconIndex(fileName, attributes, extIconPair.IconIndex, extIconPair.TypeName);
156 _map.AddToSorted(extIconPair);
157 typeName = extIconPair.TypeName;
158 return extIconPair.IconIndex;
159 }
160
GetIconIndex(UINT32 attributes,const UString & fileName)161 int CExtToIconMap::GetIconIndex(UINT32 attributes, const UString &fileName)
162 {
163 UString typeName;
164 return GetIconIndex(attributes, fileName, typeName);
165 }
166 #endif
167
168