简体   繁体   English

在非mfc应用程序中强制从dll加载资源的WTL方式? (我们使用的是WTL / ATL,而不是直接的win32)

[英]WTL way of forcing resources to load from a dll in a non mfc app? (we are using WTL/ATL, not straight win32)

I posted this question previously and now have the localized strings loaded (the ones we get with LoadString()) but I also need to load all the other resources from the satellite DLL. 我之前发布过这个问题 ,现在加载了本地化的字符串(我们用LoadString()得到的)但我还需要从附属DLL加载所有其他资源。

MFC has the AfxSetResourceHandle () call, but I need something equivalent for a non-mfc app? MFC有AfxSetResourceHandle()调用,但我需要一些非mfc应用程序的东西吗? I suspect I have to set that in the initialization code somewhere so all my resources are loaded from another DLL. 我怀疑我必须在初始化代码中设置它,所以我的所有资源都是从另一个DLL加载的。 How do I do that in a WTL (windows template library) context? 我如何在WTL(Windows模板库)上下文中执行此操作?

EDIT: 编辑:

This summarizes our problem . 这总结了我们的问题

We are not using straight win32, but ATL and WTL for windows stuff. 我们不是直接使用win32,而是ATL和WTL用于Windows的东西。 So we can't rely on the MFC stuff and we don't have low level control of the loading of menus and dialog resources. 所以我们不能依赖MFC的东西,我们没有对菜单和对话框资源的加载进行低级控制。

EDIT: Hmmm... This seems to have an answer , but I was hoping for something better than that. 编辑:嗯... 这似乎有一个答案 ,但我希望有更好的东西。 For example - a SetResourceInstance() method analog to GetResourceInstance() in a CAppModule object. 例如 - 一个SetResourceInstance()方法,类似于CAppModule对象中的GetResourceInstance()。

The resource functions (FindResource, LoadResource) take a handle to a module as one of the parameters. 资源函数(FindResource,LoadResource)将模块的句柄作为参数之一。

Use GetModuleHandleEx to get the module handle for the DLL. 使用GetModuleHandleEx获取DLL的模块句柄。

Edit: Additional info for ATL/WTL. 编辑: ATL / WTL的附加信息。

WTL uses ATL::_AtlBaseModule.GetResourceInstance() for the module handle in its Win32 calls. WTL在其Win32调用中使用ATL::_AtlBaseModule.GetResourceInstance()作为模块句柄。 There's a SetResourceInstance function that you can call to change the module that's used. 有一个SetResourceInstance函数,您可以调用它来更改使用的模块。 Something like this should work at the beginning of your program: 这样的事情应该在你的程序开始时起作用:

HMODULE hmod;
::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, myDllFuncPtr, &hmod);
ATL::_AtlBaseModule.SetResourceInstance(hmod);

Occasionally the above method is not usable, such as when you still have to support Windows 2000 for some reason. 有时,上述方法无法使用,例如当您因某些原因仍需支持Windows 2000时。 In such case it's good to have the following trick handy. 在这种情况下,使用以下技巧很方便。

We declare a static variable, which means that its address will be inside the module into which it was linked. 我们声明一个静态变量,这意味着它的地址将在它所链接的模块内。 We then use the address to that variable to query for the base address of that allocated area, which is what the HMODULE is. 然后我们使用该变量的地址来查询该分配区域的基地址,这就是HMODULE的基础地址。

HMODULE GetCurrentModuleHandle()
{
    MEMORY_BASIC_INFORMATION mbi;
    static int iDummy;
    VirtualQuery(&iDummy, &mbi, sizeof(mbi));
    return (HMODULE)mbi.AllocationBase;
}

This does by no means invalidate Mark's answer! 这绝不会使Mark的答案无效! Just keep it in mind as a fallback option if you need your programs to run on ancient systems. 如果您需要在古代系统上运行程序,请记住它作为后备选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM