how to convert SAPI's MS LANG ID to BCP 47 language tag?

828 views Asked by At

The call to SAPI's get language method returns an MS LangID, but for my purpose, it needs to be converted to a BCP 47 language tag (eg. en-GB) . how do we do it?

I am not able to do it using LCIDToLocalName, as to use this function, I need to convert the returned value into the LCID format first.

For eg, it returns "809" for english, now how do I convert it into LCID first, as LCIDHex for English is "0809", and LCIDec is "2057".

Any help would be appreciated.

Edit: Following is the code

if (S_OK != SpEnumTokens(SPCAT_VOICES, NULL, NULL, &voice_tokens))
    return FALSE;

unsigned long voice_count, i = 0;
hr = voice_tokens->GetCount(&voice_count);
cout << " count " << voice_count << endl;
for (unsigned int i = 0; i < voice_count; i++){
    //cout << i << endl;
    CComPtr<ISpObjectToken> voice_token;
    if (S_OK != voice_tokens->Next(1, &voice_token, NULL))
        return FALSE;

    WCHAR *description;
    if (S_OK != SpGetDescription(voice_token, &description))
        return FALSE;


    CComPtr<ISpDataKey> attributes;
    if (S_OK != voice_token->OpenKey(kAttributesKey, &attributes))
        return FALSE;

    WCHAR *gender_s;
    TtsGenderType gender;
    if (S_OK == attributes->GetStringValue(kGenderValue, &gender_s)){
        if (0 == _wcsicmp(gender_s, L"male"))
            gender = TTS_GENDER_MALE;
        else if (0 == _wcsicmp(gender_s, L"female"))
            gender = TTS_GENDER_FEMALE;
    }


    WCHAR *language;
    if (S_OK != attributes->GetStringValue(kLanguageValue, &language))
        return FALSE;

    wprintf(L"%s\n", language);

The last line prints hex values such as 409 and 809, but I want it in format like En-US .

1

There are 1 answers

1
Eric Brown On

@HansPassant is correct. You've got a string; parse it as hex. Use _wtoi (or your favorite parser), then pass to LCIDToLocaleName.

For XP, you can use DownlevelLCIDToLocaleName; the required DLL is downloadable from the Microsoft Download Center.