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

StackOverflow https://stackoverflow.com/questions/5341850

Question

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.

MFC has the AfxSetResourceHandle () call, but I need something equivalent for a non-mfc app? I suspect I have to set that in the initialization code somewhere so all my resources are loaded from another DLL. How do I do that in a WTL (windows template library) context?

EDIT:

This summarizes our problem.

We are not using straight win32, but ATL and WTL for windows stuff. 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.

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.

Was it helpful?

Solution

The resource functions (FindResource, LoadResource) take a handle to a module as one of the parameters.

Use GetModuleHandleEx to get the module handle for the DLL.

Edit: Additional info for ATL/WTL.

WTL uses ATL::_AtlBaseModule.GetResourceInstance() for the module handle in its Win32 calls. There's a SetResourceInstance function that you can call to change the module that's used. 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);

OTHER TIPS

Occasionally the above method is not usable, such as when you still have to support Windows 2000 for some reason. 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 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! Just keep it in mind as a fallback option if you need your programs to run on ancient systems.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top