今天就是要弄明白!

所以,经过上一篇的文章的洗礼,你应该知道如何指定 Windows 头文件的具体版本了。如下,你可以看到我们定义了四种不同的宏,是不是有点像孔乙己中不同的”茴”的写法?

#define WINVER 0x0400
#define _WIN32_WINNT 0x0400
#define _WIN32_WINDOWS 0x0400
#define _WIN32_IE 0x0400

为什么会有这些不同的宏来做同样一件事儿?我们来一个一个地说。

WINVER

WINVER 符号是最早被设计出来的。早在 16 位 Windows 时代,它就被用来控制使用的头文件版本,它的使用延续到 32 位头文件中,大概来自最初将头文件转换为 32 位的人,以及与 WINVER 符号一起长大的人。

此符号在头文件中仍然大量使用,这些文件可以将其源头追溯到 16 位 Windows,例如 winuser.h、wingdi.h 和 mmsystem.h。

_WIN32_WINNT

接下来出现的是 _WIN32_WINNT 符号。

我不确定它来自哪里,但从它的名字来看,它可能是由 Windows NT 团队发明的,以便允许他们阻止头文件中仅在 Win32 的 Windows NT 实现中可用的部分。

别忘了,在早期,还有 Win32s,它是 Win32 的一个子集,可以在 16 位 Windows 3.1 上运行。单个 WINVER 符号不足以准确指定您想要兼容的内容。

例如,仅在 Windows NT 3.1 中可用的函数将使用 #if _WIN32_WINNT >= 0x030A 进行保护,以便想要在 Win32 上运行的程序可以将 _WIN32_WINNT 设置为零,并使该函数保持禁止。

同样,Windows 95 和 Windows NT 4 都标识自己是 Windows 主要版本为 4,因此 WINVER 符号不足以区分它们。因此,Windows NT 4 中存在但 Window 95 中不存在的功能受到 _WIN32_WINNT 保护。

_WIN32_WINDOWS

另一方面,也有一些功能是在 Windows 95 中首次引入的,并且在 Windows NT 4 的原始版本中不存在。_WIN32_WINDOWS 符号允许您指定要访问 Windows 95 的新增内容,这些内容也将移植到 Windows NT 4 和未来版本的 Windows NT。

_WIN32_IE

接下来的符号是 _WIN32_IE,它允许您指定需要在系统上安装的 Internet Explorer 版本。这在 Internet Explorer 包含对选定操作系统组件的更新的时代更为重要。

例如,Internet Explorer 4 不仅带有更新的comctl32.dll,而且还带有为您提供活动桌面的新 shell32.dll。(哇,还记得 Active Desktop 吗?那时,每个人都认为HTML将接管世界,人们会用 HTML 编写整个应用程序。人们仍在努力。) => 译者注:现在确实是那么回事儿!

历史重演了:我们之前看到过,当我们试图弄清楚为什么某些函数返回 NULL 而另一些函数返回 INVALID_HANDLE_VALUE 时。

每当有人向 Windows 添加新功能并不得不添加 #ifdef 防护装置时,他们是否使用 WINVER、_WIN32_WINDOWS 或 _WIN32_WINNT 几乎都是一个折腾。一旦 Internet Explorer 停止包含对 shell 组件的更新,_WIN32_IE也陷入了“折腾”的困境。

更好的解决方案

为了从这场灾难中找出一些意义,SDK 和 DDK 团队为 Windows Vista 头文件提出了一个新计划:sdkddkver.h。

现在,您只需定义一个符号来指定最低目标操作系统:NTDDI_VERSION。设置后,所有其他符号将自动设置为目标操作系统的适当值。(不,我不知道NTDDI的字母代表什么,尽管有一个明显的候选者。)

如果运气好的话,每个人都会标准化 NTDDI_VERSION,这篇文章将成为那些“古怪的历史新奇事物”之一,就像所有关于 16 位 Windows 的文章一样。

总结

如果你仔细看看 Visual Studio 默认生成的 C++ 桌面应用程序(MFC),则你会发现,项目文件下,确实生成了一个 targetver.h,而此文件又包含了 SDKDDKVer.h 文件。此文件仅 300 多行,值得你研究一番。

最后

Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《What’s the difference between WINVER, _WIN32_WINNT, _WIN32_WINDOWS, and _WIN32_IE?》

打开网易新闻 查看更多图片