2012-10-02 113 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覆蓋),所以我達到了極限。謝謝! –