Reputation: 19197
Here is sample code:
CString CMeetingScheduleAssistantApp::GetStudyPointDescriptionEx(bool b2019Format, const int iStudyPoint, const bool bFormatText /*false*/)
{
CString strDescription = _T("<ERROR>");
LANGUAGE_E eForeignLanguage = GetForeignLanguageGroupLanguageID();
if (iStudyPoint == 0)
strDescription = _T("");
else
{
if (UseTranslationINI(eForeignLanguage))
{
// Snipped
}
else
{
HINSTANCE hInst = nullptr;
if (eForeignLanguage != LANGUAGE_ENGLISH)
hInst = LoadLibrary(theApp.GetForeignLanguageGroupSatelliteDLLPath());
else
hInst = AfxGetInstanceHandle();
if (b2019Format)
strDescription.LoadString(hInst, IDS_STR_NEW_STUDY_POINT_01 + (iStudyPoint - 1));
else
strDescription.LoadString(hInst, + (iStudyPoint - 1));
if (eForeignLanguage != LANGUAGE_ENGLISH)
FreeLibrary(hInst);
}
if (bFormatText) // AJT v16.0.9
{
CString strFormattedText;
strFormattedText.Format(_T("%d - %s"), iStudyPoint, (LPCTSTR)strDescription);
strDescription = strFormattedText;
}
}
return strDescription;
}
Notice the function calls to load the DLL resource file?
It works fine. My question:
Should I load this DLL file once and cache the HINSTANCE
in the application class until the user changes their mind, or should I constantly load and unload as I need to extract a custom resource value?
Upvotes: 2
Views: 329
Reputation: 19197
Based on all of the comments kindly provided it was decided to cache the resources. So, I now load the resources into a member variable of the application class. This is only done once, at the point the user changes the setting. Thereafter the application uses the cached instance.
void CMeetingScheduleAssistantApp::LoadForeignLanguageGroupSatelliteFile()
{
LANGUAGE_E eForeignLanguage = GetForeignLanguageGroupLanguageID();
ResetForeignLanguageGroupResources();
// Load the new foreign language resources
if (UseTranslationINI(eForeignLanguage))
ReadTranslationINI(m_SatelliteINI, eForeignLanguage, true);
else
{
if (eForeignLanguage == LANGUAGE_ENGLISH)
m_hInstanceSatelliteDLL = AfxGetInstanceHandle();
else
m_hInstanceSatelliteDLL = LoadLibraryEx(GetForeignLanguageGroupSatelliteDLLPath(), nullptr,
LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE);
}
}
void CMeetingScheduleAssistantApp::ResetForeignLanguageGroupResources()
{
if (m_hInstanceSatelliteDLL != nullptr)
{
FreeLibrary(m_hInstanceSatelliteDLL);
m_hInstanceSatelliteDLL = nullptr;
}
m_SatelliteINI.clear();
}
Since this is an additional set of resources to the primary GUI interface the instance is stored in a custom variable and not the system variable m_hResource
.
Therefore, the method shown in my original question now looks like:
CString CMeetingScheduleAssistantApp::GetStudyPointDescriptionEx(bool b2019Format, const int iStudyPoint, const bool bFormatText /*false*/)
{
CString strDescription = _T("<ERROR>");
LANGUAGE_E eForeignLanguage = GetForeignLanguageGroupLanguageID();
if (iStudyPoint == 0)
strDescription = _T("");
else
{
if (UseTranslationINI(eForeignLanguage))
{
CString strLabel, strKey = _T("StudyPoints");
if (b2019Format)
{
strKey = _T("StudyPoints2019");
strLabel.Format(_T("IDS_STR_NEW_STUDY_POINT_%02d"), iStudyPoint);
}
else
strLabel.Format(_T("IDS_STR_STUDY_POINT_%02d"), iStudyPoint);
// AJT v17.1.3 We now use our own method
strDescription = theApp.GetStringFromTranslationINI(m_SatelliteINI, strKey, strLabel);
}
else
{
if (b2019Format)
strDescription.LoadString(m_hInstanceSatelliteDLL, IDS_STR_NEW_STUDY_POINT_01 + (iStudyPoint - 1));
else
strDescription.LoadString(m_hInstanceSatelliteDLL, + (iStudyPoint - 1));
}
if (bFormatText) // AJT v16.0.9
{
CString strFormattedText;
strFormattedText.Format(_T("%d - %s"), iStudyPoint, (LPCTSTR)strDescription);
strDescription = strFormattedText;
}
}
return strDescription;
}
Upvotes: 1