barbaris
barbaris

Reputation: 515

How to change icon for a some files of file type?

I have IconHandler to change icon for some files. But other files icons becomes blank. How to leave default icon for other files?

 HRESULT CSimpleShlExt::GetIconLocation(UINT uFlags,
  PTSTR pszIconFile,
  UINT cchMax,
  int *piIndex,
  UINT *pwFlags)
 { 
    if (condition)){
        // works well
        lstrcpyn(pszIconFile, L"C:\\Windows\\System32\\shell32.dll", cchMax);
        *piIndex = 5;
        *pwFlags = 0;
    } else {
        // blank icon :(
        *pwFlags = GIL_PERINSTANCE | GIL_NOTFILENAME;// | GIL_DONTCACHE ;
    }
    return S_OK;
 }

Here is my .rgs file:

HKCR  
{
    NoRemove CLSID
{
    ForceRemove {B70B7A24-5180-4092-B3BA-6266F914C053} = s 'My Shell Extension'
    {
        InprocServer32 = s '%MODULE%'
        {
            val ThreadingModel = s 'Apartment'
        }
        TypeLib = s '{62C6D1EB-C172-4E05-BFD2-5F9313832CC3}'
        Version = s '1.0'
    }
}
    NoRemove txtfile
    {
        NoRemove ShellEx
        {
            ForceRemove IconHandler = s '{B70B7A24-5180-4092-B3BA-6266F914C053}'
        }
    }
}

Upvotes: 3

Views: 1597

Answers (2)

Jonathan Potter
Jonathan Potter

Reputation: 37132

You could do this by passing through a dummy name to SHGetFileInfo. For example,

 HRESULT CSimpleShlExt::GetIconLocation(UINT uFlags,
  PTSTR pszIconFile,
  UINT cchMax,
  int *piIndex,
  UINT *pwFlags)
 { 
    if (condition){
        // works well
        lstrcpyn(pszIconFile, L"C:\\Windows\\System32\\shell32.dll", cchMax);
        *piIndex = 5;
        *pwFlags = 0;
    } else {
        SHFILEINFO sfi;
        SHGetFileInfo(L"dummy", FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi),
            SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
        StringCchCopy(pszIconFile, cchMax, sfi.szDisplayName);
        *piIndex = sfi.iIcon;
        *pwFlags = 0;
    }
    return S_OK;
 }

The key is to pass the SHGFI_USEFILEATTRIBUTES flag, which means the filename you provide does not need to refer to a real file. Providing a filename without a file extension (as in the above example) will mean you get back the system's default file icon. And finally the SHGFI_ICONLOCATION flag returns the icon path and index in the fields of the SHFILEINFO structure.

Upvotes: 0

Xearinox
Xearinox

Reputation: 3234

This code works:

 HRESULT CSimpleShlExt::GetIconLocation(UINT uFlags,
 PTSTR pszIconFile,
 UINT cchMax,
 int *piIndex,
 UINT *pwFlags)
 { 

    if (condition))
    {
        lstrcpyn(pszIconFile, L"C:\\Windows\\System32\\Test.dll", cchMax);

        *piIndex = 0;
    } 
    else 
    {
        *piIndex = 1;

    }

    *pwFlags = 0;
    return S_OK;

 }

HRESULT CSimpleShlExt::Extract(
LPCTSTR pszFile,
UINT nIconIndex,
HICON *phiconLarge,
HICON *phiconSmall,
UINT nIconSize)
{
    return S_FALSE;
}

Changed .rgs file:

HKCR  
{
    NoRemove CLSID
{
    ForceRemove {B70B7A24-5180-4092-B3BA-6266F914C053} = s 'My Shell Extension'
    {
        InprocServer32 = s '%MODULE%'
        {
            val ThreadingModel = s 'Apartment'
        }
        TypeLib = s '{62C6D1EB-C172-4E05-BFD2-5F9313832CC3}'
        Version = s '1.0'
    }
}
    NoRemove txtfile
    {
        NoRemove DefaultIcon = s '%%1'
        NoRemove ShellEx
        {
            ForceRemove IconHandler = s '{B70B7A24-5180-4092-B3BA-6266F914C053}'
        }
    }
}

From 'MSDN' - How to Create Icon Handlers:

Registering Icon Handlers

When you statically register an icon for a file type, you create a DefaultIcon subkey under the ProgID for the file type. Its default value is set to the file that contains the icon. To register an icon handler, you must still have the DefaultIcon subkey, but its default value must be set to "%1".

Upvotes: 1

Related Questions