C++ 在WinAPI中使用资源名称
在WinAPI中,您可以通过和访问资源 根据,可以指定资源的名称: lpName[in] 类型:LPCTSTR 资源的名称。或者,该参数可以是MAKEINTRESOURCE(ID),而不是指针,其中ID是资源的整数标识符。有关更多信息,请参阅下面的备注部分 我有两个问题: 首先,这似乎并不准确,因为指定ID或文件名都不起作用。要为C++ 在WinAPI中使用资源名称,c++,winapi,embedded-resource,C++,Winapi,Embedded Resource,在WinAPI中,您可以通过和访问资源 根据,可以指定资源的名称: lpName[in] 类型:LPCTSTR 资源的名称。或者,该参数可以是MAKEINTRESOURCE(ID),而不是指针,其中ID是资源的整数标识符。有关更多信息,请参阅下面的备注部分 我有两个问题: 首先,这似乎并不准确,因为指定ID或文件名都不起作用。要为lpName参数输入的正确值是什么 其次,我想知道是否可以在运行时检索资源的文件名。这可能吗?或者,文件打包为资源后,是否会丢弃文件名 测试代码 .ico和.htm是使
lpName
参数输入的正确值是什么其次,我想知道是否可以在运行时检索资源的文件名。这可能吗?或者,文件打包为资源后,是否会丢弃文件名 测试代码 .ico和.htm是使用Visual Studio自动创建的;通过添加相应类型的新资源。因此,它们的格式不应该弄乱
FindResource
语句
资源.h
#define IDR_DRAWING1 101
#define IDI_ICON1 102
#define IDR_HTML1 103
编辑:
根据Ben Voigt的评论,我已经更改了Resource.rc文件,以便使用非数字名称:
DWG1 BINARY "Drawing1.dwg"
ICON1 ICON "icon1.ico"
HTML1 HTML "html1.htm"
现在,根本不使用resource.h文件。以下是新的相关测试:
FindResource(hInstance, _T("DWG1"), _T("BINARY")); //Succeeds now.
FindResource(hInstance, _T("ICON1"), _T("ICON")); //Still fails.
FindResource(hInstance, _T("ICON1"), RT_ICON); //Still fails.
FindResource(hInstance, _T("HTML1"), _T("HTML")); //Still fails.
FindResource(hInstance, _T("HTML1"), RT_HTML); //Still fails.
因此,我的二进制资源满足了我的期望,但是图标和HTML
发生了什么
文件打包为资源后是否会丢弃文件名
是的,没错
例如,在列表中,第一列是资源名称,第三列是文件名
nameID ICON filename
有些资源根本不来自外部文件,例如,直接从资源脚本中嵌套的菜单
和菜单项
语句获取数据<代码>对话框
、字符串表
、版本
、和版本信息
只是其他一些不作为单独文件存在的常见资源。解决方案和结果:
好了,我终于得到了一个可预测的结果
查找资源的方式部分取决于资源类型。在这种情况下,DWG1
是一种自定义类型的BINARY
资源。中不存在预定义的RT.*
,因此需要将类型指定为LPCTSTR
:
FindResource(hInstance, _T("DWG1"), _T("BINARY"));
对于预定义的资源类型,不能将类型名称指定为
LPCTSTR
。相反,您必须使用相应的RT.*
值。这可能是因为每个RT.*
值对应一个MAKEINTRESOURCE(WORD)
,如果我的理解是正确的,则宏结果指向中的无效地址,而不是资源类型的文本表示
ICON1
资源的问题是类型应该是RT\u组\u图标
,而不是RT\u图标
。这两种类型的区别在于前者与硬件无关,后者与硬件相关。不过,我不知道为什么RT\u图标
不起作用
最后,HTML1
的问题是我的错误,因为我没有确保引用的文件实际上包含数据。在构建过程中,可能会忽略它,因为它本质上是一个空资源。此资源使用的正确类型是RT\u HTML
现在,关于名字。正如Ben Voigt在对的评论中提到的,为了将名称指定为LPCTSTR
,需要非数字名称。如果使用数字名称,则必须使用MAKEINTRESOURCE
VisualStudio的资源编辑器使得用字符串而不是数字来命名资源有点麻烦,因为默认情况下它会为每个资源创建宏。然后,这些宏在预处理阶段用数字替换资源名称
要将名称更改为字符串,您有两个选项:
- 将资源的
(在属性中找到)用双引号括起来。这将阻止资源编辑器为名称创建宏。但是,如果在先前设置的ID
周围放置引号,则宏可能已经存在ID
- 或者,在任何文本编辑器中打开资源脚本文件并选择类似的名称。同样,其目的是防止生成宏。因此,分离资源脚本和资源头将起作用,或者只是确保头中不存在宏
RT\u GROUP\u图标
,也许RT\u ANIICON
我已经在我的OP上发布了一些测试代码,演示了哪些有效,哪些无效。显然,没有一条语句接受您答案中所述的nameID
。@NickMiller:预处理后,您的文件是101二进制文件“Drawing1.dwg”
等。您使用的数字ID没有任何名称。因此,在运行时没有可用的名称。如果您没有宏定义,那么资源实际上将被命名为IDR\u DRAWING1
,再次感谢您的帮助,但是这似乎还不够。我在OP中添加了更多的测试,只找到了二进制资源。图标
和HTML
仍然存在
nameID ICON filename
FindResource(hInstance, _T("DWG1"), _T("BINARY"));