Windows 机密16 位图标已经过时了

Raymond Chen

我 在 2008 年 2 月的 Windows 机密专栏中提到,某些功能确实已经从 Windows® 中消失了。它们通常消失得非常缓慢而且基本上察觉不出,只有产品团队的人们会在每一次功能消失时安静地举行庆祝。另一个在 Windows Vista® 中消失的功能是使用 32 位代码访问存储在 16 位模块(主要是 16 位 EXE 和 16 位 DLL)中的图标。

在开始介绍该功能之前,您需要了解 16 位代码可以正常访问存储在 16 位模块中的图标;而该过程发生在 16 位仿真层内部。消失的功能是从 32 位代码访问这些图标的能力,或者更确切地说,是类似 ExtractIcon 之类的 32 位图标提取函数从 16 位 DLL 中加载这些图标的能力。

从 16 位模块中提取图标的 32 位代码无法使用 FindResource 这样的内核函数在文件中找到图标。它们必须执行其自身的微型装入程序(用于解析 16 位模块头),找到并解析资源表以搜索所需的图标资源。只有完成所有步骤,32 位代码才能最终将像素转换为图标。

  (单击该图像获得较大视图)

如您所想,完成这些工作的代码非常古老而且脆弱。错误或恶意行为都会导致二进制文件破坏,解析时也很容易出错。性能团队将会要求改变打开文件的方式,以便提高通过网络执行这些操作的性能,因为不同的打开和共享模式会对网络缓存的效果产生不同的影响。而可靠性团队可能要求重新编写解析代码,以避免使用内存映射文件。最终,维护此类代码的成本开始超过其所能提供的价值。实际上,我的意思是几乎没有人会再去编写 16 位程序了,不是吗?

现在,只要还存在 16 位仿真层,那您的 16 位程序仍可继续运行。(没错,64 位 Windows Vista 不包含 16 位仿真层,但这并不表示它比 Windows XP 落后;64 位 Windows XP 同样也不包含 16 位仿真层。虽然这样不会比原来更好,但同样也不会比以前更糟糕。)

在 Windows Vista 中,您损失的功能是不能在 32 位程序中使用 ExtractIcon 函数,也不能从 16 位 DLL 中获得图标。如果“开始”菜单上有 16 位程序的快捷方式,那么该快捷方式的图标现在将变成通用程序图标,因为 Windows 资源管理器无法再从其主 EXE 中提取 16 位程序图标。损失并不大。但如果这确实给您带来了麻烦,那您可以编辑该快捷方式的属性,并为其添加来自 32 位模块中的图标。

据我所知,损失该功能后唯一的问题出现在由一种特殊图表编辑工具生成的图标库内。由于某种原因,该程序默认将其图标另存为 16 位 DLL 中的资源,这意味着您将无法从 32 位代码中访问这些图标。当然,最简单的解决方法是将这些图标库重新另存为 32 位 DLL 中的资源。

我确信最终(说不定已经有人完成了)某人会编写一个小程序从 16 位 DLL 中提取所有图标,然后使用这些图标创建仅包含 32 位资源的 DLL,这样,那些使用 DLL 中 16 位旧图标的人们可以继续在“开始”菜单的快捷方式中使用它们。但我敢说,如果您编写此程序,那您很可能发现实际上谁也不会用到该程序。到 Windows 用户界面团队那里请求此程序的次数是:零。

Raymond Chen 的网站“The Old New Thing”及同名著作讲述了 Windows 的发展历程和 Win32 编程。他非常了解很多即将退出历史舞台的技术。

© 2008 Microsoft Corporation 与 CMP Media, LLC.保留所有权利;不得对全文或部分内容进行复制.