2012-10-02 5 views
1

내 응용 프로그램에 대한 사용자 정의 오버레이 아이콘을 구현하려고합니다. 여기 (간체) 코드는 다음과 같습니다 here 설명으로쉘 오버레이 아이콘이 표시되지 않습니다.

[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에 포함됩니다.

Debugger.Launch으로 explorer.exe에 연결하면 예상대로 오버레이가 표시되지 않지만 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 오버레이)를 사용하여 한계를 맞추고있었습니다. 감사! –

관련 문제