2012-10-02 147 views
1

我正在尝试为我的应用实现自定义覆盖图标。这里的(简化的)代码:不显示外壳覆盖图标

[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

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

可能是什么问题?

+0

如果您有兴趣,有一种管理方式可以做到这一点。 http://stackoverflow.com/q/9182693/945456 –

+0

@JeffBridgman,谢谢,但那不是我正在寻找的...我想在资源管理器中显示文件图标上的覆盖图,而不是在任务栏图标上 –

+0

糟糕!我错过了“壳”部分。感谢您的澄清! –

回答

2

您可能遇到了与本主题中提到的相似的问题。 Tortoise-svn icons not showing up under windows 7

+0

是的,这似乎是原因...我也使用TortoiseSVN(9覆盖)和DropBox(4覆盖),所以我达到了极限。谢谢! –