本文示例源代碼或素材下載
大家都知道快捷方式會在原有的圖標左下方重疊個小箭頭的圖標,
文件夾共享也會在原有的圖標下面出現個手的圖標。

通過疊加圖標的顯示我們能很直觀的了解到該圖標所代表的含義,
下面我們就編寫一個圖標疊加擴展處理器,如果文件屬性為只讀的,就在圖標的右下方加個小鎖。
我們准備了一個16*16的小鎖圖標readonly.ico並存放到C:目錄下:
擴展接口
圖標疊加擴展處理器主要實現接口 IShellIconOverlayIdentifIEr
TIconOverlay
1
type
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
1
function TIconOverlay.IsMemberOf(pwszPath: PWideChar; dwAttrib: DWord): HResult;
2
begin
3
if (dwAttrib and faReadonly) = faReadonly then
4
Result := S_OK
5
else
6
Result := S_FALSE;
7
end;
GetPriority設置顯示優先級,多個疊加圖標時有效
參數:
pIPriority: 可以設置為0-100之間的值,0的優先級別最高
GetPriority
1
function TIconOverlay.GetPriority(out pIPriority: Integer): HResult;
2
begin
3
pIPriority := 0;
4
Result := S_OK;
5
end;
GetOverlayInfo在Shell啟動時加載圖標到系統圖標裡
參數:
pwszIconFile: Icon圖標的完整路徑,可以是.exe,.dll和.ico文件類型
cchMax: pwszIconFile 的 buffer大小
pIndex: 如果文件包含多個圖標的話指定使用圖標的索引值
pdwFlags: 指定返回什麼類型的信息
ISIOI_ICONFILE: 返回pwszIconFile的路徑信息
ISIOI_ICONINDEX: 返回pIndex的索引值
可以使用其中一種標識或者兩者一起使用
GetOverlayInfo
1
function TIconOverlay.GetOverlayInfo(pwszIconFile: PWideChar; cchMax: Integer;
2
var pIndex: Integer; var pdwFlags: DWord): HResult;
3
var
4
OverlayPath: WideString;
5
begin
6
OverlayPath := 'C:readonly.ico';
7
lstrcpynW(pwszIconFile, PWideChar(OverlayPath), cchMax);
8
pdwFlags := ISIOI_ICONFILE;
9
Result := S_OK;
10
end;
實現擴展接口後接下來就是注冊擴展
UpdateRegistry
1
procedure TIconOverlayFactory.UpdateRegistry(Register: Boolean);
2
var
3
ClassID: string;
4
begin
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;
26
end;
使用Regsvr32注冊完我們的dll後並不能馬上看到效果,因為圖標是在Shell啟動時才加載的。
重啟Explorer或者新開個Explorer進程就可以看到效果了。

由於只是個簡單的應用,在IsMemberOf裡只用了dwAttrib就可以判斷只讀屬性了,並沒有用到pwszPath參數。
根據這個參數我們可以定制很多種其他的應用。