本文示例源代碼或素材下載
大家都知道快捷方式會在原有的圖標左下方重疊個小箭頭的圖標,
文件夾共享也會在原有的圖標下面出現個手的圖標。
通過疊加圖標的顯示我們能很直觀的了解到該圖標所代表的含義,
下面我們就編寫一個圖標疊加擴展處理器,如果文件屬性為只讀的,就在圖標的右下方加個小鎖。
我們准備了一個16*16的小鎖圖標readonly.ico並存放到C:目錄下:
擴展接口
圖標疊加擴展處理器主要實現接口 IShellIconOverlayIdentifIEr
TIconOverlay
1type
2 TIconOverlay = class(TComObject, IShellIconOverlayIdentifIEr)
3 public
4 { IShellIconOverlayIdentifIEr }
5 //判斷疊加圖標是否應該添加到該Shell對象之上
6 function IsMemberOf(pwszPath: PWideChar; dwAttrib: DWord): HResult; stdcall;
7 //提供疊加圖標的路徑
8 function GetOverlayInfo(pwszIconFile: PWideChar; cchMax: Integer;
9 var pIndex: Integer; var pdwFlags: DWord): HResult; stdcall;
10 //設置疊加圖標的優先級
11 function GetPriority(out pIPriority: Integer): HResult; stdcall;
12 end;
IShellIconOverlayIdentifIEr 的 IsMemberOf首先被調用
參數:
pwszPath: Shell對象的完整路徑
dwAttrib: Shell對象的屬性
IsMemberOf
1function TIconOverlay.IsMemberOf(pwszPath: PWideChar; dwAttrib: DWord): HResult;
2begin
3 if (dwAttrib and faReadonly) = faReadonly then
4 Result := S_OK
5 else
6 Result := S_FALSE;
7end;
GetPriority設置顯示優先級,多個疊加圖標時有效
參數:
pIPriority: 可以設置為0-100之間的值,0的優先級別最高
GetPriority
1function TIconOverlay.GetPriority(out pIPriority: Integer): HResult;
2begin
3 pIPriority := 0;
4 Result := S_OK;
5end;
GetOverlayInfo在Shell啟動時加載圖標到系統圖標裡
參數:
pwszIconFile: Icon圖標的完整路徑,可以是.exe,.dll和.ico文件類型
cchMax: pwszIconFile 的 buffer大小
pIndex: 如果文件包含多個圖標的話指定使用圖標的索引值
pdwFlags: 指定返回什麼類型的信息
ISIOI_ICONFILE: 返回pwszIconFile的路徑信息
ISIOI_ICONINDEX: 返回pIndex的索引值
可以使用其中一種標識或者兩者一起使用
GetOverlayInfo
1function TIconOverlay.GetOverlayInfo(pwszIconFile: PWideChar; cchMax: Integer;
2 var pIndex: Integer; var pdwFlags: DWord): HResult;
3var
4 OverlayPath: WideString;
5begin
6 OverlayPath := 'C:readonly.ico';
7 lstrcpynW(pwszIconFile, PWideChar(OverlayPath), cchMax);
8 pdwFlags := ISIOI_ICONFILE;
9 Result := S_OK;
10end;
實現擴展接口後接下來就是注冊擴展
UpdateRegistry
1procedure TIconOverlayFactory.UpdateRegistry(Register: Boolean);
2var
3 ClassID: string;
4begin
5 if Register then
6 begin
7 inherited UpdateRegistry(Register);
8
9 ClassID := GUIDToString(Class_IconOverlay);
10 CreateRegKey('SoftwareMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifIErsShellExt', '', ClassID, HKEY_LOCAL_MacHINE);
11 if (Win32Platform = VER_PLATFORM_WIN32_NT) then
12 with TRegistry.Create do
13 try
14 RootKey := HKEY_LOCAL_MacHINE;
15 OpenKey('SOFTWAREMicrosoftWindowsCurrentVersionShell Extensions', True);
16 OpenKey('Approved', True);
17 WriteString(ClassID, 'Icon Overlay Shell Extension');
18 finally
19 Free;
20 end;
21 end
22 else begin
23 DeleteRegKey('SoftwareMicrosoftWindowsCurrentVersionExplorerShellIconOverlayIdentifIErsShellExt', HKEY_LOCAL_MacHINE);
24 inherited UpdateRegistry(Register);
25 end;
26end;
使用Regsvr32注冊完我們的dll後並不能馬上看到效果,因為圖標是在Shell啟動時才加載的。
重啟Explorer或者新開個Explorer進程就可以看到效果了。
由於只是個簡單的應用,在IsMemberOf裡只用了dwAttrib就可以判斷只讀屬性了,並沒有用到pwszPath參數。
根據這個參數我們可以定制很多種其他的應用。