在 MFC 应用程序中定义和读取用户定义的资源

define and read user defined resource in MFC app

我有一个 mfc dll 项目及其 Resource.h 和 resource.rc 文件。 我想在 rc 文件中存储数据(对话框的颜色)。

  1. 如何定义数据?
  2. 如何从代码中访问这些数据?

我根据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));

但是 FindResource api returns null.

FindResource、LoadResource 和 SizeofResource 应该将 DLL 的实例句柄作为第一个参数。您可以在该 DLL 的 DllMain() 函数中获取 DLL 实例句柄,将其保存在全局变量中。或者,您可以使用 DLL 文件作为参数调用 GetModuleHandle,以从中获取实例句柄: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");

您将 NULL 作为 FindResource()LoadResource()SizeofResource()hModule 参数传递。根据 FindResource()LoadResource() 文档:

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.

SizeofResource() 文档没有这样的评论,但大概 NULL 也适用于它)。

进程不是从 DLL 创建的,只能从 EXE 创建。因此,您对 hModule=NULL 的使用导致 API 搜索加载 DLL 的 EXE 资源,而不是 DLL 的资源。

您需要使用指向您的 DLL 的 HMODULE

如果您的加载代码在 DLL 本身内部,请使用提供给 DLL 的 DllMain()/DllEntryPoint():

HINSTANCE

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.

如果加载代码在 EXE 中(或在另一个 DLL 中),您将不得不使用 LoadLibrary()GetModuleHandle() 返回的 HMODULE