2011-05-17 74 views
1

有沒有一種方式來獲得使用Windows API的語言ISO代碼的主要語言ID?我想爲我的GetDateFormatInt函數使用它,我很好奇,如果沒有使用常量的方式。雖然該函數不使用英語的默認sublang,但我只對主要語言ID感興趣。如何ISO 639-1代碼轉換爲語言ID

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; 

回答

6

免責聲明:我只是基於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. 

警告德爾福7用戶:

TLanguages.Create有an issue with 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); 
+0

我冒昧地添加警告德爾福7個用戶喜歡我。我希望你不介意。 – 2011-06-07 13:06:01

+0

@The_Fox謝謝!我不知道這個問題。 – 2011-06-07 13:07:51

+0

我也不知道,直到客戶端失敗。即使使用錯誤報告,我也無法找到它發生錯誤的地方,但測試人員可能會在服務器上重現問題。然後我發現了一些額外的日誌記錄的錯誤。 – 2011-06-08 06:48:04

相關問題