четверг, 19 мая 2011 г.

Конвертируем между LCID и кодами языков RFC 1766

Это перевод Converting between LCIDs and RFC 1766 language codes. Автор: Реймонд Чен.

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

      pml := nil;
    end;
  end;
  CoUninitialize;
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 являются автофинализируемыми типами?

1 комментарий:

  1. Видимо, вызов pm:=nil сделан для того, чтобы освободить интерфейс до того, как вызовется CoUninitialize. Без принудительного обнуления переменной интерфейс будет авто-освобождаться уже после отработки основного тела функции (в т. ч. и после CoUninitialize)

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.