Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embed Text File in a Resource in a native Windows Application

I have a C++ Windows program. I have a text file that has some data. Currently, the text file is a separate file, and it is loaded at runtime and parsed. How is it possible to embed this into the binary as a resource?

like image 814
Oliver Zheng Avatar asked May 29 '10 00:05

Oliver Zheng


Video Answer


1 Answers

Since you're working on a native Windows application, what you want to do is to create a user-defined resource to embed the contents of the text file into the compiled resource.

The format of a user-defined resource is documented on MSDN, as are the functions for loading it.

You embed your text file in a resource file like this:

nameID typeID filename 

where nameID is some unique 16-bit unsigned integer that identifies the resource and typeID is some unique 16-bit unsigned integer greater than 255 that identifies the resource type (you may define those integers in the resource.h file). filename is the path to the file that you want to embed its binary contents into the compiled resource.

So you might have it like this:

In resource.h:

// Other defines...  #define TEXTFILE        256 #define IDR_MYTEXTFILE  101 

In your resource file:

#include "resource.h"  // Other resource statements...  IDR_MYTEXTFILE TEXTFILE "mytextfile.txt" 

Then you load it like this (error-checking code omitted for clarity):

#include <windows.h> #include <cstdio> #include "resource.h"  void LoadFileInResource(int name, int type, DWORD& size, const char*& data) {     HMODULE handle = ::GetModuleHandle(NULL);     HRSRC rc = ::FindResource(handle, MAKEINTRESOURCE(name),         MAKEINTRESOURCE(type));     HGLOBAL rcData = ::LoadResource(handle, rc);     size = ::SizeofResource(handle, rc);     data = static_cast<const char*>(::LockResource(rcData)); }  // Usage example int main() {     DWORD size = 0;     const char* 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.     char* buffer = new char[size+1];     ::memcpy(buffer, data, size);     buffer[size] = 0; // NULL terminator     ::printf("Contents of text file: %s\n", buffer); // Print as ASCII text     delete[] buffer;     return 0; } 

Note that you don't actually have to free the resource since the resource resides in the binary of the executable and the system will delete them automatically when the program exits (the function FreeResource() does nothing on 32-bit and 64-bit Windows systems).

Because the data resides in the executable binary, you can't modify it via the retrieved pointer directly (that's why the LoadFileInResource() function implementation stores the pointer in a const char*). You need to use the BeginUpdateResource(), UpdateResource(), and EndUpdateResource() functions to do that.

like image 192
In silico Avatar answered Oct 03 '22 03:10

In silico