【问题标题】:How to change icon for a some files of file type?如何更改某些文件类型的文件的图标?
【发布时间】:2013-03-14 17:01:02
【问题描述】:

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

【问题讨论】:

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


    【解决方案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 子项。它的默认值 值设置为包含图标的文件。注册图标 处理程序,您仍然必须有 DefaultIcon 子键,但它的默认值 值必须设置为“%1”。

    【讨论】:

    • 你的扩展是如何注册的?对于哪种文件类型?请上传您的 reg 文件。
    【解决方案2】:

    您可以通过将虚拟名称传递给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 结构字段中的图标路径和索引。

    【讨论】:

    • 您仍然需要将 DefaultIcon 键设置为 %1。
    • 增加了赏金,但你的答案不是真正的答案。
    • 哦,谢谢你的赏金!但现在我觉得这是不应该的。究竟为什么这个答案没有帮助?当你尝试它时发生了什么?
    • 如果没有正确注册 ---- DefaultIcon %1,Shell 不知道什么是“默认图标”:)
    • 我不太清楚你的意思。我提供的代码将返回默认文件图标(例如,没有文件扩展名的文件图标)。这不需要任何特殊的注册表设置,就可以按原样工作。
    猜你喜欢
    • 1970-01-01
    • 2021-07-21
    • 2018-10-13
    • 2012-02-21
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    相关资源
    最近更新 更多