Форум: "Начинающим";
Текущий архив: 2007.01.21;
Скачать: [xml.tar.bz2];
Вниз
Мультиязычность интерфейса. Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.049 c