如何更改文件类型的某些文件的图标?

时间:2013-03-25 09:01:46

标签: visual-c++ explorer windows-shell shell-extensions

我有IconHandler来更改某些文件的图标。但其他文件图标变为空白。如何为其他文件保留默认图标?

 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;
 }

这是我的.rgs文件:

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}'
        }
    }
}

2 个答案:

答案 0 :(得分:1)

此代码有效:

 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;
}

更改了.rgs文件:

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}'
        }
    }
}

来自“MSDN” - How to Create Icon Handlers

  

注册图标处理程序

     

当您静态注册文件类型的图标时,您创建一个   用于文件类型的ProgID下的DefaultIcon子项。它的默认值   value设置为包含图标的文件。注册图标   处理程序,您必须仍具有DefaultIcon子项,但它的默认值   值必须设置为“%1”。

答案 1 :(得分:0)

您可以通过将虚拟名称传递给SHGetFileInfo来完成此操作。例如,

 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;
 }

关键是传递SHGFI_USEFILEATTRIBUTES标志,这意味着您提供的文件名不需要引用真实文件。  提供没有文件扩展名的文件名(如上例所示)将意味着您将返回系统的默认文件图标。  最后,SHGFI_ICONLOCATION标志返回SHFILEINFO结构字段中的图标路径和索引。