我有这个MFC应用程序,它使用CString :: LoadString函数从字符串资源加载字符串。每个应用程序对话框的类及其相关资源都包含在MFC扩展DLL中。
CString :: LoadString成功加载主模块(.exe)资源的字符串资源中的字符串,但无法从DLL的资源字符串资源加载字符串。
在每种情况下,我通过调用以下方法从CWinApp对象获取加载字符串的实例句柄: CWinApp * WinApp = AfxGetApp(), 当然,实例的句柄是WinApp-> m_hInstance,我在调用CString :: LoadString函数时使用它作为第一个参数。
可能是什么原因以及可能是什么解决方案。
答案 0 :(得分: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。这是另一个话题。
答案 1 :(得分: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模块之间共享资源的关键。
如果所有这些都设置正确 - 并且没有身份证冲突 - 那么它只是一个呼唤:
CString str;
str.LoadString(IDS_MY_STRING_ID);
代码中的任何位置,无论字符串实际存在于何处。
有关资源ID和编号的良好起点,请参阅此link。