我为例如 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 文件名和完整路径。
这是我过去用来实现此目的的方法:
这假设您已将所有资源文件编译到主 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
时)