Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.01.21;
Скачать: CL | DM;

Вниз

Мультиязычность интерфейса.   Найти похожие ветки 

 
d_xaos ©   (2007-01-02 14:55) [0]

Появилась необходимость перевести софтину на другие языки. Решил пойти по пути наименьшего сопротивления:

1) Создал lng файл следующего вормата
название_формы - название_компонента - название_Properties - значение

2) при загрузке считываю считываю строки и в строковых переменных Form_name, component_name, Properties_name, Properties_value имею всё, что надо.

3) При помощи FindComponent можно менять всё, но там надо явно указывать:

 With TLabel(Form1.FindComponent(component_name)) do begin
       caption:=Some_Value;
       hint:=Some_Value;
 end;

Вопрос в следующем:
Как имея в переменных нужные значения, поменять свойства компонентов на форме?


 
Anatoly Podgoretsky ©   (2007-01-02 15:04) [1]

Это далеко не наименьшее сопротивление.
Хочешь наименьшего сопротивления, то используй встроеный Translation Manager


 
Eraser ©   (2007-01-02 15:17) [2]

> [1] Anatoly Podgoretsky ©   (02.01.07 15:04)

чаще всего это не выход. большинство известных мне мультиязычных продуктов используют lng файлы. по ряду причин для небольших шароварных проектов такой вариант на много лучше, чем встроенное средство.

кстати к слову! :) вот тоже планирую реализовать поддержку нескольких языков в проекте, посоветуйте пожалуйста хороший компонент, понимаю, что на torry.net много всего есть, но хочется именно проверенное решение.


 
Джо ©   (2007-01-02 16:26) [3]

> Вопрос в следующем:
> Как имея в переменных нужные значения, поменять свойства
> компонентов на форме?

Смотри TypInfo.pas.


> [2] Eraser ©   (02.01.07 15:17)

Лучший компонент — свой собственный! :)


 
Eraser ©   (2007-01-02 16:39) [4]

> [3] Джо ©   (02.01.07 16:26)

согласен,
но очень просто не хочется изобретать велосипед ) ни времени, ни желания нету ))


 
d_xaos ©   (2007-01-02 17:33) [5]

