1
votes

I have an mfc dll project and its Resource.h and resource.rc files. I want to store data (colors to the dialog) in the rc file.

  1. How can I define the data?
  2. How can I access this data from the code?

I've wrote this code according to How to read user-defined resource in Visual C++ 2012?

// resource.h

#define IDR_COLOR_ATT 2010

// resource.rc

IDR_COLOR_ATT BUTTON_DEF
{
    0x71c5,
    0xffff,
    0x0003,
}

// Dialog.cpp

HRSRC rc = ::FindResource(NULL, MAKEINTRESOURCE(IDR_COLOR_ATT),L"BUTTON_DEF");
HGLOBAL rcData = ::LoadResource(NULL, rc);
DWORD size = ::SizeofResource(NULL, rc);
const char* data = static_cast<const char*>(::LockResource(rcData));

But the FindResource api returns null.

2

2 Answers

2
votes

FindResource, LoadResource and SizeofResource should take the instance handle of your DLL as first parameter. You can get your DLL instance handle in the DllMain() function of that DLL, save it in a global variable. Or, you can call GetModuleHandle with your DLL file as parameter to get the instance handle from it: https://msdn.microsoft.com/en-us/library/windows/desktop/ms683199(v=vs.85).aspx

HMODULE hMod = GetModuleHandle(L"MyDll.dll");
HRSRC rc = ::FindResource(hMod, MAKEINTRESOURCE(IDR_COLOR_ATT),L"BUTTON_DEF");
2
votes

You are passing NULL as the hModule parameter of FindResource(), LoadResource(), and SizeofResource(). Per the FindResource() and LoadResource() documentations:

hModule [in, optional]
Type: HMODULE

A handle to the module whose portable executable file or an accompanying MUI file contains the resource. If this parameter is NULL, the function searches the module used to create the current process.

hModule [in, optional]
Type: HMODULE

A handle to the module whose executable file contains the resource. If hModule is NULL, the system loads the resource from the module that was used to create the current process.

(The SizeofResource() documentation has no such comment, but presumably NULL also apples to it as well).

A process is not created from a DLL, only from an EXE. So your use of hModule=NULL is causing the API to search the resources of the EXE that loaded your DLL, not the resources of your DLL.

You need to use the HMODULE that points to your DLL.

If your loading code is inside the DLL itself, use the HINSTANCE that is supplied to the DLL's DllMain()/DllEntryPoint():

hinstDLL [in]
A handle to the DLL module. The value is the base address of the DLL. The HINSTANCE of a DLL is the same as the HMODULE of the DLL, so hinstDLL can be used in calls to functions that require a module handle.

If the loading code is inside the EXE instead (or in another DLL), you will have to use the HMODULE that is returned by LoadLibrary() or GetModuleHandle().