【问题标题】:Shell overlay icon is not displayed外壳覆盖图标不显示
【发布时间】:2012-10-02 13:05:06
【问题描述】:

我正在尝试为我的应用实现自定义叠加图标。这是(简化的)代码:

[ComVisible(true)]
[Guid("30BD35BE-D5CE-4751-A3B3-9D601F926E36")]
public abstract class OverlayIconBase : IShellIconOverlayIdentifier
{
    private const string OverlayIdentifiersKeyPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers";
    private readonly string _iconFileName;
    protected OverlayIconBase()
    {
        _iconFileName = GetType().Assembly.Location;
    }

    protected static void Register(Type type, string registrationName)
    {
        string guid = type.GUID.ToString("B").ToUpper();

        string keyPath = OverlayIdentifiersKeyPath + "\\" + registrationName;
        using (var key = Registry.LocalMachine.CreateSubKey(keyPath))
        {
            key.SetValue(string.Empty, guid);
        }

        NativeMethods.SHChangeNotify(SHChangeNotifyEvents.AssocChanged, SHChangeNotifyFlags.IdList, IntPtr.Zero, IntPtr.Zero);
    }

    protected static void Unregister(Type type, string registrationName)
    {
        string keyPath = OverlayIdentifiersKeyPath + "\\" + registrationName;
        Registry.LocalMachine.DeleteSubKeyTree(keyPath, false);

        NativeMethods.SHChangeNotify(SHChangeNotifyEvents.AssocChanged, SHChangeNotifyFlags.IdList, IntPtr.Zero, IntPtr.Zero);
    }

    public int IsMemberOf(string path, uint attributes)
    {
        try
        {
            return ShouldDisplay(path) ? WinError.S_OK : WinError.S_FALSE;
        }
        catch
        {
            return WinError.E_FAIL;
        }
    }

    public int GetOverlayInfo(IntPtr pwszIconFile, int cchMax, out int iconIndex, out uint flags)
    {
        iconIndex = 0;
        flags = 0;
        if (string.IsNullOrEmpty(_iconFileName) || fileName.Length + 2 > cchMax)
            return WinError.E_FAIL;

        int count = Encoding.Unicode.GetByteCount(_iconFileName);
        byte[] bytes = new byte[count + 2];
        Encoding.Unicode.GetBytes(_iconFileName, 0, _iconFileName.Length, bytes, 0);
        Marshal.Copy(bytes, 0, pwszIconFile, bytes.Length);
        iconIndex = IconIndex;
        flags = (uint) (ShellIconOverlayIdentifierFlags.ISIOI_ICONFILE | ShellIconOverlayIdentifierFlags.ISIOI_ICONINDEX);
        return WinError.S_OK;
    }

    public int GetPriority(out int priority)
    {
        priority = Priority;
        return WinError.S_OK;
    }

    // 0-100 (0: highest); typically 0
    protected virtual int Priority { get { return 0; } }

    protected abstract bool ShouldDisplay(string path);
    protected abstract int IconIndex { get; }
}

[ComVisible(true)]
[Guid("76344480-04C1-4D15-A0A5-578881CEF415")]
public class MyOverlayIcon1 : OverlayIconBase
{
    private const string RegistrationName = "MyOverlayIcon1";

    [ComRegisterFunction]
    static void Register(Type t)
    {
        Register(t, RegistrationName);
    }

    [ComUnregisterFunction]
    static void Unregister(Type t)
    {
        Unregister(t, RegistrationName);
    }

    protected override bool ShouldDisplay(string path)
    {
        /* some logic to decide if the overlay should be displayed... */
    }

    protected override int IconIndex
    {
        get { return 0; }
    }
}

图标使用 Win32Res 嵌入到 DLL 中,如 here 所述。

通过使用 Debugger.Launch 附加到 explorer.exe,我能够确认 GetOverlayInfoIsMemberOf 可以按预期工作,但是覆盖不会显示在资源管理器中。

可能是什么问题?

【问题讨论】:

  • 如果您有兴趣,有一种管理方式可以做到这一点。 stackoverflow.com/q/9182693/945456
  • @JeffBridgman,谢谢,但这不是我要找的...我想在资源管理器中的文件图标上显示叠加层,而不是在任务栏图标上
  • 糟糕!我错过了“外壳”部分。感谢您的澄清!

标签: c# .net shell icons overlay


【解决方案1】:

您可能遇到了与此线程中讨论的类似的问题。 Tortoise-svn icons not showing up under windows 7

【讨论】:

  • 是的,这似乎是原因......我也在使用 TortoiseSVN(9 个叠加层)和 DropBox(4 个叠加层),所以我达到了极限。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-05
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多