第 ⑪ 章 · 图标叠加处理器(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 不叠
OverlayHandler.cpp(节选)——判定与取图标
// 演示规则:文件名含 “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)才会重新扫描叠加列表——这点和右键菜单不同,光刷新是不够的。

参考

本页目录