Время от времени я вижу, как кто-то спрашивает функцию, которая конвертирует 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)
ОтветитьУдалить