Как преобразовать код ISO 639-1 в идентификатор языка - PullRequest
1 голос
/ 17 мая 2011

Есть ли способ получить основной языковой идентификатор из языкового кода ISO с помощью Windows API?Я хочу использовать его для своей функции GetDateFormatInt, и мне любопытно, если есть способ без использования констант.Хотя эта функция не использует субланг по умолчанию для английского языка, меня интересует только основной языковой идентификатор.

function GetDateFormatInt(const aLanguageISOCode: string): string;
const
  C_ISO_CODES: array[0..3] of string = (
    'nl', 'en', 'de', 'fr'
  );
  C_LCIDS: array[0..3] of Cardinal = (
    ((SUBLANG_DUTCH shl 10) or LANG_DUTCH) or (SORT_DEFAULT shl 16),
    ((SUBLANG_ENGLISH_UK shl 10) or LANG_ENGLISH) or (SORT_DEFAULT shl 16),
    ((SUBLANG_GERMAN shl 10) or LANG_GERMAN) or (SORT_DEFAULT shl 16),
    ((SUBLANG_FRENCH shl 10) or LANG_FRENCH) or (SORT_DEFAULT shl 16)
  );
var
  i: Integer;
  lLCID: Cardinal;
  lBuffer: array[0..512] of Char;
begin
  i := AnsiIndexText(aLanguageISOCode, C_ISO_CODES);
  if i > -1 then
    lLCID := C_LCIDS[i]
  else
    lLCID := LOCALE_USER_DEFAULT;

  i := GetDateFormat(lLCID, DATE_LONGDATE, nil, nil, lBuffer, 512);
  SetString(Result, lBuffer, i - 1);
end;

1 Ответ

6 голосов
/ 17 мая 2011

Отказ от ответственности: я написал следующее исключительно на основании существования константы LOCALE_SISO639LANGNAME .Я понятия не имею, действительно ли это работает или полезно в любом случае.Я вообще не тестировал.

unit Iso639;

interface

uses
  Windows;

function Iso639ToPrimaryLangID(const S: string): LANGID;

implementation

uses
  SysUtils, Classes;

var
  Iso639Languages: TStringList = nil;

function GetLocaleDataW(ID: LCID; Flag: DWORD): WideString;
var
  Buffer: array[0..1023] of WideChar;
begin
  Buffer[0] := #0;
  SetString(Result, Buffer, GetLocaleInfoW(ID, Flag, Buffer, SizeOf(Buffer) div 2));
end;

function LangIDFromLcID(ID: LCID): LANGID;
begin
  Result := LANGID(ID);
end;

function PrimaryLangID(LangID: LANGID): LANGID;
begin
  Result := LangID and $3FF;
end;

procedure InitializeIso639Languages;
var
  I: Integer;
  ALocaleID: LCID;
  ALangID: LANGID;
  S: string;
begin
  Iso639Languages := TStringList.Create;
  try
    Iso639Languages.Sorted := True;
    for I := 0 to Languages.Count - 1 do
    begin
      ALocaleID := Languages.LocaleID[I];
      ALangID := PrimaryLangID(LangIDFromLcID(ALocaleID));
      if Iso639Languages.IndexOfObject(TObject(ALangID)) = -1 then
      begin
        S := GetLocaleDataW(ALocaleID, LOCALE_SISO639LANGNAME);
        Iso639Languages.AddObject(S, TObject(ALangID));
      end;
    end;
  except
    FreeAndNil(Iso639Languages);
    raise;
  end;
end;

function Iso639ToPrimaryLangID(const S: string): LANGID;
var
  I: Integer;
begin
  Result := 0;

  if not Assigned(Iso639Languages) then
    InitializeIso639Languages;

  I := Iso639Languages.IndexOf(S);
  if I <> -1 then
    Result := LANGID(Iso639Languages.Objects[I]);
end;

initialization

finalization
  FreeAndNil(Iso639Languages);

end.

Предупреждение для пользователей Delphi 7:

TLanguages.Create имеет проблему с DEP и выбрасывает нарушение прав доступа, когда DEP включен.Так что не используйте Languages[I].LocaleID и получите LocaleID самостоятельно:

function EnumLocalesProc(aLocaleString: PChar): Integer; stdcall;
var
  lLocaleID: LCID;
begin
  lLocaleID := StrToInt('$' + Copy(aLocaleString, 5, 4));
  Result := 1;
end;

EnumSystemLocales(@EnumLocalesProc, LCID_SUPPORTED);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...