Насчёт времени - это точно. Надо за 50 вечеров перелопатить то, над чем в своё время сидел пол года :(

А есть ли толковые/вменяемые бесплатные компоненты для русификации??


 
Anatoly Podgoretsky ©   (2007-01-02 17:46) [6]

> d_xaos  (02.01.2007 17:33:05)  [5]

Translation Manager и никаких 50 вечеров не потребуется.


 
d_xaos ©   (2007-01-02 17:55) [7]

Так первод на мультиязычность - это 3% от общей работы :(


 
d_xaos ©   (2007-01-02 18:04) [8]

Да, а как Translation Manager справляется с поиском в коде всяческих MessageBox и т.д.


 
Anatoly Podgoretsky ©   (2007-01-02 18:07) [9]

> d_xaos  (02.01.2007 18:04:08)  [8]

Изучай Дельфи в части resourcestring


 
azl ©   (2007-01-02 20:05) [10]

Я делал для своей программы мультиязычный интерфейс. Делал все при помощи ini-файлов.
Создавал ini-файлы с нужным мне языком. Считывал, какие есть языковые файлы для создания списка доступных языков. Потом в программе из списка выбирал нужный мне язык и просто считывал из него и все.


 
Palladin ©   (2007-01-02 20:17) [11]


> [10] azl ©

с ума сойти, а что ж с простым циклом то справиться не можешь...


 
azl ©   (2007-01-02 20:28) [12]

Palladin, это ты к чему?


 
Дмитрий Белькевич ©   (2007-01-05 04:23) [13]

Пробуй то, чем сам перевожу. Если будут вопросы, пиши в мыло. Если найдешь глюки - пиши. Лишние компоненты/библиотеки закомменть.

Юзать в основном модуле (dpr):

Internat: TInternationalization;

for i := 0 to Screen.FormCount - 1 do
 Internat.Execute(Screen.Forms[i]);

p.s. очень предпросмотра не хватает. Вот пощу код и думаю - будет нормальный или кривой?


//--------------------------------------------------------//
//                                                        //
//  Revised:  Dmitry Belkevich                            //
//  Version: 1.3                                          //
//  Based on TInternationalisation by Igor Izotov         //
//                                                        //
//          Copyright (c) 2004, 2006 Dmitry Belkevich     //
//           http://www.makhaon.com                       //
//                                                       //
//--------------------------------------------------------//

//--------------------------------------------------------//
//                                                        //
//  Author:  Igor Izotov                                  //
//  Company: proTeam Spb.                                 //
//  Version: 1.0                                          //
//                                                        //
//          Copyright (c) 2002 proTeam Spb.               //
//           http://www.rugdesign.spb.ru                  //
//                                                        //
//--------------------------------------------------------//

//--------------------------------------------------------//
// Visual component for Internationalization feature      //
// in your application.                                   //
// Just drop this component onto your Form,               //
// start your application, close application,             //
// copy text from messages_XXX.log file into              //
// new created file messages_XXX.prop and edit this       //
// file by the adding required strings values like this:  //
//   Zoom In = Óâåëè÷èòü                                  //
//                                                        //
// XXX is an extension defines a local language setting   //
// on a working computer                                  //
//                                                        //
// En empty file messages_XXX.log means you"ve finished   //
// localization process                                   //
//--------------------------------------------------------//

unit Internationalization;

interface

uses
Classes,
JvPageListTreeView,
JclFileUtils,
ActnMan,
ComCtrls,
DBCtrls,
ExtCtrls,
Forms,
SysUtils,
MakStrUtils,
TypInfo,
StdCtrls,
Buttons,
CoolGrid,
Dialogs,
TBXExtItems,
Controls,
Windows;

type
TInternationalization = object
private
 FForm: TForm;
 Translated: TStringList;
 NotTranslated: TStringList;
public
 procedure Execute(Form: TForm);
 procedure CheckAndSetComponentPropertyString(var s: string; const PropName: string); overload;
 procedure CheckAndSetComponentPropertyString(const prop: string; var cm: TObject); overload;
 procedure CheckAndSetComponentPropertyStrings(prop: TStrings;const PropName: string);
 function GetString(const CompName, Value: string): string;
end;

implementation

uses DBGridEh;

procedure TInternationalization.CheckAndSetComponentPropertyString(var s: string; const PropName: string);
var
TempInt: integer;
strValue: string;
begin
if (s <> "") and (s <> "-") and not TryStrToInt(s, TempInt) then
begin
 strValue := GetString(PropName, s);
 if strValue <> "" then
  s := strValue;
end;
end;

procedure TInternationalization.CheckAndSetComponentPropertyString(const prop: string; var cm: TObject);
var
TempInt: integer;
strValue: string;
begin
if assigned(GetPropInfo(cm, prop)) then
begin
 strValue := GetPropValue(cm, prop);
 if (strValue <> "") and (strValue <> "-") and not TryStrToInt(strValue, TempInt) then
 begin
  strValue := GetString(FForm.Name + "." + (Cm as TComponent).Name + "." + prop, strValue);
  if strValue <> "" then
   SetPropValue(cm, prop, strValue);
 end;
end;
end;

procedure TInternationalization.CheckAndSetComponentPropertyStrings(prop: TStrings;const PropName: string);
var
i: Integer;
TempInt: integer;
Strings: TStringList;
strValue: string;
begin
Strings := TStringList.Create;
try
 Strings.Assign(prop);
 for i := 0 to Strings.Count - 1 do
 begin
  strValue := Strings[i];
  if (strValue <> "") and (strValue <> "-") and not TryStrToInt(strValue, TempInt) then
  begin
   strValue := GetString(Format("%s[%d]", [PropName, i]), strValue);
   if strValue <> "" then
    prop[i] := strValue;
  end;
 end;
finally
 Strings.Free;
end;
end;



 
Дмитрий Белькевич ©   (2007-01-05 04:23) [14]


procedure TInternationalization.Execute;
var
prop_file, prop_file_log: string;
i, j, k: Integer;
cm, cm2: TObject;
strValue: string;
s: string;
begin
prop_file := ChangeFileExt(Application.ExeName, ".itf");
prop_file_log := PathGetTempPath + ExtractFileName(ChangeFileExt(Application.ExeName, ".itf"));
if not FileExists(prop_file) then
 Exit;
Translated := TStringList.Create;
NotTranslated := TStringList.Create;
Translated.LoadFromFile(prop_file);
if FileExists(prop_file_log) then
 NotTranslated.LoadFromFile(prop_file_log);
FForm := Form;
Form.Caption := GetString(FForm.Name + ".Caption", Form.Caption);
for i := 0 to Form.ComponentCount - 1 do
begin
 try
  cm := Form.Components[i];
  CheckAndSetComponentPropertyString("Caption", cm);
  CheckAndSetComponentPropertyString("Hint", cm);
  CheckAndSetComponentPropertyString("Title", cm);
  CheckAndSetComponentPropertyString("Text", cm);
  if cm is TLabeledEdit then
  begin
   strValue := (cm as TLabeledEdit).EditLabel.Caption;
   if (strValue <> "") and (strValue <> "-") then
   begin
    strValue := GetString(FForm.Name + "." + (Cm as TComponent).Name + ".Caption", strValue);
    if strValue <> "" then
     (cm as TLabeledEdit).EditLabel.Caption := strValue
   end;
  end;
  if cm is TActionManager then
   with TActionManager(cm) do
    for j := 0 to ActionBars.Count - 1 do
     with ActionBars[j] do
      for k := 0 to Items.Count - 1 do
      begin
       cm2 := Items[k];
      end;
  if cm is TOpenDialog then
   CheckAndSetComponentPropertyString("Filter", cm);
  if cm is TSaveDialog then
   CheckAndSetComponentPropertyString("Filter", cm);
  if cm is TLabeledEdit then
  begin
   cm2 := TLabeledEdit(cm).EditLabel;
   CheckAndSetComponentPropertyString("Caption", cm2);
  end;
  if cm is TTreeView then
   with TTreeView(cm) do
    for j := 0 to Items.Count - 1 do
    begin
     cm2 := Items[j];
     CheckAndSetComponentPropertyString("Text", cm2);
    end;
  if cm is TListView then
   with TListView(cm) do
    for j := 0 to Columns.Count - 1 do
    begin
     s := Columns[j].Caption;
     CheckAndSetComponentPropertyString(s, FForm.Name + "." + (Cm as TComponent).Name + ".Columns[" + IntToStr(j) +
      "].Caption");
     Columns[j].Caption := s;
    end;
  if cm is TCoolGrid then
   with TCoolGrid(cm) do
    for j := 0 to Columns.Count - 1 do
    begin
     s := Columns[j].Title.Caption;
     CheckAndSetComponentPropertyString(s, FForm.Name + "." + (Cm as TComponent).Name + ".Columns[" + IntToStr(j) +
      "].Caption");
     Columns[j].Title.Caption := s;
    end;
  if cm is TJvSettingsTreeView then
   with TJvSettingsTreeView(cm) do
    for j := 0 to Items.Count - 1 do
    begin
     s := Items[j].Text;
     CheckAndSetComponentPropertyString(s, FForm.Name + "." + (Cm as TComponent).Name + ".Items[" + IntToStr(j) +
      "].Caption");
     Items[j].Text := s;
    end;
  if cm is TTBXComboBoxItem then
  begin
   CheckAndSetComponentPropertyStrings((cm as TTBXComboBoxItem).Strings, FForm.Name + "." + (Cm as TComponent).Name +
    ".Strings");
  end;
  if cm is TComboBox then
  begin
   CheckAndSetComponentPropertyStrings((cm as TComboBox).Items, FForm.Name + "." + (Cm as TComponent).Name +
    ".Items");
  end;
  if cm is TRadioGroup then
  begin
   CheckAndSetComponentPropertyStrings((cm as TRadioGroup).Items, FForm.Name + "." + (Cm as TComponent).Name +
    ".Items");
  end;
  if cm is TTabControl then
  begin
   CheckAndSetComponentPropertyStrings((cm as TTabControl).Tabs, FForm.Name + "." + (Cm as TComponent).Name +
    ".Tabs");
  end;
  if cm is TDBNavigator then
  begin
   CheckAndSetComponentPropertyStrings((cm as TDBNavigator).Hints, FForm.Name + "." + (Cm as TComponent).Name +
    ".Hints");
  end;
  if cm is TDBGridEh then
  begin
   for j := 0 to (cm as TDBGridEh).Columns.Count - 1 do
   begin
    strValue := (cm as TDBGridEh).Columns[j].Title.Caption;
    if (strValue <> "") and (strValue <> "-") then
    begin
     strValue := GetString(FForm.Name + "." + (Cm as TComponent).Name + ".Columns[" + IntToStr(j) + "].Caption",
      strValue);
     if strValue <> "" then
      (cm as TDBGridEh).Columns[j].Title.Caption := strValue;
    end;
    strValue := (cm as TDBGridEh).Columns[j].Title.Hint;
    if (strValue <> "") and (strValue <> "-") then
    begin
     strValue := GetString(FForm.Name + "." + (Cm as TComponent).Name + ".Columns[" + IntToStr(j) + "].Hint",
      strValue);
     if strValue <> "" then
      (cm as TDBGridEh).Columns[j].Title.Hint := strValue;
    end;
   end;
  end;
 except
 end;
end;
Translated.Free;
if NotTranslated.Count > 0 then
 NotTranslated.SaveToFile(prop_file_log);
NotTranslated.Free;
end;

function TInternationalization.GetString(const CompName, Value: string): string;
var
i: Integer;
function IndexOf(const Value: string): integer;
var
 i: integer;
begin
 Result := -1;
 for i := 0 to Translated.Count - 1 do
  if Pos(Value, Translated[i]) <> 0 then
  begin
   Result := i;
   Break;
  end;
end;
begin
i := IndexOf(CompName);
if i = -1 then
begin
 NotTranslated.Add(CompName + "=" + Value);
 Result := Value;
end
else
begin
 Result := Copy(Translated[i], Length(CompName) + 2, MaxInt);
 Translated.Delete(i);
end;
end;

end.



 
Дмитрий Белькевич ©   (2007-01-05 04:35) [15]

p.p.s. почти ровный. Код отдаю за фри, можете пользовать где хотите (если хоть кто-то на это смотрит), насколько знаю, Igor Izotov его отдавал так же. Буду _очень_ признателен за найденные глюки (код релизный, но мало ли) и дополнения.
Выдирает все (или большинство, если что-то найдете, пишите) строковые свойства всех компонент на всех (или на нужных) формах.
Раньше переводил по словарю, но из-за специфических глюков кодировок американской винды переписан в текущий вид. Нет глюка, который (иногда) проявляется при переводах по словарю - каждое свойство переводиться отдельно, зато при изменении свойств нужно (не забывать) переводить повторно. Проблема достаточно просто решается, но не было времени заниматься. Короче, пробуйте, господа!



Страницы: 1 вся ветка

Текущий архив: 2007.01.21;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.049 c
1-1164631313
Alex_C
2006-11-27 15:41
2007.01.21
Переопределение WMPaint


15-1167209356
Курдль
2006-12-27 11:49
2007.01.21
Серьезный вопрос: "КУДА ПОДАТЬСЯ НА НОВЫЙ ГОД??!!"


15-1167751512
_uw_
2007-01-02 18:25
2007.01.21
Приоритет потоков


2-1167032516
KyRo
2006-12-25 10:41
2007.01.21
Подскажите как сделать DBGrid без скролов


2-1167225102
Гульназ
2006-12-27 16:11
2007.01.21
У меня база не работает, как восстановить?