Время от времени я вижу, как кто-то спрашивает функцию, которая конвертирует LCID (это такие штуки вроде $0409 для English-US) в языковые идентификаторы RFC 1766 (а это - "en-us") и наоборот. Ну, тут есть простое правило: если то, о чём вы спрашиваете, - это языковая штука, которая требуется web-браузеру, то вам нужно начать поиски с библиотеки MLang. В нашем случае нас будет интересовать метод
IMultiLanguage.GetRfc1766FromLcid
.Для примера я написал код, который принимает US-English и конвертирует его в формат RFC 1766. Чтобы было забавнее, он также конвертирует "sv-fi" (Finland-Swedish) в LCID:
program Project1; {$APPTYPE CONSOLE} uses Windows, SysUtils, OleAuto, ActiveX, MLang; var hr: HRESULT; pml: IMultiLanguage; bs: WideString; lcid: Windows.LCID; begin hr := CoInitialize(nil); if SUCCEEDED(hr) then begin hr := CoCreateInstance(CLSID_CMultiLanguage, nil, CLSCTX_ALL, IID_IMultiLanguage, pml); if SUCCEEDED(hr) then begin // Let's convert US-English to an RFC 1766 string lcid := MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); hr := pml.GetRfc1766FromLcid(lcid, &bs); if SUCCEEDED(hr) then WriteLn(bs); // And a sample reverse conversion just for good measure bs := 'sv-fi'; if SUCCEEDED(pml.GetLcidFromRfc1766(lcid, bs)) then WriteLn(Format('%x', [lcid])); Finalize(pml); end; CoUninitialize; end; end.Когда вы запустите программу, то увидите такой вывод:
en-us 81D"en-us" - это способ RFC 1766 сказать "US-English", а $081D - это
MAKELCID(MAKELANGID(LANG_SWEDISH, SUBLANG_SWEDISH_FINLAND), SORT_DEFAULT)
.Если вы покопаетесь в MLang, то увидите кучу других интересных вещей, которые вы можете с ней делать. Если вы помните, мы использовали MLang ранее, чтобы показывать строки без квадратиков (прим.пер.: и для представления web-страницы в понятном виде).
Обновление (январь 2008): ребята из команды глобализации сказали мне, что они предпочли бы, чтобы люди не использовали MLang для этой цели, а использовали бы функции
LCIDToLocaleName
и LocaleNameToLCID
. Эти функции поставляются с Windows Vista и доступны на предыдущих системах через отдельный redistributable.Прим.пер.: зачем в Delphi коде вставлен вызов
pml := nil
, если интерфейсы в Delphi являются автофинализируемыми типами?
Видимо, вызов pm:=nil сделан для того, чтобы освободить интерфейс до того, как вызовется CoUninitialize. Без принудительного обнуления переменной интерфейс будет авто-освобождаться уже после отработки основного тела функции (в т. ч. и после CoUninitialize)
ОтветитьУдалить