Jonas
Jonas

Reputation: 1214

Convert three letter language code to language identifier (LANGID)

Is there some way in the Win32 API to convert a three letter language code, as returned by GetLocaleInfo() with LOCALE_SABBREVLANGNAME specified, to a corresponding LANGID or LCID? That is, going in "reverse" to what GetLocaleInfo() normally does?

What I'm trying to do is to parse what kind of language a resource DLL is using, and so far, without touching anything about the DLL, going by the dll name with a format nameLNG.dll, where LNG is a three letter language code, seems to be the easiest method, assuming such a function exists.

If this isn't easy to do, I guess Plan B is to give our language DLL's a version info resource, specify their respective cultures there, and later on in the application, read which cultures they use.

Upvotes: 5

Views: 6025

Answers (3)

Heath Hunnicutt
Heath Hunnicutt

Reputation: 19477

You can obtain the LangID by calling GetLocaleInfo() with LOCAL_RETURN_NUMBER|LOCALE_ILANGUAGE for the LCType parameter, just as you passed LOCALE_SABBREVLANGNAME to obtain the three-letter ISO code. By passing the same lcid to this function, you can store the corresponding LangID with the ISO code.

Note that MSDN says LOCALE_ILANGUAGE should not be used in favor LOCALE_SLANG on Vista and above, but I believe the comment does not apply for use of LOCALE_ILANGUAGE with LOCALE_RETURN_NUMBER.

As your project evolves, you might generate several localized files for each language. For this reason, I would suggest you store your localized files in subdirectories named after the language. Microsoft has used directories named after the LangID's, for example "1033" as the English resources directory. I think it would be more friendly to use the three-letter code, such as "ENU\name.dll". In any case, subdirectories are a simple solution and hopefully won't complicate your build process as much as changing the target file name.

Upvotes: 0

Serge Wautier
Serge Wautier

Reputation: 21888

Unfortunately, there's no direct Win32 API that gives you a LANGID given a 3-letters abbreviation.

It looks like CLanguageSupport is your friend today :-) It already implements your plan B to lookup the LANGID based on the contents of the version info resource.

The piece of code you're looking for is int the function

LANGID CLanguageSupport::GetLangIdFromFile(LPCTSTR pszFilename)

Of course, the drawback is that you may have a mismatch between the version info and the DLL name. But you'd very quickly catch it during tests. And if you let a tool such as appTranslator create the DLLs for you, you're sure to be on the safe side.

Upvotes: 2

D.Shawley
D.Shawley

Reputation: 59583

You can enumerate the installed locales using EnumSystemLocales() and build the map yourself. I do this during application initialization in a service that I wrote a while ago and it has worked out well thus far.

I would recommend using Plan B in this case. I usually steer clear of encoding stuff into the file name. If for no other reason, using the 3-character ISO-639 variant isn't perfect unless you strictly specify which variant you are using - ISO-639-2/B, ISO-639-2/T, or ISO-639-3.

If you need to provide locale-specific variants, then you should take a close look at RFC3066. Basically, you need to specify the language and country code and, in some cases, the region code as well. In any case, the LCID encapsulates all of this goodness.

The one thing that I am not completely certain of is whether the langID in the resource information is a full LCID or not. The codes listed in the VERSIONINFO reference are LCIDs so I would try using an LCID in the VERSIONINFO header. If not, you can always include the information as a string in the string block.

Upvotes: 1

Related Questions