C ++三字母语言名称为LCID

时间:2019-07-01 12:45:59

标签: c++ windows winapi internationalization

如何将ISO639-3三字母语言名称(例如“ PLK”,“ DEU”,“ ENU”)转换为语言代码(例如,对于PLK为0x0415,对于DEU为0x0407,对于ENU为0x0409)或转换为文化名称(例如,PLK是“ pl-PL”,DEU是“ de”,ENU是“ en-US”)?

我需要在以下代码行中进行反向转换:

GetLocaleInfoA(0x0415, LOCALE_SABBREVLANGNAME, buffer.data(), buffer.size());
    // now buffer will have "PLK"

我希望能够写类似的东西:

LCID langCode = SomeMagicalFunctionThatISearchFor("PLK");
//and landCode should be now 0x0415 (1045 in decimal)

我的代码针对Microsoft Windows,因此可以使用WinAPI。

2 个答案:

答案 0 :(得分:2)

static LCID lcid = -1;
::EnumSystemLocalesEx([](LPWSTR a1, DWORD a2, LPARAM a3) -> BOOL {
        const int cch = 512;
        wchar_t wcBuffer[cch] = { 0 };
        int iResult = ::GetLocaleInfoEx(a1, LOCALE_SABBREVLANGNAME, wcBuffer, cch);
        if(iResult > 0 && 0 == ::_wcsicmp(L"PLK", wcBuffer))
        {
            lcid = ::LocaleNameToLCID(a1, 0);
            return FALSE;
        }
        return TRUE;
}, LOCALE_ALL, NULL, nullptr);

答案 1 :(得分:1)

因为它似乎不存在,所以您可以构建自己的。如果您需要进行很多查找,则unordered_map应该可以解决这一问题,以保持信息的存储,以便快速访问。

#include <iostream>
#include <unordered_map>
#include <string_view>
#include <Windows.h>

class LocaleAbbr {
public:
    LocaleAbbr() {
        // enumerate all locales and call "proxy" for each one      
        ::EnumSystemLocalesEx(proxy, LOCALE_ALL, reinterpret_cast<LPARAM>(this), nullptr);
    }
    LCID operator[](std::wstring_view abbr) const {
        // operator to query for LCID from abbreviation
        return name_lcid_map.at(abbr.data());
    }
private:
    BOOL callback(LPWSTR Arg1, DWORD Arg2) {
        // extract abbreviation and LCID
        wchar_t Buffer[512];
        int rv = ::GetLocaleInfoEx(Arg1, LOCALE_SABBREVLANGNAME, Buffer, 512);
        if (rv > 0) // put result in a name->LCID map:
            name_lcid_map.emplace(Buffer, ::LocaleNameToLCID(Arg1, 0));
        return TRUE;
    }
    static BOOL proxy(LPWSTR Arg1, DWORD Arg2, LPARAM Arg3) {
        // cast Arg3 to "this" (set in the constructor) and call "callback"
        return reinterpret_cast<LocaleAbbr*>(Arg3)->callback(Arg1, Arg2);
    }

    std::unordered_map<std::wstring, LCID> name_lcid_map;
};

int main() {
    LocaleAbbr abbr;

    std::wcout << abbr[L"PLK"];
}