LANGID Language::getLangID(const wchar_t* locale) { TCHAR languageID[MAX_PATH]; const int charSize = GetLocaleInfoEx(locale, LOCALE_ILANGUAGE, languageID, MAX_PATH); assert(charSize > 0); if (charSize == 0) throw new COMException(E_INVALIDARG); return wcstol(languageID, nullptr, 16); }
/* * On Windows, use CP<code page number> instead of the nl_langinfo() result * * Visual Studio 2012 expanded the set of valid LC_CTYPE values, so have its * locale machinery determine the code page. See comments at IsoLocaleName(). * For other compilers, follow the locale's predictable format. * * Visual Studio 2015 should still be able to do the same, but the declaration * of lc_codepage is missing in _locale_t, causing this code compilation to * fail, hence this falls back instead on GetLocaleInfoEx. VS 2015 may be an * exception and post-VS2015 versions should be able to handle properly the * codepage number using _create_locale(). So, instead of the same logic as * VS 2012 and VS 2013, this routine uses GetLocaleInfoEx to parse short * locale names like "de-DE", "fr-FR", etc. If those cannot be parsed correctly * process falls back to the pre-VS-2010 manual parsing done with * using <Language>_<Country>.<CodePage> as a base. * * Returns a malloc()'d string for the caller to free. */ static char * win32_langinfo(const char *ctype) { char *r = NULL; #if (_MSC_VER >= 1700) && (_MSC_VER < 1900) _locale_t loct = NULL; loct = _create_locale(LC_CTYPE, ctype); if (loct != NULL) { r = malloc(16); /* excess */ if (r != NULL) sprintf(r, "CP%u", loct->locinfo->lc_codepage); _free_locale(loct); } #else char *codepage; #if (_MSC_VER >= 1900) uint32 cp; WCHAR wctype[LOCALE_NAME_MAX_LENGTH]; memset(wctype, 0, sizeof(wctype)); MultiByteToWideChar(CP_ACP, 0, ctype, -1, wctype, LOCALE_NAME_MAX_LENGTH); if (GetLocaleInfoEx(wctype, LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER, (LPWSTR) &cp, sizeof(cp) / sizeof(WCHAR)) > 0) { r = malloc(16); /* excess */ if (r != NULL) sprintf(r, "CP%u", cp); } else #endif { /* * Locale format on Win32 is <Language>_<Country>.<CodePage> . For * example, English_United States.1252. */ codepage = strrchr(ctype, '.'); if (codepage != NULL) { int ln; codepage++; ln = strlen(codepage); r = malloc(ln + 3); if (r != NULL) sprintf(r, "CP%s", codepage); } } #endif return r; }
/* Retrieves the decimal point * Returns the decimal point string or -1 on error */ int libcstring_locale_get_decimal_point( void ) { int decimal_point = -1; #if defined( WINAPI ) DWORD locale_data = 0; #else struct lconv *locale_data = NULL; #endif #if defined( WINAPI ) #if WINVER >= 0x0600 if( GetLocaleInfoEx( LOCALE_NAME_USER_DEFAULT, LOCALE_SDECIMAL, (LPWSTR) &locale_data, sizeof( DWORD ) / sizeof( wchar_t ) ) == 0 ) { return( -1 ); } #elif WINVER >= 0x0500 if( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, (LPSTR) &locale_data, sizeof( DWORD ) / sizeof( char ) ) == 0 ) { return( -1 ); } #else if( libcstring_GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, (LPSTR) &locale_data, sizeof( DWORD ) / sizeof( char ) ) == 0 ) { return( -1 ); } #endif decimal_point = (int) locale_data; #else locale_data = localeconv(); if( locale_data == NULL ) { return( -1 ); } if( locale_data->decimal_point == NULL ) { return( -1 ); } decimal_point = ( locale_data->decimal_point )[ 0 ]; #endif return( decimal_point ); }
std::wstring Language::getLangIDStringWithoutLeadingZeros(const wchar_t* locale) { TCHAR languageID[MAX_PATH]; const int charSize = GetLocaleInfoEx(locale, LOCALE_ILANGUAGE, languageID, MAX_PATH); assert(charSize > 0); if (charSize == 0) throw new COMException(E_INVALIDARG); const wchar_t* langIDWithoutTrailingZeros = languageID; while (*langIDWithoutTrailingZeros == '0') { langIDWithoutTrailingZeros++; } return langIDWithoutTrailingZeros; }
BOOL CALLBACK MyFuncLocaleEx(LPWSTR pStr, DWORD dwFlags, LPARAM lparam) { UNREFERENCED_PARAMETER(dwFlags); WCHAR** argv = (WCHAR**)lparam; WCHAR wcBuffer[BUFFER_SIZE]; int iResult; // Get its LCID LCID lcid = LocaleNameToLCID(pStr, NULL); if (lcid != 0) wprintf(L"LCID for %s is %x\n", pStr, lcid); else wprintf(L"Error %d getting LCID\n", GetLastError()); // Print out the locale name we found iResult = GetLocaleInfoEx(pStr, LOCALE_SENGLANGUAGE, wcBuffer, BUFFER_SIZE); // If it succeeds, print it out if (iResult > 0) wprintf(L"Locale %s (%s)\n", pStr, wcBuffer); else wprintf(L"Locale %s had error %d\n", pStr, GetLastError()); // CompareStringEx if this is the system locale, let us know iResult = GetSystemDefaultLocaleName(wcBuffer, BUFFER_SIZE); if (iResult > 0) { if (CompareStringEx(LOCALE_NAME_INVARIANT, LINGUISTIC_IGNORECASE, wcBuffer, -1, pStr, -1, NULL, NULL, 0) == CSTR_EQUAL) { wprintf(L"\nLocale %s is the system locale!\n", wcBuffer); system("Pause"); } } else { wprintf(L"Error %d getting system locale\n", GetLastError()); system("Pause"); } return (TRUE); }
// Parses the settings from an ini file. Supports UTF16, UTF8 or ANSI files // Use forceLang for force a specific language void ParseTranslations( const wchar_t *fname, const wchar_t *forceLang ) { g_Translations.Reset(); if (fname) { if (!g_Translations.LoadText(fname)) return; g_Translations.ParseText(); } wchar_t languages[100]={0}; if (forceLang && *forceLang) { int len=(int)wcslen(forceLang); if (len>5) len=5; memcpy(languages,forceLang,len*2); wcscpy_s(languages+len+1,10,L"default"); } else { ULONG size=4; // up to 4 languages ULONG len=_countof(languages); GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME,&size,languages,&len); wcscpy_s(languages+len-1,10,L"default"); languages[len+7]=0; } g_Translations.FilterLanguages(languages); // Checks for right-to-left languages g_bRTL=false; LOCALESIGNATURE localesig; LANGID language=GetUserDefaultUILanguage(); if (forceLang && *forceLang) { if (GetLocaleInfoEx(forceLang,LOCALE_FONTSIGNATURE,(LPWSTR)&localesig,(sizeof(localesig)/sizeof(wchar_t))) && (localesig.lsUsb[3]&0x08000000)) g_bRTL=true; } else { if (GetLocaleInfoW(language,LOCALE_FONTSIGNATURE,(LPWSTR)&localesig,(sizeof(localesig)/sizeof(wchar_t))) && (localesig.lsUsb[3]&0x08000000)) g_bRTL=true; } }
BOOL CALLBACK MyFuncLocaleEx(LPWSTR pStr, DWORD dwFlags, LPARAM lparam) { WCHAR wcBuffer[BUFFER_SIZE]; int bufferSize; bufferSize = GetLocaleInfoEx(pStr, LOCALE_SENGLANGUAGE, wcBuffer, BUFFER_SIZE); if (bufferSize == 0) { wprintf(L"Locale %s had error %d\n", pStr, GetLastError()); return (TRUE); } LCID lcid = LocaleNameToLCID(pStr, nullptr); if (lcid == 0) { wprintf(L"Error %d getting LCID\n", GetLastError()); return (TRUE); } if (lcid > 0x8000) { wprintf(L"//"); } wprintf(L" { 0x%.4x, \"%s\" }, //%s\n", lcid, pStr, wcBuffer); return (TRUE); }