c++winapiwindows-mui

FindResourceEx and fallback languages


I have all translations of a resource in a single executable. Effectively:

STRINGTABLE
  LANGUAGE LANG_ENGLISH, LANG_ENGLISH_US
BEGIN
  IDSTR_HELLO "Hello"
END

STRINGTABLE
  LANGUAGE LANG_SPANISH, LANG_SPANISH_PANAMA
BEGIN
  IDSTR_HELLO "Hola"
END

// ... more languages ...

I'm trying to find the (most) appropriate one using FindResourceEx given a LANGID. A LANGID consists of both the language and a sublanguage. For example, I might have resources for Spanish as spoken in Panama (LANGUAGE_SPANISH, SUBLANG_SPANISH_PANAMA) and Spanish as spoken in Mexico (LANGUAGE_SPANISH, SUBLANG_SPANISH_MEXICAN). When there's an exact match between the desired langid and one of the resources, everything is fine.

If I use FindResourceEx to try to find the resource for a third flavor of Spanish, say (LANG_SPANISH, SUBLANG_SPANISH_COSTA_RICA), the find will fail because I don't have a resource specifically for Costa Rica. In such a case, I'd like to "fall back" to any flavor of primary language.

I read something that suggested setting the sublanguage to SUBLANG_NEUTRAL should match any resource with the same primary language:

HRSRC handle = FindResourceEx(NULL, RT_STRING, MAKEINTRESOURCE(IDSTR_HELLO), langid);
if (handle == NULL) {
  fallback_langid = MAKELANGID(PRIMARYLANGID(langid), SUBLANG_NEUTRAL);
  handle = FindResourceEx(NULL, RT_STRING, MAKEINTRESOURCE(IDSTR_HELLO), fallback_langid);
}

Unfortunately that doesn't work. Neither does setting the sublanguage to SUBLANG_DEFAULT. (It seems the neutral and default sublanguages are only meaningful when the primary language is also neutral or default.)

What are my options? Is there a way to enumerate through the resources and do my own comparison of the primary language in the LANGID? I've been looking at the assortment of EnumResource-like functions, but most of them seem specific to using MUI. I'm intentionally not using MUI, for various reasons, including the requirement to have all of the translations in a single binary.


Solution

  • I would be astonished if you can't use EnumResourceLanguages without having MUI files. Of course, if all else fails, perhaps you can create a table with a default sub language for every primary language. Or your table could have a default for every primary/sub language pair. You can store this table in your code or in a custom resource.