BACKGROUND:
Our application is an AppWizard generated MDI
appliction that explicitly loads extension dlls
using AfxLoadLibrary(). In the DllMain() call for
this extension dll, the dll is added to the
resource list that MFC maintains by creating an
instance of the CDynLinkLibrary. In the
constructor the CDynLinkLibrary the m_hResource,
the m_hModule the m_classList and m_factoryList
variables are set to the corresponding values in
the AFX_EXTENSION_MODULE. For our situation the
m_classList and the m_factoryList variables are
empty lists.
Many of these dlls may get loaded while the
application is up.
PROBLEM:
We do not have unique resource ids across all the
dlls that are loaded. As a result, we are running
into problems when a resource needs to get
loaded: because of duplication of resource ids
the incorrect resource from the incorrect dll may
be loaded.
To get around this problem resources that are
explicitly loaded by us is done as follows:
// Get the current resource handle
hFlexrClient = AfxGetResourceHandle();
// Set current resource handle to the dll
we want the resource to be loaded from
AfxSetResourceHandle
(g_hInstanceClientFLM150);
// Load resource
FTimingFacAttribDlg TimingFacAttribDlg
(AfxGetApp()->m_pMainWnd, NULL, this);
TimingFacAttribDlg.DoModal();
// Set the saved resource handle back
AfxSetResourceHandle(hFlexrClient);
As stated this works for resources that we are
explicitly loading. However it does not take care
of problems like menu description displayed when
the user hovers over a tool bar icon (the wrong
description is displayed based on the dll in
which the MFC framework finds the string
resource). Potentially, this problem will show up
anywhere the MFC framework calls
AfxFindResourceHandle or AfxLoadString where the
loaded extension dlls are traversed to find a
resource.
PROPOSED SOLUTION:
We are aware of what dll is the "active dll"
based on the View that the user has currently
made active. When the active view changes what we
do is as follows:
// Get the module state
AFX_MODULE_STATE* pModuleState = AfxGetModuleState
();
AfxLockGlobals(CRIT_DYNLINKLIST);
// Iterate over the active extension dll instance
handle and all other extension dlls that this dll
is dependent upon
for(i = 0; i < pFUIR->m_hInstanceArray.GetSize();
i++)
{
// Get handle of dll
hInstance = *(pFUIR->m_hInstanceArray
[i]);
// Iterate over list maintained by the
module state
for (CDynLinkLibrary* pDLL = pModuleState-
>m_libraryList; pDLL != NULL; pDLL = pDLL-
>m_pNextDLL)
{
// Do the instance handles match?
if(pDLL->m_hModule == hInstance)
{
// Yes
// Remove CDynLinkLibrary
instance from current position in list
pModuleState-
>m_libraryList.Remove(pDLL);
// Add hand
CDynLinkLibrary instance to top of the llist
pModuleState-
>m_libraryList.AddHead(pDLL);
break;
}
}
}
AfxUnlockGlobals(CRIT_DYNLINKLIST);
What this snippet of code does is that it
rearranges the order of CDynLinkLibrary objects
maintained by the module state so that the
CDynLinkLibrary object corresponding to the
active dll is now at the head of the list
followed by the CDynLinkLibrary objects
corresponding to the other dlls that are
implicitly loaded by the "active dll".
Now when AfxFindResourceHandle or AfxLoadString
functions are called the extension dlls get
traversed in the order we desire and the resource
is found in the "correct dll".
IS THIS THE RIGHT WAY?
Searching through Microsoft knowledge base and
postings in the various newsgroups the solutions
that we have come across suggest maintaining
unique resource IDs across all the extension dlls
to be loaded. This would be a big undertaking for
us at the current stage of the project.
Is there a problem with the above solution being
proposed?
There is a concern in the group that we should
not change the order of CDynLinkLibrary objects
in module state object as we are messing with MFC
code and this may have unknown implications. I
have looked at all of MFC code and the way this
list is used internally should not be effected by
the order of the the CDynLinkLibrary objects in
the list.
Your thoughts on this matter would be appreciated.
Thanks,
Ranjit
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.