Search code examples
classmfcresource-files

What is the correct way to embed a resource in a reusable MFC class?


I am writing a C++ (MFC in particular) class which uses an external .gif image file and produces another image file after some processing. It would be nice if the initial image could be embedded in the code somehow. I have read in MSDN about using multiple .rc files and the whole thing seems quite complicated.

I would like to know from people who have gone through this before how to handle this problem.

EDIT : Sorry I was not clear. The class I am writing should be standalone, so I could use it again. If I put the image in a resource file, then the class will not compile if used in a fresh project.


Solution

  • You cannot embedd MFC resources inside a class or similar C++ container. They can only be embedded in DLL or EXE files - in a separate section of the produced binary. Since you want your class to be reusable, you must put it in a DLL. Hence, you must tag your class with the AFX_EXT_CLASS keyword.

    There are two solutions.

    Solution #1:

    • Create an MFC DLL project (MFC Extension DLL). Call it MyLibrary or whatever.
    • Put all your standalone classes in this DLL.
    • Embed all necessary resources.
    • Let your classes load resources from the HINSTANCE of your DLL as described below.

    There are several ways to retrieve the HINSTANCE of your DLL. If you ask me, the best solution is to grab it in DllMain. This is done automatically if you choose the MFC Extension DLL configuration:

    static AFX_EXTENSION_MODULE MyLibDLL = { NULL, NULL }; // Make this variable global!
    // Then access the hInstance as follows:
    LoadResource(MyLibDLL.hModule, ...)
    

    Solution #2:

    Store your resource as a byte buffer. Or better, convert it to Base64 and store it as an ASCII string. But remember not to blow the stack! Keep your resources small or increase the stack size in your project settings. Example:

    const char *encodedResource = "SGVsbG8gd29ybGQh";
    char *data = decode(encodedResource);
    foo(data);