January 5th, 2006

Converting between LCIDs and RFC 1766 language codes

Occasionally, I see someone ask for a function that converts between LCIDs (such as 0x0409 for English-US) and RFC 1766 language identifiers (such as “en-us”). The rule of thumb is, if it’s something a web browser would need, and it has to do with locales and languages, you should look in the MLang library. In this case, the IMultiLanguage::GetRfc1766FromLcid method does the trick.

For illustration, here’s a program that takes US-English and converts it to RFC 1766 format. For fun, we also convert “sv-fi” (Finland-Swedish) to an LCID.

#include <stdio.h>
#include <ole2.h>
#include <oleauto.h>
#include <mlang.h>
int __cdecl main(int argc, char **argv)
{
 HRESULT hr = CoInitialize(NULL);
 if (SUCCEEDED(hr)) {
  IMultiLanguage * pml;
  hr = CoCreateInstance(CLSID_CMultiLanguage, NULL,
                        CLSCTX_ALL,
                        IID_IMultiLanguage, (void**)&pml);
  if (SUCCEEDED(hr)) {
   // Let's convert US-English to an RFC 1766 string
   BSTR bs;
   LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,
                        SUBLANG_ENGLISH_US), SORT_DEFAULT);
   hr = pml->GetRfc1766FromLcid(lcid, &bs);
   if (SUCCEEDED(hr)) {
    printf("%ws\n", bs);
    SysFreeString(bs);
   }
   // And a sample reverse conversion just for good measure
   bs = SysAllocString(L"sv-fi");
   if (bs && SUCCEEDED(pml->GetLcidFromRfc1766(&lcid, bs))) {
    printf("%x\n", lcid);
   }
   SysFreeString(bs);
   pml->Release();
  }
  CoUninitialize();
 }
 return 0;
}

When you run this program, you should get

en-us
81d

“en-us” is the RFC 1766 way of saying “US-English”, and 0x081d is MAKELCID(MAKELANGID(LANG_SWEDISH, SUBLANG_SWEDISH_FINLAND), SORT_DEFAULT).

If you browse around, you’ll find lots of other interesting functions in the MLang library. You may recall that earlier we saw how to use MLang to display strings without those ugly boxes.

Update (January 2008): The globalization folks have told me that they’d prefer that people didn’t use MLang. They recommend instead the functions LCIDToLocaleName and LocaleNameToLCID. The functions are built into Windows Vista and are also available downlevel via a redistributable.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.