Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect system language in delphi for multi-language project?

I need to translate a program in others languages, actually I have the same program in 3 languages (english, spanish, portuguese), but I translated, recompiled, and I have 3 separate executables. And add more languages, and keep links, and adding new functions is driving me crazy.

So now I decided to keep a single executable, and a external language file, so adding new languages does not need recompiling, just editing the language file with a text editor, and everything is ok.

I want to keep all languages in a single external file. like international.lang

[portuguese]
greeting="Bem-vindo"

[spanish]
greeting="Ben venido"

if the file international.lang is not there, or your language is not on the file, the program will launch in english by default, with no errors. Just like most multi-languages programas based on resources.

So the question is, how detect the Windows language in delphi? Any thoughts on my approach? There is any way to replace all captions on dialogs programaticly?

ps: I'm using delphi7, and I can't find any component that is free that is good.

like image 452
Vitim.us Avatar asked Nov 26 '11 15:11

Vitim.us


2 Answers

You can use the GetSystemDefaultLCID function to get the locale identifier and then use the VerLanguageName function to resolve the language associated name. or use the GetLocaleInfo function

Check this sample

{$APPTYPE CONSOLE}

uses
  Windows,
  SysUtils;


procedure Test_VerLanguageName;
var
  wLang : LangID;
  szLang: Array [0..254] of Char;
begin
  wLang := GetSystemDefaultLCID;
  VerLanguageName(wLang, szLang, SizeOf(szLang));
  Writeln(szLang);
end;

procedure Test_GetLocaleInfo;
var
  Buffer : PChar;
  Size : integer;
begin
  Size := GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SENGLANGUAGE, nil, 0);
  GetMem(Buffer, Size);
  try
    GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SENGLANGUAGE, Buffer, Size);
    Writeln(Buffer);
  finally
    FreeMem(Buffer);
  end;
end;

begin
  try
    Test_VerLanguageName;
    Test_GetLocaleInfo;

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

Note : Starting with Windows Vista exists new functions to get the same locale information, check these functions GetLocaleInfoEx, GetUserDefaultLocaleName and GetSystemDefaultLocaleName

like image 155
RRUZ Avatar answered Nov 12 '22 18:11

RRUZ


I have the same problem although I have to deal with only two languages: English (default) and Polish. I tried all the solutions listed above and none of them was working. I was changing system setting, rebooting etc. and always receiving language English. When switched to Polish everything was displayed in Polish, all Polish locales were set but my application was receiving English as the OS language. After many tries I came across with quite easy and reliable workaround (I do not call it solution) that is good if you have to deal with a small number of languages. So the trick is to check in what language the language list is returned by TLanguages.

function GetLang: Integer; //lcid
const
  lcidEnglish = $9;
  lcidPolish = $415;
var Idx: Integer;
begin
   Result := Languages.IndexOf(lcidPolish);

  if (Result > 0) and
     (Languages.Name[Result].StartsWith('Polski', True)) //'Polski'is the Polish name of the language
  then Result := lcidPolish
  else Result := lcidEnglish;
end;

You can do the same for your three languages. Hope it helps.

like image 34
Ben Avatar answered Nov 12 '22 18:11

Ben