对于类型为RCDATA

时间:2019-07-18 22:04:48

标签: c++ windows embedded-resource

我正在编写一个C ++程序,该程序需要处理大块数据,尤其是文本文件,但是数据长于给定的字符串限制。结果,我试图将文本文件加载为资源文件,但是,每当我调用FindResource时,响应都是一个空句柄。

我已经遍历了其他堆栈溢出帖子,并且MSDN尝试正确实现此功能,但是我尝试过的任何操作都没有返回有效的句柄。

C ++代码:

HGLOBAL     res_handle = NULL;
HRSRC       res;
char *      res_data;
DWORD       res_size;

auto g_hInstance = GetModuleHandle(NULL);
res = FindResource(g_hInstance, MAKEINTRESOURCE(MY_RESOURCE), RT_RCDATA);
std::cout << res << std::endl;
std::cout << GetLastError() << std::endl;
res_handle = LoadResource(NULL, res);
std::cout << GetLastError() << std::endl;
res_data = (char*)LockResource(res_handle);
std::cout << GetLastError() << std::endl;
res_size = SizeofResource(NULL, res);
std::cout << GetLastError() << std::endl;

输出:

0000000000000000
1813
87
87
87

Resource.h:

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Resource.rc
//
#define MY_RESOURCE 300
// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        103
#define _APS_NEXT_COMMAND_VALUE         40002
#define _APS_NEXT_CONTROL_VALUE         1001
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

Resource.rc:

MY_RESOURCE RCDATA "C:\\Users\\foobar\\Desktop\\projects\\foobar\\test0.txt"

2 个答案:

答案 0 :(得分:0)

当您从GetLastError()收到错误代码时,您应该调用FormatMessage API(带有FORMAT_MESSAGE_FROM_SYSTEM标志)或在Visual Studio中使用错误查找工具“工具/错误查找”。

代码1813转换为以下消息:“在图像文件中找不到指定的资源类型。”

如您所见,它抱怨资源类型

我认为您不需要RCDATA。从16位窗口开始,它已经很旧了。在Win32中,自定义资源类型是字符串,而不是整数。 IDE甚至不支持RCDATA。

正确的方法-右键单击.rc文件,“添加资源”,“导入”,浏览要包含的文件,Visual Studio会询问您资源类型,并写任何字符串,例如text将执行此操作,然后将该字符串作为FindResource函数的最后一个参数传递。如果使用默认项目设置进行构建,则它是Unicode,因此您需要在此处传递Unicode字符串L"text"

答案 1 :(得分:0)

这对我有用。我怀疑您的构建设置有问题。

我从Visual Studio 2017中的一个空项目开始,我在项目设置中唯一更改的是配置属性>常规>字符集>“使用Unicode字符集”

Source.cpp

#include <iostream>
#include <Windows.h>
#include "resource.h"

int main() {
  auto hinst = ::GetModuleHandleW(NULL);
  std::cout << hinst << std::endl;
  auto hrsrc = ::FindResourceW(hinst, MAKEINTRESOURCE(IDTHING), RT_RCDATA);
  std::cout << hrsrc << std::endl;
  auto hglob = ::LoadResource(hinst, hrsrc);
  std::cout << hglob << std::endl;
  return 0;
}

resource.h

#define IDTHING 300

Resource.rc

#include "resource.h"

IDTHING RCDATA "C:\\Windows\\notepad.exe"

我完全避免了VS中所有自动生成的资源,而只是将它们写为纯文本文件。

如果您在调试器中运行,请在分配hglob后停止并将其值放入内存窗口,我可以清楚地看到notepad.exe的PE标头。