Andrew Truckle
Andrew Truckle

Reputation: 19197

Do you cache the LoadLibrary HINSTANCE?

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

Answers (1)

Andrew Truckle
Andrew Truckle

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

Related Questions