Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading an embedded text file resource Visual Studio C++

Here are the steps I took to add a text file as a resource: 1. Right click project, add New Item 2. Choose text file, click add 3. Go to project properties, configuration properties->Linker->Input->Embed Managed Resource File 4. I then added my text file "items.txt in that textbox

Then in my .rc file, I put the following code:

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

In my resource.h file, I put:

#define TEXTFILE   256
#define IDR_DATA1  255

In my form1.cpp method:

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;

I keep getting hRes is null no matter what, for some reason FindResource is not finding Items.txt even though I added it as a resource using the steps above, anyone know why FindResource() isn't working? Btw it compiles with no errors and the above code is in a method that is supposed to return the line of text that contains "2000000" (which I'm changed for testing purposes)

like image 297
user3931764 Avatar asked Aug 12 '14 03:08

user3931764


1 Answers

It appears that swapping the positions of MAKEINTRESOURCE(IDR_DATA1) and MAKEINTRESOURCE(TEXTFILE) in the above FindResource function would work.

The way it operates in the following wide char variation bypasses steps 1 - 4 as described above, and follows from @In Silico's solution:

  • 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
    

And define the two functions:

    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 should provide a widechar implementation of the above pkcSearch query.

like image 176
Laurie Stearn Avatar answered Oct 21 '22 08:10

Laurie Stearn