指定Windows/MFC API版本所需的标准Windows预处理器定义有哪些?
常用Windows/MFC构建相关预处理器宏列表
按用途分类如下:
Windows版本控制类
WINVER:传统Windows平台版本标识,早期用于同时兼容Win9x和NT内核系列系统_WIN32_WINNT:NT内核系统专属版本标识,是目前Windows SDK的核心版本控制宏NTDDI_VERSION:更细粒度的Windows Build版本标识,用于区分同大版本下的更新包差异_WIN32_IE:IE控件及相关Shell API的版本控制宏
MFC/ATL专用类
_AFXDLL:标识动态链接MFC库,需和所有依赖模块配置一致_USRDLL:标识构建常规MFC DLL_AFXEXT:标识构建MFC扩展DLL,仅扩展DLL项目需要定义,普通项目定义会导致类导入导出逻辑错误VC_EXTRALEAN:裁剪MFC头文件中极少使用的老旧API声明,可提升编译速度_ATL_ALL_WARNINGS:开启ATL库的严格编译警告
构建类型类
WIN32:标识目标为Windows平台(32位/64位均会定义,无需手动设置)_WINDOWS:标识目标为GUI程序,区别于_CONSOLE控制台程序_DEBUG:Debug版本标识,自动生成无需手动设置_VC80_UPGRADE:VS2005版本升级遗留宏,高版本VS可直接删除无实际作用
版本号标准命名替代硬编码
所有版本数值都可以用SDK内置的命名宏替代,无需硬编码,这些宏定义在sdkddkver.h头文件中,常用对应关系如下:
- Windows XP:
_WIN32_WINNT_WINXP= 0x0501 - Windows Vista:
_WIN32_WINNT_VISTA= 0x0600 - Windows 7:
_WIN32_WINNT_WIN7= 0x0601 - Windows 8:
_WIN32_WINNT_WIN8= 0x0602 - Windows 10/11:
_WIN32_WINNT_WIN10= 0x0A00
宏推导关系与配置简化
早期Windows SDK中WINVER和_WIN32_WINNT不会互相推导,因此旧的项目规范要求同时定义两个宏,避免部分头文件只读取其中一个宏导致版本判断不一致。你当前项目中两个宏分别对应XP和Win7版本的冲突,就是典型的配置不一致问题,会直接导致MFC中AFX相关结构体、函数的内存布局和调用约定不匹配,触发奇怪的运行时bug。
目前的简化配置方案:
在所有模块的预编译头文件最顶部,先定义_WIN32_WINNT为你需要的最低支持系统版本对应的命名宏,然后立即包含sdkddkver.h,该头文件会自动推导并设置WINVER、NTDDI_VERSION、_WIN32_IE等所有相关版本宏,无需单独设置就能保证所有版本定义完全一致。
配置清理注意事项
- 删除所有模块预处理器配置中零散的版本相关硬编码,统一放到预编译头最开始定义,保证所有模块版本完全对齐
- 仅MFC扩展DLL项目保留
_AFXEXT宏,普通exe、常规DLL项目删除该宏 - 如果不需要兼容Windows XP及更老系统,可保留
VC_EXTRALEAN减少编译体积,否则删除避免依赖的老旧API被裁剪 - 同步检查所有模块的CRT链接方式(/MT/MD/MTd/MDd)、MFC链接方式(静态/动态)完全一致,这也是AFX跨模块bug的高发原因
内容的提问来源于stack exchange,提问作者Mr. Boy
相关产品推荐
相关产品推荐

