Problems With Resource DLL

Problems With Resource DLL

Kyudos
Advisor Advisor
1,360 Views
4 Replies
Message 1 of 5

Problems With Resource DLL

Kyudos
Advisor
Advisor

I've put my resources in a resource only DLL, which I build as an extension DLL. In my app initialisation, I load the resource DLL with LoadLibraryEx and LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE. I then insert it into the resource chain by intialising a CDynLinkLibrary member.

 

It was my understanding that resource DLLs added this way are added to the begining of the resource search path - meaning resources should be found in my DLL first. However, it seems my resource LoadStrings (for example) are coming from AutoCAD, and the only way to fix this (so far) is to specifically FindResource using my resource handle. This is easy enough for strings, more complicatied for dialog templates.

 

I was trying to avoid having to constantly change my resource handle.

 

Is there a way to ensure the resource search order is as I want it?

 

If I can't get my resource DLL to the front of the queue, is there a published list of resource IDs to use so as to avoid conflict with AutoCAD IDs?

 

Cheers

0 Likes
Accepted solutions (1)
1,361 Views
4 Replies
Replies (4)
Message 2 of 5

tbrammer
Advisor
Advisor

As far as I know you definetley need to switch the resource handle temporary yourself. Setting the resource handle to your own resource permanantly could cause AutoCAD to fail. Have a look at the class CAcModuleResourceOverride. It is very easy to use:

 

From <ARX>\inc\AcExtensionModule.h:

/////////////////////////////////////////////////////////////////////////////
// CAcModuleResourceOverride - Switch between default and module's resources
//
//   Use an instance of this class to switch between resource providers. When
// the object is constructed a new resource provider will get switched in.
// Upon destruction the original resource provider will be restored. For
// example:
//
//      void MyFunc ()
//      {
//          CAcModuleResourceOverride myResources;
//              .
//              .
//      }

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 3 of 5

Kyudos
Advisor
Advisor

But doesn't CAcModuleResourceOverride switch to the resources in the ARX file? My resources are in a separate file. Anyway, it would be easy enough to make my own version of it, but I'd still have to go through hundreds of source files and add it in there

 

Isn't the whole idea of the extension DLL system so you DON'T have to keep flipping your resource handles? It would be easier - and one less thing to remember to do - if I could make my DLL the first in the resource chain. Failing that I could change my IDs to something more 'unusual' - but only if I know what ID ranges AutoCAD uses.

0 Likes
Message 4 of 5

tbrammer
Advisor
Advisor
Accepted solution

 

> But doesn't CAcModuleResourceOverride switch to the resources in the ARX file? My resources are in a separate file

 

You have to make sure that the CAcExtensionModule object stores your resource handle in CAcExtensionModule::m_hDefaultResource.

Look into the header file <ARX>\inc\AcExtensionModule.h. It's pretty obvious. This is how you can do it:

 

 

// Define a CAcExtensionModule at global scope:
AC_IMPLEMENT_EXTENSION_MODULE(theArxDLL);  
    // expands to:
    // CAcExtensionModule theArxDLL;
    // CAcExtensionModule& CAcModuleResourceOverride::m_extensionModule = theArxDLL;

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
   if (dwReason == DLL_PROCESS_ATTACH)
   {         
       HINSTANCE hResOld = AfxGetResourceHandle();   // store the original Resource Handle
       HINSTANCE hMyResource = LoadLibrary(<myResDllPath>);  // Load your Resource DLL or get its handle
       AfxSetResourceHandle(hMyResource);   // temporary set your Resource Handle...
       theArxDLL.AttachInstance(hInstance); // ..to make sure that theArxDLL grabs your Resource Handle when calling AfxGetResourceHandle()
       AfxSetResourceHandle(hResOld);       // restore to the original handle
   }
   else if (dwReason == DLL_PROCESS_DETACH)
   {
      theArxDLL.DetachInstance();
   }
   return 1;
}

 

I have to admit that I'm not sure wether LoadLibrary() will work within DllMain(). If not you could move the code to initModule() (acrxEntryPoint(AcRx::kInitAppMsg,..))

 

> Isn't the whole idea of the extension DLL system so you DON'T have to keep flipping your resource handles?

>It would be easier - and one less thing to remember to do - if I could make my DLL the first in the resource chain.

 

Sure it would be easier. But AutoCAD itself and maybe other extension modules use their own resource DLLs as well. So you can't ever rely on the current resource handle being yours. This is why you need the flipping.

 

> ...have to go through hundreds of source files and add it in there.

You should add this to functions that need to access the resources. I.e. if you have resource Strings use a function like CString resStr(int id) {...} that does the flipping before retrieving the string.

 

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 5 of 5

Kyudos
Advisor
Advisor

> You should add this to functions that need to access the resources. I.e. if you have resource Strings use a function like

> CString resStr(int id){...} that does the flipping before retrieving the string.

 

Yeah, I already did this on my string an icon retrieval functions while investigating the problem. It's not quite so easy with dialog templates in MFC - anyway it seems obvious I'll just have to bite the bullet and do the flipping.

 

Thanks.

0 Likes