提取可执行文件中图标

时间:2022-12-30 08:26:15

上星期看到豆三版主在坛子上发表的提取 EXE/DLL 文件中图标的帖子,由于当时没有空闲时间,没仔细看代码,趁今天有空仔细看了看后,发现有些问题:
1. 示例代码中使用了 ExtractIcon 来提取图标,用这个函数得到的不一定是 exe/dll 文件中图标资源的原内容。按照 msdn 上的解释,该函数会依据注册表中 HKEY_CURRENT_USER/Control Panel/desktop/WindowMetrics/Shell Icon Size 以及 ... /Shell Icon BPP 所指定的尺寸和色深来提取图标,如果刚好有相同尺寸/色深的图标资源,则直接返回它,否则会查找最接近的图标并缩放后再返回给调用代码。也就是说,返回的图标数据可能是经过转换的,而且总是返回固定尺寸/色深的图标(通常注册表中的这个值是 32x32),尽管资源中提供了多种尺寸和色深的图标,也仅能得到一个。
2. 示例代码中是调用 OleCreatePictureIndirect 来创建一个标准 IPciture 接口的对象,然后用 vfp 自带的 SavePicture 来保存图标的。尽管提取的图标可能是 256/真彩/带透明度的图标,用这种方法也只能得到 16 色的图标。


上 msdn 查了下资料,在 http://msdn.microsoft.com/en-us/library/ms997538.aspx 这篇文章中,对 ico 格式的图标、作为资源存放在可执行文件中的图标格式,以及如何使用它们,都有详细的描述。有了这些知识,就完全可以用 vfp 来编写一个提取并保存图标的程序了。唯一的问题是,要知道资源中包含的所有图标资源名称,需要调用 EnumResourceNames API,而它与所有 api 枚举类函数一样,都需要传入一个回调函数指针,vfp 中没有这样的功能。实现的方法目前有两种,一是借助第三方扩展函数库来创建回调函数,这个在我以前的代码中已多次使用的 vfp2c32.fll 中就有,但通常我们都不喜欢多一个文件;另一种方法是嵌入一段汇编代码看来实现,这个坛子上的 coolyylu 已经给出了实现代码,参见:http://topic.csdn.net/u/20090210/19/deda48ef-268b-48cf-86a6-d588dfa3f0c5.html。确定了这些问题的解决方法后,就有了下面的示例。在这个示例中,当你指定任何一个 Win32 格式的可执行文件(exe/dll/cpl/scr)后,程序会枚举其中的图标组资源,将其提取出来,然后按照 ico 图标文件的格式保存在表单所在文件夹的 Icon_??? 子文件夹中(其实图标组资源与 ico 文件的结构只有一个字节的内容不同,参见示例表单中的 __readme 方法);考虑到有人可能不了解图标文件的结构,不知道一个 ico 文件中可以同时存在多个不同的图标,所以也同时将拆分后的图标保存在 Icon_???/Split 文件夹中,这里 ??? 是你要提取图标的文件基名,例如你指定要从 explorer.exe 中提取,则 Icon_??? 就是 Icon_explorer。

 

示例表单:http://filer.blogbus.com/1502086/resource_150208612768629522.rar

 

-----------------------------------------------

 

由于 coolyylu 给出的回调函数中存在问题,详情请参见 带行号显示的 RichEdit 改造 中后面部分的描述,下面修改后重新上传的示例:

http://download.csdn.net/detail/dkfdtf/4303497