如何创建图标处理程序

文件类型通常具有与之关联的自定义图标,以使其成员在 Windows 资源管理器中易于识别。 将自定义图标分配给文件类型的最简单方法是注册图标的文件。 但是,以这种方式注册的图标对于文件类型的所有成员都是相同的。 通过实现图标 处理程序,可以更加灵活地将图标分配给文件类型的成员。

图标处理程序是一种 Shell 扩展处理程序,可用于将图标动态分配给文件类型的成员。 每次显示类型的文件时,Shell 都会在处理程序中查询相应的图标。 例如,图标处理程序可以将不同的图标分配给文件类型的不同成员,或者根据文件的当前状态改变图标。

创建 Shell 扩展处理程序中讨论了实现和注册 Shell 扩展处理程序的一般过程。 本文档重点介绍特定于图标处理程序的实现的那些方面。

Instructions

步骤 1:实现图标处理程序

与所有 Shell 扩展处理程序一样,图标处理程序是进程内组件对象模型 (COM) 作为 DLL 实现的对象。 除了 IUnknown 之外,它们还必须导出两个接口: IPersistFileIExtractIcon

Shell 通过其 IPersistFile 接口初始化处理程序。 它使用此接口 (CLSID) 请求处理程序的类标识符,并为其提供文件的名称。 操作的其余部分通过 IExtractIcon 接口进行。 有关如何实现 Shell 扩展处理程序(包括 IPersistFile 接口)的一般讨论,请参阅 创建 Shell 扩展处理程序。 本文档的其余部分讨论如何实现 IExtractIcon 接口。

步骤 2:实现 IExtractIcon 接口

初始化接口后,Shell 使用处理程序的 IExtractIcon 接口请求相应的图标。 接口有两种方法: IExtractIcon::GetIconLocationIExtractIcon::Extract

图标由它们在文件系统中的位置标识。 调用 IExtractIcon::GetIconLocation 方法来请求此信息。 将 szIconFile 参数设置为文件名。 如果文件中有多个图标,请将 piIndex 设置为图标的索引。 将适当的值分配给两个标志变量。 如果不想指定文件名,或者不希望 Shell 提取图标,请在 pwFlags 参数中设置GIL_NOTFILENAME标志。 无需将值分配给 szIconFile,但当 Shell 调用 IExtractIcon::Extract 时,处理程序必须提供图标句柄。

如果返回文件名,Shell 通常会尝试从其缓存加载图标。 若要防止加载缓存的图标,请在 pwFlags 参数中设置GIL_DONTCACHE标志。 如果未加载缓存的图标,Shell 会调用 IExtractIcon::Extract 来请求图标句柄。

如果文件和索引是由 IExtractIcon::GetIconLocation 指定的,它们将分别传递到 pszFilenIconIndex 参数中的 IExtractIcon::Extract。 如果提供了文件名,处理程序可以返回S_FALSE让 Shell 提取图标。 否则,处理程序必须提取或生成大图标和小图标,并将其 HICON 句柄分配给 phiconLargephiconSmall 参数。 Shell 将图标添加到其缓存,以加快对处理程序的后续调用。

步骤 3:注册图标处理程序

静态注册某个文件类型的图标时,将在 ProgID 下的文件类型下创建一个 DefaultIcon 子项。 其默认值设置为包含图标的文件。 若要注册图标处理程序,必须仍具有 DefaultIcon 子项,但其默认值必须设置为“%1”。 将 IconHandler 子项添加到 ProgID 子项的 Shellex 子项,并将其默认值设置为处理程序的 CLSID GUID 的字符串形式。 有关如何注册 Shell 扩展处理程序的一般讨论,请参阅 创建 Shell 扩展处理程序

下面的示例修改了 自定义图标 中的注册表项,以便 .myp 文件类型现在使用快捷菜单处理程序而不是静态定义的图标。

HKEY_CLASSES_ROOT
   .myp
      (Default) = MyProgram.1
   MyProgram.1
      (Default) = MyProgram Application
      DefaultIcon
         (Default) = %1
      Shellex
         IconHandler
            (Default) = {The handler's CLSID GUID}

创建 Shell 扩展处理程序

IPersistFile

IExtractIcon