读取嵌入的文本文件资源 Visual Studio C++

7
以下是我添加文本文件作为资源所采取的步骤: 1. 右键单击项目,添加新项 2. 选择文本文件,点击添加 3. 转到项目属性,配置属性->链接器->输入->嵌入托管资源文件 4. 然后在文本框中添加我的文本文件"items.txt"
接下来,在我的.rc文件中,我放置了以下代码:
#include "resource.h"
IDR_DATA1 TEXTFILE "Items.txt"

在我的 resource.h 文件中,我放置了如下内容:
#define TEXTFILE   256
#define IDR_DATA1  255

在我的form1.cpp方法中:
std::string result;
char* data = NULL;
HINSTANCE hInst = GetModuleHandle(NULL);
HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(IDR_DATA1), MAKEINTRESOURCE(TEXTFILE));
if (NULL != hRes)
{
    HGLOBAL hData = LoadResource(hInst, hRes);
    if (hData)
    {
        DWORD dataSize = SizeofResource(hInst, hRes);
        data = (char*)LockResource(hData);
    }
    else
    {
        MessageBox::Show("hData is null");
        return "";
    }
    char* pkcSearchResult = strstr(data, "2000000");
    if (pkcSearchResult != NULL)
        MessageBox::Show(gcnew String(pkcSearchResult));
}
else
    MessageBox::Show("hRes is null");
return result;

无论如何我一直得到hRes为null的错误,不知道为什么FindResource没有找到Items.txt,尽管我按照上述步骤将其添加为资源,有人知道为什么FindResource()不起作用吗?顺便说一下,它没有编译错误,上面的代码在一个方法中,该方法应该返回包含“2000000”的文本行(我已更改用于测试)。


你可能需要添加文本文件的路径,而不仅仅是文件“Items.txt”。 - Juniar
只是一点提示:您不必自己调用 GetModuleHandle。您可以将 NULL 直接作为第一个参数传递给 FindResource,而无需使用 hInst - Max Truxa
2017年,还没有答案吗? - Ari Seyhun
还有UDR - Laurie Stearn
1个回答

3

看起来在上述的FindResource函数中交换MAKEINTRESOURCE(IDR_DATA1)MAKEINTRESOURCE(TEXTFILE)的位置就可以工作。

以下宽字符变量的操作方式绕过了上述描述的1-4步骤,并遵循@In Silico的解决方案

  • Ensure textfile is either ANSI or Unicode depending on requirement (UTF-8 etc. requires extra conversion)
  • Copy the textfile into the project directory
  • As already described, add the following statements to the project rc and resource.h respectively:

    #include "resource.h"
    IDR_DATA1 TEXTFILE "Items.txt"
    

    For "Items.txt" in some subdirectory of $(ProjectDir) escape backslash with backslash, a fully qualified path works as well, but may not be portable.

    #define TEXTFILE   256
    #define IDR_DATA1  255
    

并定义这两个函数:

    void LoadFileInResource(int name, int type, DWORD& size, const wchar_t *& data) // *& is passing the pointer by reference and not by val.
    {
    HMODULE handle = ::GetModuleHandleW(NULL);
    HRSRC rc = ::FindResourceW(handle, MAKEINTRESOURCEW(name), MAKEINTRESOURCEW(type));
    HGLOBAL rcData = ::LoadResource(handle, rc);
    size = ::SizeofResource(handle, rc);
    data = static_cast<const wchar_t*>(::LockResource(rcData));                                                                 
    //LockResource does not actually lock memory; it is just used to obtain a pointer to the memory containing the resource data. 
    }

    wchar_t GetResource()
    {
    DWORD size = 0;
    const wchar_t* data = NULL;
    LoadFileInResource(IDR_MYTEXTFILE, TEXTFILE, size, data);
    /* Access bytes in data - here's a simple example involving text output*/
    // The text stored in the resource might not be NULL terminated.
    wchar_t* buffer = new wchar_t[size + 1];
    ::memcpy(buffer, data, size);
    buffer[size] = 0; // NULL terminator
    delete[] buffer;
    return  *data;
    }

data 应该提供一个以上述 pkcSearch 查询的 widechar 实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接