【问题标题】:define and read user defined resource in MFC app在 MFC 应用程序中定义和读取用户定义的资源
【发布时间】:2017-08-20 01:17:58
【问题描述】:

我有一个 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 返回 null。

【问题讨论】:

    标签: c++ winapi visual-studio-2013 mfc embedded-resource


    【解决方案1】:

    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");
    

    【讨论】:

    • 根据文档:“如果 hModule 为 NULL,系统会从用于创建当前进程的模块加载资源。
    • @Remy 是的,但是 OP 想要从 DLL 加载资源,而不是从 EXE 加载资源
    • @zett42:我知道这一点。
    • 锁定后是否需要使用freeLibrary API?
    • 提醒任何尝试此操作的人:如果将文字 BUTTON_DEF 替换为数字,则数字不被视为文字,IDR_COLOR_ATT 仅采用 2010 的值。跨度>
    【解决方案2】:

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

    hModule [输入,可选]
    类型:HMODULE

    其可移植可执行文件或随附的 MUI 文件包含该资源的模块的句柄。 如果此参数为NULL,则函数搜索用于创建当前进程的模块。

    hModule [输入,可选]
    类型:HMODULE

    其可执行文件包含资源的模块的句柄。 如果 hModule 为 NULL,则系统从用于创建当前进程的模块加载资源。

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

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

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

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

    hinstDLL [输入]
    DLL 模块的句柄。该值是 DLL 的基地址。 DLL 的 HINSTANCE 与 DLL 的 HMODULE 相同,因此 hinstDLL 可用于调用需要模块句柄的函数。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-12
      • 2018-05-19
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-23
      • 2016-08-14
      相关资源
      最近更新 更多