VS2017纯C++项目中如何通过位图资源ID获取对应BMP文件名
位图资源ID对应源文件名的实现方法
你在
.rc资源脚本里写的"something.bmp",本质只是RC编译器在本地开发阶段用来定位磁盘上位图源文件的路径标记——正常链接生成的最终程序模块里,根本不会存储这个原始文件名。我自己刚学资源开发的时候,也试过翻PE结构说明、用各种Win32资源API想读这个值,折腾了半天才发现这条路从设计上就走不通:要是RC编译器把开发者本地的文件路径存在最终程序里,等于直接把本地磁盘目录结构泄露给最终用户,微软从一开始就没设计这个存储逻辑,别在这个方向上耗时间。
如果你的纯C++项目没有引入MFC/ATL,把代码里的CString替换成std::basic_string<TCHAR>即可,逻辑完全通用。
方案1:直接在集中管理资源ID的头文件里做映射(最推荐)
你现在已经把所有资源ID都集中定义在the.h里了,完全可以在同一个位置直接维护ID和对应文件名的映射,零依赖、无性能损耗:
- 在
the.h里紧跟现有资源ID定义追加映射表:// 原有定义 #define IDB_BITMAP7 7004 // 新增ID到源文件名的映射 const std::unordered_map<UINT, CString> g_BmpResPathMap = { {IDB_BITMAP7, _T("something.bmp")}, // 其他位图资源按同样格式追加即可 }; - 取值的时候直接实现你要的调用效果:
CString file_name = g_BmpResPathMap[IDB_BITMAP7];
这个方案没有任何兼容问题,哪怕你后续调整rc里的位图引用路径,只要同步更新这张映射表的内容就行,和资源编译逻辑完全解耦,是项目里最常用的做法。
方案2:用统一取值函数减少重复维护成本
如果你的项目里位图资源条目特别多,手动写映射表太繁琐,可以在头文件里给每个ID绑定对应的文件名常量,再封装统一的取值函数:
- 在
the.h里给每个资源绑定文件名常量:// 原有ID定义 #define IDB_BITMAP7 7004 // 绑定和rc中完全一致的源文件名 #define IDB_BITMAP7_FILE_NAME _T("something.bmp") - 封装通用的取值函数:
CString GetBitmapResFileName(UINT resId) { switch(resId) { case IDB_BITMAP7: return IDB_BITMAP7_FILE_NAME; // 其他资源按分支逐个补充即可 default: return _T(""); } } - 调用时的效果和需求完全一致:
CString file_name = GetBitmapResFileName(IDB_BITMAP7);
踩坑避坑提醒
- 不要尝试用
FindResource、EnumResourceNames这类Win32资源API去读取rc脚本里写的原始文件路径:这类API只能读取模块中已经编译好的二进制资源信息,完全不涉及RC编译阶段使用的本地源路径,在这个方向上调试纯粹浪费时间。 - 没必要为了存这个文件名专门新增自定义字符串资源和位图ID做硬关联,这种做法只会额外增加资源管理的复杂度,远不如直接在头文件维护映射高效。
内容的提问来源于stack exchange,提问作者user15194312
相关产品推荐
相关产品推荐

