大家都知道快捷方式会在原有的图标左下方重叠个小箭头的图标,
文件夹共享也会在原有的图标下面出现个手的图标。
通过叠加图标的显示我们能很直观的了解到该图标所代表的含义,
下面我们就编写一个图标叠加扩展处理器,如果文件属性为只读的,就在图标的右下方加个小锁。
我们准备了一个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('Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\ShellExt', '', 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('SOFTWARE\Microsoft\Windows\CurrentVersion\Shell 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('Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\ShellExt', HKEY_LOCAL_MACHINE);
24 inherited UpdateRegistry(Register);
25 end;
26end;
使用Regsvr32注册完我们的dll后并不能马上看到效果,因为图标是在Shell启动时才加载的。
重启Explorer或者新开个Explorer进程就可以看到效果了。
由于只是个简单的应用,在IsMemberOf里只用了dwAttrib就可以判断只读属性了,并没有用到pwszPath参数。
根据这个参数我们可以定制很多种其他的应用。
Demo下载: ShellExt.rar