3

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}'
        }
    }
}
Xearinox
  • 3,224
  • 2
  • 24
  • 38
barbaris
  • 514
  • 8
  • 25

2 Answers2

1

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".

Xearinox
  • 3,224
  • 2
  • 24
  • 38
0

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.

Jonathan Potter
  • 36,172
  • 4
  • 64
  • 79
  • You still need DefaultIcon key set to %1. – Xearinox Apr 02 '13 at 07:35
  • Added bounty, but your answer is not real answer. – Xearinox Apr 09 '13 at 20:55
  • Oh, well thanks for the bounty! But now I feel like it was undeserved. Exactly why didn't this answer help? What happened when you tried it? – Jonathan Potter Apr 09 '13 at 21:44
  • Without proper registration ---- DefaultIcon %1, Shell dont have knowledge what is 'Default Icon' :) – Xearinox Apr 10 '13 at 06:49
  • I'm not quite sure what you mean. The code I provided will return the default file icon (e.g. the icon for a file without a file extension). That doesn't require any special registry settings, that will just work as is. – Jonathan Potter Apr 10 '13 at 06:53
  • But question was (example): I have icon handler for .zzz file, if .zzz file has size greater than 1kb use my icon, else use DEFAULT icon. – Xearinox Apr 10 '13 at 06:57
  • Oh ok. Your question didn't make that clear. In that case I'm not sure how it could work, since you've replaced the original icon reference in the registry. You can't have two different sets of icons registered for the one filetype. You would need to save the old data somewhere else when installing your handler and refer to that. – Jonathan Potter Apr 10 '13 at 07:01
  • Yeah I know. But OP dont know. :) – Xearinox Apr 10 '13 at 07:08