【问题标题】:Custom icon overlays for namespace extension命名空间扩展的自定义图标覆盖
【发布时间】:2015-10-31 06:39:07
【问题描述】:

我正在实现代表服务器上远程文件系统的命名空间扩展,我希望图标覆盖以显示文件状态(锁定),就像这里的另一个问题一样:icon overlay handlers for namespace extension

那个问题已经回答了,我已经按照建议做了所有事情:

  1. 创建了附加的外壳扩展,并实现了 IShellIconOverlayIdentifier 接口: 在 IShellIconOverlayIdentifier.GetOverlayInfo 我返回图标文件和图标索引。 在 IShellIconOverlayIdentifier.IsMemberOf 中,我返回 S_FALSE 以不显示系统中任何其他文件的覆盖。

  2. 在主 NSE 中,我实现了 IShellIconOverlay 接口,并使用 SHGetIconOverlayIndex 函数从系统图像列表中检索我的图标覆盖。

问题是:SHGetIconOverlayIndex 总是返回-1。

但是!如果我返回 S_OK 作为 IShellIconOverlayIdentifier.IsMemberOf 的结果 - SHGetIconOverlayIndex 立即开始提供正确的覆盖索引!但当然,在这种情况下,我的叠加层会添加到系统中的所有文件中,包括我的 NSE。

有趣的是,如果我在 IShellIconOverlayIdentifier.IsMemberOf 的后续调用中返回 S_FALSE - SHGetIconOverlayIndex 仍然给出正确的覆盖索引,一切都变得很好:我只有 NSE 中有覆盖......

我做错了什么以及如何从一开始就得到这个结果?可能是缓存问题?..

(抱歉,我无法将其写为对所提及问题的评论,因为我没有足够的声誉......)

【问题讨论】:

  • 您的系统中注册了多少个图标处理程序?
  • 我的意思是覆盖图标处理程序。
  • @Denis,你是天才!是的,我的开发系统中有超过 15 个,所以我将“000”字符放在注册表中名称的开头以将其放置在更高的位置。刚刚在另一个系统上尝试了它,只注册了 4 个非系统覆盖处理程序 - 它从一开始就加载了我的图标!我怎样才能在第一个系统上得到这个结果?重置一些外壳图标缓存?..
  • 试图在 NSE dll 附加上调用 FileIconInit(TRUE) - 没有帮助。

标签: windows com atl windows-shell shell-extensions


【解决方案1】:

看起来您遇到的问题没有正确的解决方案。也许我错了,但我认为 Windows 可以使用以下规则:

1) 在开始时,shell 有覆盖图标列表,其中仅包含默认覆盖图标(4 个图标,在 Windows 的下一版本中,此值可以更大)。

2) 当任何覆盖图标处理程序在调用 IShellIconOverlayIdentifier.IsMemberOf 时返回 S_OK 时,shell 会将其图标添加到覆盖图标列表中。

3) shell 图标列表中覆盖图标的最大数量为 15(4 个默认 + 11 个外部)。

4) 因此只有 11 个返回 S_OK 的第一个图标处理程序将被添加到外壳图标列表中。其他将被忽略。

因此,即使您将注册表项重命名为 000,其他图标处理程序也可能在您的处理程序之前返回 S_OK。

所以我的建议是为您的 NSE 对象创建带有叠加图像的完整图标。

【讨论】:

  • 最后我得到了基于你的“规则”的棘手解决方案:当 SHGetIconOverlayIndex 在我的 NSE 中返回 -1 时,我调用 SHGetFileInfo 函数传递一些唯一的文件名和 SHGFI_ICON | SHGFI_ADDOVERLAYS 标志。这会导致调用我的 IShellIconOverlayIdentifier.IsMemberOf,我在其中检查该唯一文件名并返回 S_OK。所有这些都像我的图标覆盖的预加载一样,以便后续调用 SHGetIconOverlayIndex 工作正常 :))) 感谢您为我指明正确的方向!
  • 预加载图标也可以尝试使用函数 SHLoadNonloadedIconOverlayIdentifiers。
  • 试过 SHLoadNonloadedIconOverlayIdentifiers,但在我的情况下它不起作用。我认为它仍然需要至少一次成功调用 IShellIconOverlayIdentifier.IsMemberOf。
  • @Alexey 嗨,Alexey,我也面临同样的问题 - 如果您的 IsMemberOf 总是返回 false,我不会感到不安?我只需要我的命名空间扩展中的图标
  • @ArielB,在简单的情况下,如果系统中的覆盖图标少于 15 个 - 是的,IsMemberOf 总是返回 S_FALSE,因为它从未调用我的 NSE 的虚拟项目。所以我通过 NSE 的 IShellIconOverlay 接口将覆盖索引返回给 shell。
猜你喜欢
  • 2014-01-25
  • 2014-06-16
  • 2017-02-16
  • 1970-01-01
  • 1970-01-01
  • 2017-08-24
  • 1970-01-01
  • 1970-01-01
  • 2023-01-04
相关资源
最近更新 更多