第 ⑪ 章 · 图标叠加处理器(IShellIconOverlayIdentifier)
给文件图标左下角叠一个小角标——OneDrive/Dropbox/TortoiseGit 的同步状态标就是它;讲 IsMemberOf 判定、15 个槽位的硬上限与抢位技巧、以及“必须快”的铁律。
作者 David更新于
你一定见过 OneDrive/Dropbox 文件图标左下角那个“同步中/已同步”的小角标,或者 TortoiseGit 里绿勾红叹号——它们全是图标叠加处理器。这是最能出效果、也最容易把资源管理器拖卡的一种扩展。配套代码:11-icon-overlay。
只有一个接口,三个方法
IShellIconOverlayIdentifier——不需要任何初始化接口,因为判定方法直接把路径给你:
| 方法 | 作用 |
|---|---|
GetOverlayInfo | 叠加图标从哪个文件、第几个图标取(返回 .ico/DLL 路径 + 索引) |
GetPriority | 多个叠加同时命中一个文件时的排序,0 最高 |
IsMemberOf(path, attrib) | 核心判定:这个文件要不要叠?S_OK 叠,S_FALSE 不叠 |
// 演示规则:文件名含 “demo” 就叠标记
IFACEMETHODIMP OverlayHandler::IsMemberOf(LPCWSTR pwszPath, DWORD) {
return (StrStrIW(pwszPath, L"demo") != nullptr) ? S_OK : S_FALSE;
}
// 叠加图标:演示用 shell32.dll 占位,真实项目换成自带 .ico
IFACEMETHODIMP OverlayHandler::GetOverlayInfo(LPWSTR file, int cch, int* pIndex, DWORD* pdwFlags) {
GetSystemDirectoryW(file, cch);
StringCchCatW(file, cch, L"\\shell32.dll");
*pIndex = 0;
*pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
return S_OK;
}两条硬约束(决定成败)
① 只有前 15 个生效。 系统对叠加处理器有全局硬上限:注册在 ShellIconOverlayIdentifiers 下的项按名字排序,只取前 15 个,多的直接忽略。这就是为什么 TortoiseGit、Dropbox 的注册名前面加空格甚至多个空格——空格排在字母前,用来抢靠前的槽位。本示例也用了 DaiwDemoOverlay(前置空格)这一招。
② IsMemberOf 必须快。 它会对资源管理器里每一个显示的文件被调用。任何阻塞操作(读文件内容、查数据库、访问网络)都会让整个窗口卡死。真实扩展的做法是:后台线程维护一份内存缓存,IsMemberOf 只查缓存、立刻返回。
注册与生效
叠加处理器登记在 HKLM(机器级,需管理员):
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\
⟨ 名字(前置空格抢槽位)⟩\ (默认) = {你的CLSID}改完注册必须重启资源管理器(Stop-Process -Name explorer -Force)才会重新扫描叠加列表——这点和右键菜单不同,光刷新是不够的。
参考
- IShellIconOverlayIdentifier · How to Implement Icon Overlay Handlers
- 云存储的现代替代方案:云文件 API(Cloud Filter),它有自己的一套状态角标机制。