Преобразовать трехбуквенный код языка в идентификатор языка (LANGID)

Есть ли какой-нибудь способ в Win32 API для преобразования трехбуквенного кода языка, возвращаемого с GetLocaleInfo()помощью LOCALE_SABBREVLANGNAMEуказанного, в соответствующий LANGIDили LCID? То есть идти в «обратном направлении» к тому, что GetLocaleInfo()обычно делает?

То, что я пытаюсь сделать, - это проанализировать, какой язык использует ресурсная DLL, и до сих пор, не затрагивая ничего о DLL, переходя по имени dll к формату nameLNG.dll, где LNGесть трехбуквенный код языка, кажется, быть самым простым методом, предполагая, что такая функция существует.

Если это нелегко сделать, я думаю, что План Б состоит в том, чтобы предоставить нашим языковым DLL информационный ресурс версии, указать их соответствующие культуры, а затем в приложении прочитать, какие культуры они используют.

13.10.2009 12:23:25
3 ОТВЕТА
РЕШЕНИЕ

К сожалению, нет прямого Win32 API, который бы давал вам LANGID с трехбуквенным сокращением.

Похоже, CLanguageSupport ваш друг сегодня :-) Он уже реализует ваш план B по поиску LANGID на основе содержимого ресурса информации о версии.

Кусок кода, который вы ищете, является функцией

LANGID CLanguageSupport::GetLangIdFromFile(LPCTSTR pszFilename)

Конечно, недостатком является то, что у вас может быть несоответствие между информацией о версии и именем DLL. Но вы очень быстро поймете это во время тестов. И если вы позволите такому инструменту, как appTranslator, создать библиотеки DLL для вас, вы наверняка будете в безопасности.

2
23.05.2017 11:48:41
Да, я думаю, что в итоге я буду использовать этот класс, поскольку вы, очевидно, уже обошли стороной не только одну, но и две проблемы, с которыми мы сейчас сталкиваемся. Мы можем даже реализовать языковое подменю, которое я только что убрал, думая, что наш переход на механизм MFC будет окончательным. Ну да ладно ...
Jonas 14.10.2009 07:50:30

Вы можете перечислить установленные локали, используя EnumSystemLocales()и построить карту самостоятельно. Я делаю это во время инициализации приложения в сервисе, который я написал некоторое время назад, и до сих пор это работало хорошо.

Я бы порекомендовал использовать план Б в этом случае. Я обычно избегаю кодирования вещей в имени файла. Если по какой-либо другой причине использование трехсимвольного варианта ISO-639 не является идеальным, если вы строго не укажете, какой вариант вы используете - ISO-639-2 / B, ISO-639-2 / T или ISO-639- 3 .

Если вам нужно предоставить специфичные для локали варианты, вам следует внимательно изучить RFC3066 . В основном вам необходимо указать язык и код страны, а в некоторых случаях и код региона. В любом случае, LCID заключает в себе все эти качества.

В одном я не совсем уверен, является ли langID в информации о ресурсе полным LCID или нет. Коды, перечисленные в справочнике VERSIONINFO, являются идентификаторами LCID, поэтому я бы попробовал использовать LCID в заголовке VERSIONINFO. Если нет, вы всегда можете включить информацию в виде строки в строковый блок.

1
13.10.2009 12:52:22
EnumSystemLocales дают только список из трех буквенных аббревиатур, верно? Я не уверен, как построить карту, используя только эту информацию и не имея LCID или LANGID для перевода? Это решение было бы идеально, если бы функция обратного вызова для EnumSystemLocales вернула бы пару строк LCID и "ISO".
Jonas 14.10.2009 07:45:47
Аргументом для EnumLocalesProcфактически является LCID, отформатированный как шестнадцатеричное число в строку. Документация не совсем ясна по этому поводу - «Указатель на буфер, содержащий строку идентификатора локали с нулевым символом в конце» . Чего они не упоминают, так это того, что вы должны вызвать что-то вроде _tcstoul(lpLocaleString, NULL, 16)этого, чтобы получить идентификатор локали в удобной форме. Получив LCID, вы можете получить то, что вам нужно, с GetLocaleInfo()помощью LOCALE_SISO639LANGNAMEи LOCALE_SISO3166CTRYNAME.
D.Shawley 14.10.2009 11:01:33

Вы можете получить идентификатор языка по телефону GetLocaleInfo()с LOCAL_RETURN_NUMBER|LOCALE_ILANGUAGEдля LCType параметра, так же , как вы прошли , LOCALE_SABBREVLANGNAMEчтобы получить три-буквенный код ISO. Передав этот же lcid этой функции, вы можете сохранить соответствующий LangID с кодом ISO.

Обратите внимание, что MSDN говорит, LOCALE_ILANGUAGEчто не следует использовать в LOCALE_SLANGVista и выше, но я считаю, что комментарий не относится к использованию LOCALE_ILANGUAGEс LOCALE_RETURN_NUMBER.

По мере развития вашего проекта вы можете создавать несколько локализованных файлов для каждого языка. По этой причине я бы посоветовал вам хранить ваши локализованные файлы в подкаталогах, названных по имени языка. Microsoft использовала каталоги, названные в честь LangID, например, «1033» в качестве каталога ресурсов на английском языке. Я думаю, что было бы более удобно использовать трехбуквенный код, такой как «ENU \ name.dll». В любом случае, подкаталоги - это простое решение, и мы надеемся, что оно не будет усложнять процесс сборки так же, как изменение имени целевого файла.

0
13.10.2009 23:20:39
У меня, к сожалению, нет доступа к LCID, но я хочу LANGID из трехбуквенной аббревиатуры с кодом языка (код faux-ISO).
Jonas 14.10.2009 07:42:38
FWIW, MS хочет, чтобы мы отошли от LOCALE_ILANGUAGE, потому что они хотят перейти на "только идентификаторы строк", идентификаторы культур .NET. Как они пытаются убедить нас, что когда- нибудь LANGID может умереть, по крайней мере, для недавно поддерживаемых языков в Win8 +
Serge Wautier 14.10.2009 07:59:02