首页 文章

为什么CString :: LoadString在我的应用程序的主模块(.exe)中工作,但在我的扩展DLL中不起作用?

提问于
浏览
1

我有这个MFC应用程序使用CString :: LoadString函数从字符串资源加载字符串 . 每个应用程序对话框的类及其相关资源都包含在MFC扩展DLL中 .

CString :: LoadString成功加载主模块(.exe)资源的字符串资源中的字符串,但无法从DLL的资源的字符串资源加载字符串 .

在每种情况下,我通过调用CWinApp * WinApp = AfxGetApp()从CWinApp对象获取加载字符串的实例句柄,当然实例的句柄是WinApp-> m_hInstance,我在调用CString ::时使用它作为第一个参数LoadString函数 .

可能是什么原因以及可能是什么解决方案 .

2 回答

  • 1

    您是否通过EXE的HINSTANCE从扩展库加载字符串?听起来像 .

    使用MFC,如果您有扩展库并确保您的字符串标识符是唯一的,则只需要调用CString :: LoadString(UINT nID)版本 . 因为扩展库创建进入全局链表的CDynLinkLibrary结构,所以LoadString(UINT)函数将搜索所有MFC库,直到找到包含该字符串的HINSTANCE,然后它将从那里加载 . 如果您坚持使用带有HINSTANCE参数的LoadString()函数,请确保在要从DLL加载字符串或对话框时使用扩展DLL的HINSTANCE,而不是EXE的扩展名 .

    对于小型项目,例如不到12个DLL,您可能只需要为所有内容使用唯一ID . 当您进入像100个DLL这样疯狂的大型项目时,您必须使用其他技术,例如DLL中调用AfxSetResourceHandle()的特殊命名函数,或者知道始终使用DLL的HINSTANCE . 那是另一个话题 .

  • 0

    为了补充Joe Willcoxson的答案,请务必检查您使用的每个MFC扩展DLL是否需要特殊的初始化代码,类似于以下示例:

    #include "stdafx.h"
    #include <afxdllx.h>
    
    static AFX_EXTENSION_MODULE MyExtDLL = { NULL, NULL };
    
    extern "C" int APIENTRY
    DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
    {
        if (dwReason == DLL_PROCESS_ATTACH)
        {
            TRACE0("MyExt.DLL Initializing!\n");
    
            // Extension DLL one-time initialization
            if (!AfxInitExtensionModule(MyExtDLL, hInstance))
                return 0;
            new CDynLinkLibrary(MyExtDLL);
        }
        else if (dwReason == DLL_PROCESS_DETACH)
        {
            TRACE0("MyExt.DLL Terminating!\n");
            // Terminate the library before destructors are called
            AfxTermExtensionModule(MyExtDLL);
        }
        return 1;   // ok
    }
    

    此代码只负责CDynLinkLibrary创建,这是在MFC模块之间共享资源的关键 .

    如果所有这些都设置正确 - 并且没有ID冲突 - 那么它只是一个调用:

    CString str;
    str.LoadString(IDS_MY_STRING_ID);
    

    代码中的任何位置,无论字符串实际存在的位置 .

    可以在link中找到有关资源ID和编号的良好起点 .

相关问题