SWF 摘要 Shell 扩展 (SWF 文件的属性页!)





5.00/5 (3投票s)
此应用程序向 Windows 文件属性窗口添加一个属性页,用于显示 SWF 文件的属性。
简介与背景
在过去的两个星期里,我一直在网上搜寻能够轻松确定 Flash SWF 文件宽度/高度和版本的方法。不用说,什么都没找到!至少我没找到…… 然后我说——“好吧,那我来做一个!” 因此,我决定开发一个能在查看 SWF 文件属性时,“摘要”选项卡中添加所需信息的工具。但我搜遍了,也没找到任何关于如何实现我想要的功能的线索。
就在两个小时前,我在 CodeProject 上发现了这篇精彩的文章:编写外壳扩展的完整傻瓜指南 - 第 V 部分。我立即开始将Michael Dunn 的代码与我的 SWF 代码(包含在我的项目中)结合起来。结果就是我想要的(好吧,是我做的,为什么不呢?)。希望大家喜欢!
注意 1:我的 SWF 头部读取器代码是我很久以前写的,它适用于 Flash SWF 版本 1-10……它也支持解压缩的 SWF 文件!
注意 2:因为我的 SWF 读取器使用了 ZLIB(仅压缩版本),所以可能需要在项目中使用 ZLIB 的许可协议。目前,我对 ZLIB 的许可协议一无所知。
注意 3:如果您有兴趣了解 SWF 规范——请访问 http://www.adobe.com/devnet/swf/pdf/swf_file_format_spec_v10.pdf。
Using the Code
实际上,我没有时间坐下来解释整个代码。因此,我假设您要么是专家级开发者,要么对源代码不感兴趣。如果您想了解外壳扩展机制的工作原理,请参阅Michael Dun 的文章 这里。
文章附带两个文件
- 一个压缩的安装包,其中包含带 DLL 的 INF 文件。只需右键单击 INF -> 安装,即可准备就绪!
- 一个包含完整源代码的 zip 文件,包括已编译的 DLL 和安装 INF 文件。
INF 文件会在控制面板的“添加/删除程序”中添加一项,这样您就可以轻松卸载它(您为什么要这样做?)。它会将 DLL 复制到 `System32` 中的 `ShellExt` 文件夹,那里才是它应该在的地方。对于喜欢 RegSvr32 的人来说——它也可以用,所以您并不真的需要 INF,但它很方便 :-)
好的,我是如何做到的呢?
第一件事是使用 Visual Studio 的向导创建一个新的具有 COM 支持的 ATL 应用程序,因为所有外壳扩展都基于 COM 技术。然后,您添加 -> 类 -> ATL COM 组件,并为其命名……现在您就有 DLL 调用 DLL 入口点所需的 COM 组件了。(请参阅我的代码中的 `BEGIN_OBJECT_MAP` / `OBJECT_ENTRY` 宏。)
根据 MSDN(http://msdn.microsoft.com/en-us/library/cc144106(VS.85).aspx),您必须让该 COM 组件实现另外两个接口:`IShellExtInit` 和 `IShellPropSheetExt`。
- `IShellExtInit` 有一个重要函数:`Initialize`。此时,外壳会传递相关文件名的信息。
- `IShellPropSheetExt` 有两个重要函数需要实现:`AddPages` 和 `ReplacePages`。实际上,`ReplacePages` 不会被调用,所以我们只返回 `E_NOTIMPL`。`AddPages` 是重要的那个:在这里您添加属性页。
基本上,我在代码中的做法是:遍历所有文件名,只保留扩展名为 SWF 的文件。如果只有一个,就为其添加一个标题为“SWF 摘要”的属性页。如果有一个以上,就为每个文件添加一个以文件名命名的页面。
如果您想了解更多关于代码的细节——您应该深入代码(最佳选择),或者阅读 Michael Dunn 的文章(也很好!)。我的代码(与外壳扩展相关的部分)很大程度上基于 Michael Dunn 的代码,并且他的大部分注释仍然保留在那里!
现在到注册表部分了(!):
在注册表中,文件/程序/处理程序之间的大部分连接都存储在 `HKEY_CLASSES_ROOT` 中。
基本上,每个扩展名在 `HKEY_CLASSES_ROOT` 中都有自己的键(像一个文件夹)。每个扩展名的键指向另一个键,该键包含有关它将具有的上下文菜单项、要与之关联的默认程序以及当然还有属性表处理程序的信息。
如果您打开 *REGEDIT.EXE* 并进入 `HKEY_CLASSES_ROOT`,您会在此处找到 *.swf* 键,其中“默认值”是最主要的条目,大多数时候其值为“ShockwaveFlash.ShockwaveFlash
”。
“ShockwaveFlash.ShockwaveFlash
”实际上是另一个键的名称,该键包含有关 Flash Player 应用程序的信息,因此 *.swf* 将由 Flash Player 运行。
现在,查看 `HKEY_CLASSES_ROOT\ShockwaveFlash.ShockwaveFlash`。您会发现里面有一个名为“shell
”的键,其中包含大多数上下文菜单项(例如,打开、编辑……)。我们实际上想要的是“shellex
”键,而它默认是不存在的。
`shellex` 键包含两个子键:“PropertySheetHandlers
”和“ContextMenuHandlers
”。
- “
ContextMenuHandlers
”是管理上下文菜单处理程序的键,这些处理程序是 DLL 而不是直接的 *.EXE* 关联。 - “
PropertySheetHandlers
”是负责文件属性对话框中属性页的键。
要在“PropertySheetHandlers
”中添加 COM 处理程序,只需创建一个以该 COM 处理程序的 CLSID 命名的键,或者一个以您选择的名称命名的 CLSID,但其默认值包含 CLSID。
在 `HKEY_CLASSES_ROOT` 中还有两个其他特殊键:`*` 和 `Folder`—— *Folder* 是一个全局键,负责处理所有文件夹的处理程序。 * 是一个与所有文件(非文件夹)相关的全局键!
因此,如果我们想处理 *.bmp* **和** *.gif*,我们不必将处理程序添加到 *.bmp* 的键和 *.gif* 的键中,而只需添加到 * 中(并在我们 DLL 的代码中过滤扩展名)。
实际上,无论如何使用单独扩展名的键都会有问题:当您想安装一个扩展时,您必须查找 *.extension* 键的默认值,然后跟踪到执行工作的实际键。如果有人随后安装了另一个程序,将 *.SWF* 指向另一个键,那么我们的处理程序就会被注册到错误的位置,并且不会被使用……
所以,解决方案是只使用 ***/Folder* 键。这也是我所做的,因为这样,您可以确保处理程序**始终**被调用。
**顺便说一下**——想象一下,在 * 键中有 20 个处理程序,它们被不断调用,并检查文件扩展名或格式以确定它们是否应该显示信息。这种情况可能成为 Windows 的巨大瓶颈……事实上,Windows 的大多数瓶颈都是这类情况,即加载了太多不必要的 DLL。所以,我想说的是:
- 如果您觉得在单个扩展名的键中注册处理程序而不是在全局“*”键中注册就可以满足需求,那就去做吧!
- 如果您喜欢清理 Windows 注册表,请检查 * 和 *Folder* 键,确保您没有太多不必要的处理程序。当您右键单击文件或文件夹时,它需要很长时间才能显示上下文菜单,这**非常**烦人……但请小心不要删除重要的处理程序……(例如文件的默认“摘要”属性页,或文件的默认“打开方式”上下文菜单处理程序……)。
好的,玩得开心!
关注点
Macromedia 和 Adobe 今天才想到这一点,这**确实**很有趣!!!
历史
嗯,这是第一个版本,希望没有 bug,因此这也是最后一个版本 :-)
更新: 我还添加了 x64 版本,并更新了源代码包,还有一个现成的安装包,支持 x86 和 x64。