00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "ShellIcons.h"
00025
00026 #ifdef _DEBUG
00027 #undef THIS_FILE
00028 static char THIS_FILE[]=__FILE__;
00029 #define new DEBUG_NEW
00030 #endif
00031
00032 CShellIcons ShellIcons;
00033
00035
00036
00037 CShellIcons::CShellIcons()
00038 {
00039 m_hUser = LoadLibrary( _T("User32.dll") );
00040 m_pfnPrivate = NULL;
00041
00042 if ( m_hUser != NULL )
00043 {
00044 #ifdef UNICODE
00045 (FARPROC&)m_pfnPrivate = GetProcAddress( m_hUser, "PrivateExtractIconsW" );
00046 #else
00047 (FARPROC&)m_pfnPrivate = GetProcAddress( m_hUser, "PrivateExtractIconsA" );
00048 #endif
00049 }
00050 }
00051
00052 CShellIcons::~CShellIcons()
00053 {
00054 if ( m_hUser ) FreeLibrary( m_hUser );
00055 }
00056
00058
00059
00060 void CShellIcons::Clear()
00061 {
00062 if ( m_i16.m_hImageList ) m_i16.DeleteImageList();
00063 if ( m_i32.m_hImageList ) m_i32.DeleteImageList();
00064 if ( m_i48.m_hImageList ) m_i48.DeleteImageList();
00065
00066 m_i16.Create( 16, 16, ILC_COLOR32|ILC_MASK, SHI_MAX, 4 );
00067 m_i32.Create( 32, 32, ILC_COLOR32|ILC_MASK, 1, 4 );
00068 m_i48.Create( 48, 48, ILC_COLOR32|ILC_MASK, 1, 4 );
00069
00070 CBitmap bmBase;
00071 HICON hTemp;
00072
00073 if ( theApp.m_bRTL )
00074 bmBase.LoadBitmap( IDB_SHELL_BASE_RTL );
00075 else
00076 bmBase.LoadBitmap( IDB_SHELL_BASE );
00077 m_i16.Add( &bmBase, RGB( 0, 255, 0 ) );
00078 m_i16.SetOverlayImage( SHI_LOCKED, SHI_O_LOCKED );
00079 m_i16.SetOverlayImage( SHI_PARTIAL, SHI_O_PARTIAL );
00080 m_i16.SetOverlayImage( SHI_COLLECTION, SHI_O_COLLECTION );
00081 m_i16.SetOverlayImage( SHI_COMMERCIAL, SHI_O_COMMERCIAL );
00082 m_i16.SetOverlayImage( SHI_RATING_FAKE, SHI_O_RATING_FAKE );
00083 m_i16.SetOverlayImage( SHI_RATING_AVERAGE, SHI_O_RATING_AVERAGE );
00084 m_i16.SetOverlayImage( SHI_RATING_GOOD, SHI_O_RATING_GOOD );
00085
00086 hTemp = (HICON)LoadImage( AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_FILE), IMAGE_ICON, 32, 32, 0 );
00087 if ( theApp.m_bRTL ) hTemp = CreateMirroredIcon( hTemp );
00088 m_i32.Add( hTemp );
00089 DestroyIcon( hTemp );
00090 hTemp = (HICON)LoadImage( AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_FILE), IMAGE_ICON, 48, 48, 0 );
00091 if ( theApp.m_bRTL ) hTemp = CreateMirroredIcon( hTemp );
00092 m_i48.Add( hTemp );
00093 DestroyIcon( hTemp );
00094
00095 hTemp = (HICON)LoadImage( AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_EXECUTABLE), IMAGE_ICON, 32, 32, 0 );
00096 if ( theApp.m_bRTL ) hTemp = CreateMirroredIcon( hTemp );
00097 m_i32.Add( hTemp );
00098 DestroyIcon( hTemp );
00099 hTemp = (HICON)LoadImage( AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_EXECUTABLE), IMAGE_ICON, 48, 48, 0 );
00100 if ( theApp.m_bRTL ) hTemp = CreateMirroredIcon( hTemp );
00101 m_i48.Add( hTemp );
00102 DestroyIcon( hTemp );
00103
00104 hTemp = (HICON)LoadImage( AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_COLLECTION_MASK), IMAGE_ICON, 32, 32, 0 );
00105
00106 if ( theApp.m_bRTL ) hTemp = CreateMirroredIcon( hTemp );
00107 m_i32.SetOverlayImage( m_i32.Add( hTemp ), SHI_O_COLLECTION );
00108 DestroyIcon( hTemp );
00109 hTemp = (HICON)LoadImage( AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_COLLECTION_MASK), IMAGE_ICON, 48, 48, 0 );
00110
00111 if ( theApp.m_bRTL ) hTemp = CreateMirroredIcon( hTemp );
00112 m_i48.SetOverlayImage( m_i48.Add( hTemp ), SHI_O_COLLECTION );
00113 DestroyIcon( hTemp );
00114
00115 m_m16.RemoveAll();
00116 m_m32.RemoveAll();
00117 m_m48.RemoveAll();
00118
00119 m_m16.SetAt( _T(".exe"), (LPVOID)SHI_EXECUTABLE );
00120 m_m32.SetAt( _T(".exe"), (LPVOID)1 );
00121 m_m48.SetAt( _T(".exe"), (LPVOID)1 );
00122 }
00123
00125
00126
00127 int CShellIcons::Get(LPCTSTR pszFile, int nSize)
00128 {
00129 LPCTSTR pszType = _tcsrchr( pszFile, '.' );
00130 if ( pszType == NULL ) return 0;
00131
00132 if ( m_i16.m_hImageList == NULL ) Clear();
00133
00134 CString strType( pszType );
00135 CharLower( strType.GetBuffer() );
00136 strType.ReleaseBuffer();
00137
00138 HICON hIcon = NULL;
00139 int nIndex;
00140
00141 switch ( nSize )
00142 {
00143 case 16:
00144 if ( m_m16.Lookup( strType, (void*&)nIndex ) ) return nIndex;
00145 Lookup( pszType, &hIcon, NULL, NULL, NULL );
00146 nIndex = hIcon ? m_i16.Add( hIcon ) : 0;
00147 m_m16.SetAt( strType, (LPVOID)nIndex );
00148 break;
00149 case 32:
00150 if ( m_m32.Lookup( strType, (void*&)nIndex ) ) return nIndex;
00151 Lookup( pszType, NULL, &hIcon, NULL, NULL );
00152 nIndex = hIcon ? m_i32.Add( hIcon ) : 0;
00153 m_m32.SetAt( strType, (LPVOID)nIndex );
00154 break;
00155 case 48:
00156 if ( m_m48.Lookup( strType, (void*&)nIndex ) ) return nIndex;
00157 Lookup( pszType, NULL, NULL, NULL, NULL, &hIcon );
00158 nIndex = hIcon ? m_i48.Add( hIcon ) : 0;
00159 m_m48.SetAt( strType, (LPVOID)nIndex );
00160 break;
00161 }
00162
00163 if ( hIcon ) DestroyIcon( hIcon );
00164
00165 return nIndex;
00166 }
00167
00169
00170
00171 int CShellIcons::Add(HICON hIcon, int nSize)
00172 {
00173 if ( m_i16.m_hImageList == NULL ) Clear();
00174
00175 switch ( nSize )
00176 {
00177 case 16:
00178 return m_i16.Add( hIcon );
00179 case 32:
00180 return m_i32.Add( hIcon );
00181 case 48:
00182 return m_i48.Add( hIcon );
00183 default:
00184 return -1;
00185 }
00186 }
00187
00189
00190
00191 HICON CShellIcons::ExtractIcon(int nIndex, int nSize)
00192 {
00193 HICON hIcon;
00194 switch ( nSize )
00195 {
00196 case 16:
00197 hIcon = m_i16.ExtractIcon( nIndex );
00198 if ( theApp.m_bRTL ) hIcon = CreateMirroredIcon( hIcon );
00199 return hIcon;
00200 case 32:
00201 hIcon = m_i32.ExtractIcon( nIndex );
00202 if ( theApp.m_bRTL ) hIcon = CreateMirroredIcon( hIcon );
00203 return hIcon;
00204 case 48:
00205 hIcon = m_i48.ExtractIcon( nIndex );
00206 if ( theApp.m_bRTL ) hIcon = CreateMirroredIcon( hIcon );
00207 return hIcon;
00208 default:
00209 return NULL;
00210 }
00211 }
00212
00214
00215
00216 CString CShellIcons::GetTypeString(LPCTSTR pszFile)
00217 {
00218 CString strOutput;
00219
00220 LPCTSTR pszType = _tcsrchr( pszFile, '.' );
00221 if ( ! pszType ) return strOutput;
00222
00223 CString strName, strMime;
00224 Lookup( pszType, NULL, NULL, &strName, &strMime );
00225
00226 if ( strName.GetLength() )
00227 {
00228 strOutput = strName;
00229 if ( strMime.GetLength() ) strOutput += _T(" (") + strMime + _T(")");
00230 }
00231 else
00232 {
00233 strOutput = pszType + 1;
00234 }
00235
00236 return strOutput;
00237 }
00238
00240
00241
00242 BOOL CShellIcons::Lookup(LPCTSTR pszType, HICON* phSmallIcon, HICON* phLargeIcon, CString* psName, CString* psMIME, HICON* phHugeIcon)
00243 {
00244 DWORD nType, nResult;
00245 TCHAR szResult[128];
00246 HKEY hKey, hSub;
00247
00248 if ( phSmallIcon ) *phSmallIcon = NULL;
00249 if ( phLargeIcon ) *phLargeIcon = NULL;
00250 if ( psName ) *psName = pszType + 1;
00251 if ( psMIME ) psMIME->Empty();
00252
00253 if ( pszType == NULL || *pszType == 0 ) return FALSE;
00254
00255 if ( RegOpenKeyEx( HKEY_CLASSES_ROOT, pszType, 0, KEY_READ, &hKey ) != ERROR_SUCCESS ) return FALSE;
00256
00257 if ( psMIME )
00258 {
00259 nResult = sizeof(TCHAR) * 128; nType = REG_SZ;
00260 if ( RegQueryValueEx( hKey, _T("Content Type"), NULL, &nType, (LPBYTE)szResult, &nResult ) == ERROR_SUCCESS )
00261 {
00262 szResult[ nResult / sizeof(TCHAR) ] = 0;
00263 *psMIME = szResult;
00264 }
00265 }
00266
00267 nResult = sizeof(TCHAR) * 128; nType = REG_SZ;
00268 if ( RegQueryValueEx( hKey, _T(""), NULL, &nType, (LPBYTE)szResult, &nResult ) != ERROR_SUCCESS )
00269 {
00270 RegCloseKey( hKey );
00271 return FALSE;
00272 }
00273
00274 RegCloseKey( hKey );
00275 szResult[ nResult / sizeof(TCHAR) ] = 0;
00276
00277 if ( RegOpenKeyEx( HKEY_CLASSES_ROOT, szResult, 0, KEY_READ, &hKey ) != ERROR_SUCCESS ) return 0;
00278
00279 if ( psName )
00280 {
00281 nResult = sizeof(TCHAR) * 128; nType = REG_SZ;
00282 if ( RegQueryValueEx( hKey, _T(""), NULL, &nType, (LPBYTE)szResult, &nResult ) == ERROR_SUCCESS )
00283 {
00284 szResult[ nResult / sizeof(TCHAR) ] = 0;
00285 *psName = szResult;
00286 }
00287 }
00288
00289 if ( RegOpenKeyEx( hKey, _T("DefaultIcon"), 0, KEY_READ, &hSub ) != ERROR_SUCCESS )
00290 {
00291 if ( RegOpenKeyEx( hKey, _T("CurVer"), 0, KEY_READ, &hSub ) != ERROR_SUCCESS )
00292 {
00293 RegCloseKey( hKey );
00294 return FALSE;
00295 }
00296 nResult = sizeof(TCHAR) * 128; nType = REG_SZ;
00297 if ( RegQueryValueEx( hSub, _T(""), NULL, &nType, (LPBYTE)szResult, &nResult ) != ERROR_SUCCESS )
00298 {
00299 RegCloseKey( hSub );
00300 RegCloseKey( hKey );
00301 return FALSE;
00302 }
00303 RegCloseKey( hKey );
00304 szResult[ nResult / sizeof(TCHAR) ] = 0;
00305
00306 if ( RegOpenKeyEx( HKEY_CLASSES_ROOT, szResult, 0, KEY_READ, &hKey ) != ERROR_SUCCESS ) return 0;
00307 if ( psName )
00308 {
00309 nResult = sizeof(TCHAR) * 128; nType = REG_SZ;
00310 if ( RegQueryValueEx( hKey, _T(""), NULL, &nType, (LPBYTE)szResult, &nResult ) == ERROR_SUCCESS )
00311 {
00312 szResult[ nResult / sizeof(TCHAR) ] = 0;
00313 *psName = szResult;
00314 }
00315 }
00316
00317 if ( RegOpenKeyEx( hKey, _T("DefaultIcon"), 0, KEY_READ, &hSub ) != ERROR_SUCCESS )
00318 {
00319 RegCloseKey( hKey );
00320 return FALSE;
00321 }
00322 }
00323
00324 nResult = sizeof(TCHAR) * 128; nType = REG_SZ;
00325 if ( RegQueryValueEx( hSub, _T(""), NULL, &nType, (LPBYTE)szResult, &nResult ) != ERROR_SUCCESS )
00326 {
00327 RegCloseKey( hSub );
00328 RegCloseKey( hKey );
00329 return FALSE;
00330 }
00331
00332 RegCloseKey( hSub );
00333 RegCloseKey( hKey );
00334 szResult[ nResult / sizeof(TCHAR) ] = 0;
00335
00336 CString strIcon( szResult );
00337
00338 int nIcon, nIndex = strIcon.ReverseFind( ',' );
00339 if ( nIndex < 0 && strIcon.Right(3).MakeLower() != _T("ico") ) return 0;
00340
00341 if ( nIndex != -1 )
00342 {
00343 if ( _stscanf( strIcon.Mid( nIndex + 1 ), _T("%i"), &nIcon ) != 1 ) return FALSE;
00344 strIcon = strIcon.Left( nIndex );
00345 }
00346 else nIndex = nIcon = 0;
00347
00348 if ( strIcon.GetLength() < 3 ) return FALSE;
00349
00350 if ( strIcon.GetAt( 0 ) == '\"' && strIcon.GetAt( strIcon.GetLength() - 1 ) == '\"' )
00351 strIcon = strIcon.Mid( 1, strIcon.GetLength() - 2 );
00352
00353 BOOL bSuccess = FALSE;
00354
00355 if ( phLargeIcon || phSmallIcon )
00356 {
00357 if ( ExtractIconEx( strIcon, nIcon, phLargeIcon, phSmallIcon, 1 ) )
00358 {
00359 bSuccess |= ( phLargeIcon && *phLargeIcon ) || ( phSmallIcon && *phSmallIcon );
00360 if ( theApp.m_bRTL )
00361 {
00362 if ( phLargeIcon && *phLargeIcon )
00363 *phLargeIcon = CreateMirroredIcon( *phLargeIcon );
00364 if ( phSmallIcon && *phSmallIcon )
00365 *phSmallIcon = CreateMirroredIcon( *phSmallIcon );
00366 }
00367 }
00368 }
00369
00370 if ( m_pfnPrivate && phHugeIcon )
00371 {
00372 UINT nLoadedID;
00373
00374 if ( (*m_pfnPrivate)( strIcon, nIcon, 48, 48, phHugeIcon, &nLoadedID, 1, 0 ) )
00375 {
00376 bSuccess = TRUE;
00377 if ( phHugeIcon && *phHugeIcon && theApp.m_bRTL )
00378 *phHugeIcon = CreateMirroredIcon( *phHugeIcon );
00379 }
00380 }
00381
00382 return bSuccess != 0;
00383 }
00384
00386
00387
00388 void CShellIcons::Draw(CDC* pDC, int nIcon, int nSize, int nX, int nY, COLORREF crBack, BOOL bSelected)
00389 {
00390 ImageList_DrawEx( ShellIcons.GetHandle( nSize ), nIcon, pDC->GetSafeHdc(),
00391 nX, nY, nSize, nSize, crBack, CLR_DEFAULT, bSelected ? ILD_SELECTED : ILD_NORMAL );
00392
00393 if ( crBack != CLR_NONE ) pDC->ExcludeClipRect( nX, nY, nX + nSize, nY + nSize );
00394 }