在MFC项目中支持多语言,无需使用dll

问题描述 投票:0回答:1

我为例如 Japanese.rc 和 English.rc 创建了不同的 .rc 文件。我想根据用户而不是根据区域设置系统语言加载各自的字符串。

我尝试了以下方法:

// Assume the languagePreference is set by the user (e.g., through a settings menu)
    CString resourcePath = L"C:\\Users\\Meritech-43\\source\\repos\\MFCAppMulti-Language\\MFCAppMulti-Language";
    CString languagePreference = L"Japanese"; // or "English"

    // Construct the resource file name based on the user's language preference
    CString resourceFileName = (languagePreference.CompareNoCase(L"Japanese") == 0) ? resourcePath + L"\\Japanese.rc" : resourcePath + L"\\MFCAppMultiLanguage.rc";
    //TRACE(_T("My variable value: %d\n"), resourceFileName);
    // Load the resource file dynamically
    HMODULE hModule = LoadLibrary(resourceFileName);
    if (hModule != nullptr) {
        // Successfully loaded resources, set the resource handle
        AfxSetResourceHandle(hModule);

        // Load the strings dynamically
        CString strTitle, strHelloMessage;
        strTitle.LoadString(IDS_APP_TITLE);
        strHelloMessage.LoadString(IDS_HELLO_MESSAGE);

        // Display or use the loaded strings as needed
        AfxMessageBox(strTitle + L"\n" + strHelloMessage);

        // Unload the current resource handle
        AfxSetResourceHandle(nullptr);
    }
    else {
        // Failed to load resources, handle the error
        AfxMessageBox(L"Failed to load resources for the selected language.");
    }

但是每次`LoadLibrary(resourceFileName)?返回空值。 CString resourceFileName 包含相应的 .rc 文件名和完整路径。

winapi mfc
1个回答
0
投票

这是我过去用来实现此目的的方法:

这假设您已将所有资源文件编译到主 exe 中。

wchar_t* GetStringFromStringTable(UINT lang, UINT subLang, UINT uStringID)
{

    wchar_t* pwchMem, * pwchCur;
    UINT      idRsrcBlk = uStringID / 16 + 1;
    int       strIndex = uStringID % 16;
    HINSTANCE hModule = NULL;
    HRSRC     hResource = NULL;

    hResource = FindResourceEx(nullptr, RT_STRING,
        MAKEINTRESOURCE(idRsrcBlk),
        MAKELANGID(lang, subLang));

    if (hResource != NULL)
    {
        pwchMem = (wchar_t*)LoadResource(hModule, hResource);

        if (pwchMem != NULL)
        {
            pwchCur = pwchMem;
            for (int i = 0; i < 16; i++)
            {
                if (*pwchCur)
                {
                    int cchString = *pwchCur;  // String size in characters.
                    pwchCur++;
                    if (i == strIndex)
                    {
                        // The string has been found in the string table.
                        wchar_t* pwchTemp = new wchar_t[cchString];
                        wcsncpy(pwchTemp, pwchCur, cchString);
                        pwchTemp[cchString] = '\0';

                        return pwchTemp;
                    }
                    pwchCur += cchString;
                }
                else
                    pwchCur++;
                }
            }
        }
    return NULL;

}

然后你可以这样称呼它:

WCHAR* english = GetStringFromStringTable(LANG_NEUTRAL, SUBLANG_DEFAULT, IDS_HELLO_MESSAGE);
WCHAR* spanish = GetStringFromStringTable(LANG_SPANISH, SUBLANG_SPANISH_ARGENTINA, IDS_HELLO_MESSAGE);

要使用的 LANG_* 和 SUBLANG_* 值可以在您定义的每种语言各自的 .rc 中找到(美国英语除外,当您应该使用

LANG_NEUTRAL
SUBLANG_DEFAULT
时)

© www.soinside.com 2019 - 2024. All rights reserved.