"Required Resource is not available" Oh the agony !!!

I recently got my hands dunked into VC++ code. With my limited brain matter and absolutely clean C++ hands, i got flummoxed with a doozy !

Problem:
I need to package my C++ UI (PropertySheet / Page Wizard like UI) into a regular DLL. Then call it from the main application. So here's my sample code...

CPropertySheet obSheet(_T("MySheet"));
CMyPage obPage;
obSheet.AddPage( &obPage );
obSheet.SetWizardMode();
obSheet.DoModal();

This would work except when called from the main App (EXE). When called from the mainApp, it pops an error message "Required Resource is not available" and no UI. The offending line is the DoModal call..

After some help and lots of motivation to find the resolution of this irritating lil thing, here is what I found. When called from the exe, it attempts to read the resources from the Exe file instead of ones in the Dll. (Don't ask me why ?) That explains the resource missing error message.

Resolution:
We need to tell the powers that be .. to do this switch when we do the UI magic.

Set Res Handle to current DLL's path :

HINSTANCE m_hOldResHandle = AfxGetResourceHandle();

TCHAR szPathName[_MAX_PATH];
for Extension DLL
::GetModuleFileName(AfxGetAppModuleState()->m_hCurrentInstanceHandle,
szPathName,
_MAX_PATH)
for reg DLLs
::GetModuleFileName(AfxGetStaticModuleState()->m_hCurrentInstanceHandle,
szPathName,
_MAX_PATH)

AfxSetResourceHandle(::GetModuleHandle(szPathName));


Reset when you are done :
AfxSetResourceHandle( m_hOldResHandle );

So what I did in the end was
wrap up this code into an exported [ _declspec(dllexport) ] static gateway method ShowDialog()
void CGateWayClass::ShowDialog()
{
//set res handle

CPropertySheet obSheet(_T("MySheet"));

CMyPage obPage;
obSheet.AddPage( &obPage );
obSheet.SetWizardMode();
obSheet.DoModal();

//reset res handle

}

"Holy Cow Batman! I'm glad that's over!!"

1 comment:

  1. Thanks for this. I am having the same issue, except the resource I need to point to is a DLL in a different project. Using your code, my current instance handle is still my EXE app. Do you know how I could set my resource handle to a different dll?

    ReplyDelete