Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Локализация 
:(
    Опции темы
mohax
Дата 24.8.2005, 07:49 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Приветствую!
У меня такой вопрос: есть большой проект, >70 форм, >40000 строк кода. Все на русском языке. Сейчас понадобилось добавить англ язык. Как лучше это сделать? Ведь перевести надо не только текст на формах, но и в коде тоже...
  Вверх
Плаха
Дата 24.8.2005, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 126
Регистрация: 10.11.2004
Где: МО п. Киевский

Репутация: нет
Всего: нет



поиши компоненты. гдето я подобное встречал.
Посмотри компонет JoGaLang

Это сообщение отредактировал(а) Плаха - 24.8.2005, 09:08
--------------------
Принимай то что есть и устраивайся как хочеш
PM MAIL ICQ   Вверх
mohax
Дата 24.8.2005, 12:49 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Плаха
интересный компонент... но загвоздка в том что мне нужно "добавить" второй язык и когда пользователь выбирает тот или иной язык, то приложение переключается на него "на лету". Как вот совместить в переводе "на лету" строки с формы и строки из кода...
  Вверх
Dimannn
Дата 26.8.2005, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 318
Регистрация: 14.4.2005
Где: Владимир

Репутация: нет
Всего: 1



Вот. Долго искал. Нашол.
Код

Procedure SetLang(Obj: TComponent);
Var i: Integer;
begin
If Obj.ComponentCount>0 then For i:=0 to Obj.ComponentCount-1 do SetLang(Obj.Components[i]);

If Obj is TForm then (Obj as TForm).Caption:=ini.ReadString('Language',Obj.Name,Obj as TForm).Caption);
If Obj is TLabel then (Obj as TLabel).Caption:=ini.ReadString('Language',Obj.Name,Obj as TLabel).Caption);;
If Obj is TButton then (Obj as TButton).Caption:=ini.ReadString('Language',Obj.Name,Obj as TButton).Caption);;

end;

procedure TForm1.Button1Click(Sender: TObject);
Var I: Integer;
begin
For i:=0 to Application.ComponentCount-1 do  SetLang(Application.Components[i]);

end;


Правда несовсем красиво.
Может, кто подскажет, как зделать что-то типа этого:
If Obj has Caption then Obj.Caption ..



--------------------
Хотите быстро и без проблем опубликовать вашу программу в сети за 5 минут?
Тогда потратьте пару минут чтобы посмотреть, что предлагает OpenProject.org.ru
PM MAIL ICQ   Вверх
Delphins
Дата 26.8.2005, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 10.8.2005
Где: Россия, Краснодар

Репутация: нет
Всего: нет



Код

Procedure SetLang(Obj: TComponent);    
Var i: Integer;    
begin    
// If Obj.ComponentCount>0 then For i:=0 to Obj.ComponentCount-1 do SetLang(Obj.Components[i]);     Это не надо
If Obj is TForm then (Obj as TForm).Caption:=ini.ReadString('Language',Obj.Name,Obj as TForm).Caption);    
If Obj is TLabel then (Obj as TLabel).Caption:=ini.ReadString('Language',Obj.Name,Obj as TLabel).Caption);;    
If Obj is TButton then (Obj as TButton).Caption:=ini.ReadString('Language',Obj.Name,Obj as TButton).Caption);;    
end;    
procedure TForm1.Button1Click(Sender: TObject);    
Var I: Integer;    
begin    
For i:=0 to Application.ComponentCount-1 do  SetLang(Application.Components[i]);    
end;


Так ты пиши компоненыт у которых есть Caption или Text. smile
А код выведи в константы и потом какнить юзай. smile
PM MAIL ICQ Skype MSN   Вверх
Illusion Dolphin
Дата 27.8.2005, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 36
Всего: 63



Цитата

If Obj has Caption then Obj.Caption ..


Код

uses TYPINFO.PAS;

function hasprop(comp: TComponent; const prop: String): Boolean; 
var 
  proplist: PPropList; 
  numprops, i: Integer; 
begin 
  result := false; 
  getmem(proplist, getTypeData(comp.classinfo)^.propcount * Sizeof(Pointer)); 
  try 
    NumProps := getproplist(comp.classInfo, tkProperties, proplist); 
    for i := 0 to pred (NumProps) do 
    begin 
      if comparetext(proplist[i]^.Name, prop) = 0 then 
      begin 
        result := true; 
        break; 
      end; 
    end; 
  finally 
    freemem(proplist, getTypeData(comp.classinfo)^.propcount * Sizeof(Pointer)); 
  end; 
end; 


и ещё:

Код

function HasProperty(Obj: TObject; Prop: string): PPropInfo; 
begin 
  Result := GetPropInfo(Obj.ClassInfo, Prop); 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
  p: pointer; 
begin 
  p := HasProperty(Button1, 'Color'); 
  if p <> nil then 
    SetOrdProp(Button1, p, clRed) 
  else 
    ShowMessage('Button has no color property'); 
  p := HasProperty(Label1, 'Color'); 
  if p <> nil then 
    SetOrdProp(Label1, p, clRed) 
  else 
    ShowMessage('Label has no color property'); 
  p := HasProperty(Label1.Font, 'Color'); 
  if p <> nil then 
    SetOrdProp(Label1.Font.Color, p, clBlue) 
  else 
    ShowMessage('Label.Font has no color property'); 
end; 

imho, как-то так


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Dimannn
Дата 27.8.2005, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 318
Регистрация: 14.4.2005
Где: Владимир

Репутация: нет
Всего: 1



Цитата(Delphins @ 26.8.2005, 22:41)
// If Obj.ComponentCount>0 then For i:=0 to Obj.ComponentCount-1 do SetLang(Obj.Components[i]);    Это не надо


Почему же не надо. Так он толлько у форм каптион поменяет.
Добавлено @ 20:02
Тока что попробовал. Действительно так.


--------------------
Хотите быстро и без проблем опубликовать вашу программу в сети за 5 минут?
Тогда потратьте пару минут чтобы посмотреть, что предлагает OpenProject.org.ru
PM MAIL ICQ   Вверх
TP@MB@Y
Дата 30.8.2005, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 18.12.2004
Где: Москва

Репутация: нет
Всего: 4



По сабжу:
Можно создать матрицу строк размера M*N, где M - кол-во текстовых констант, а N - кол-во языков. Заполнить. В настройках сделать выюор языка (например через радиопереключатели), а в ходе программы выводить соответствующие константы. Идея думаю ясна.
PM   Вверх
bel_nikita
  Дата 30.8.2005, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: нет
Всего: 47



Можно обойтись без матрицы, а использовать XML smile
Не знаю, как тут у Вас в Дельфях, но у меня в Сях так:
Идея такова, что нужен XML-парсер и метод GetString(), который будет извлекать из *.xml файла нужный перевод в зависимости от языка. Ваша программа прежде, чем вывести, что-либо на форму вызывает метод GetString() с текущим, заданным языком, который возвращает перевод. Причем, если в xml файле мы не находим нужный нам clause name, то мы его записываем в файл. Таким образом мы пишем, отлаживаем программу, а она сама записывает все стандартные(дефолтные) строки в файл. А потом только вставляем нужный перевод и локализация готова.
Код

<?xml version="1.0" encoding="UTF-8" ?> 
- <languages name="English;Русский;český;">
- <clause name="OK">
  <language name="Русский">OK</language> 
  <language name="český">OK</language> 
  </clause>
- <clause name="Cancel">
  <language name="Русский">Выход</language> 
  <language name="český">Storno</language> 
  </clause>
- <clause name="Can not load '%s' file">
  <language name="Русский">Не могу загзузить '%s' файл</language> 
  </clause>
- <clause name="Can't connect with server">
  <language name="Русский">Не могй соединиться с сервером</language> 
  </clause>
  </languages>



--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
mohax
Дата 31.8.2005, 07:44 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Способ с хмл понравился)) не подумал об этом, хотя в проекте активно используется эта технология...
У меня немного другой вопрос - нужно же перевести все строки на русском языке в коде... Например тут - "if StatusStr = 'не распознан' then ..." или "ShowMessage('Нет распознанных файлов!');" То есть надо как-то собрать все строки и заменить их в коде на переменные? Пример - "ShowMessage(TranslateStr1);" А значения переменных меняются в зависимости от выбранного языка... Самая проблема как это сделать без больших затрат времени и самым оптимальным способом
  Вверх
bel_nikita
Дата 31.8.2005, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: нет
Всего: 47



Ну тут либо ручками, либо написать програмку, которая будет парсить паскалевсткий файл. Вместо 'а-ля строка' ставить переменную, а эту 'а-ля строка' записывать в файл. Т.е. в файл будет выглядеть следующим образом:
Код
TranslateStr1 = 'а-ля строка'
TranslateStr2 = 'а-ля строка 2'
TranslateStr3 = 'а-ля строка 3'

А дальше, берешь этот файл и вставляешь в проект. В итоге, переменные готовы. Делаешь ребилд проекта, и добовляешь локализацию smile

З.Ы.: ИМХО. Сам так никога не пробывал, но думаю это один из возможных методов. Тем более написать парсер - никаких проблем, просто икриментируешь и записываешь в файл найденые строки.


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
offline
Дата 31.8.2005, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 474
Регистрация: 7.2.2005

Репутация: нет
Всего: 7



PM MAIL   Вверх
Delphins
Дата 31.8.2005, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 10.8.2005
Где: Россия, Краснодар

Репутация: нет
Всего: нет



kirillliusNo input file specified.
А еще можно взять какойнить эксперт для дельфи, например ModelMaker Code Explorer. И так в меню есть Wizard. Так он все такие строки собирает. А потом ты ими можеш пользоваться. Удобно! smile
PM MAIL ICQ Skype MSN   Вверх
offline
Дата 1.9.2005, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 474
Регистрация: 7.2.2005

Репутация: нет
Всего: 7



PM MAIL   Вверх
offline
Дата 1.9.2005, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 474
Регистрация: 7.2.2005

Репутация: нет
Всего: 7



Можно сделать следующее:
Заготовить ini фай с переводами следующей структуры

[язык]
имя компонента1 = перевод
имя компонента2 = перевод
имя компонента3 = перевод
…
сообщение1 = перевод
сообщение2 = перевод
…

Пример

[Russian]
forma = Мои фотографии
butAdd = Добавить
butEdit = Редактировать
message1 = Фотография уже существует!

[English]
forma = My photos
butAdd = Add
butEdit = Edit
message1 = Photos ...!

[Germany]
...

Затем

Код

uses
  Forms, …, IniFiles;

procedure TfrmMain.Language;
var
 ini Language : TIniFile; //переменная для работы с ини файлами
 lang, perevod : String; //переменная языка и перевода
 i : Integer;
begin
 //если нет ини файла
 if not FileExists(Path + '\Language.ini')
  then Exit;
 lang := выбранный язык; //например lang := ’Russian’;
 try
  iniLanguage:= TIniFile.Create(Path + '\Language.ini');
  if iniLanguage.ValueExists(lang, frmMain.Name) then begib
    perevod := iniLanguage.ReadString(lang, frmMain.Name,'')
    frmMain.Caption := perevod;
  end;
 //пробежаться по всем компонентам формы и поменять заголовок
 for i := 0 to frmMain.ControlCount - 1 do 
  if iniLanguage.ValueExists(lang, (frmMain.Controls[i]).Name) then begib
    perevod := iniLanguage.ReadString(lang, (frmMain.Controls[i]).Name,'')
   (frmMain.Controls[i]).Caption := perevod;
  end;
 finally
  iniLanguage.Free;
 end;
end;


Код может содержать ошибки, т.к. не проверен, но думаю, что смысл понятен. Будут переведены те компоненты имя которых содержится в ini файле.

Перевод сообщений выглядит также.
Нужно создать процедуру или функцию в которую отправляешь язык и номер сообщения, а она возвращает текст сообщения, который и подставляется в сообщение.




PM MAIL   Вверх
allx
Дата 2.9.2005, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 1.9.2005

Репутация: нет
Всего: нет



Для фриварных программ удобно делать так, чтобы сами юзеры могли быстро создавать свои переводы.
Я делаю так:

Код

unit ini_lang;

interface

uses
  SysUtils, Inifiles;

const
  ini_filename = 'lang.ini';

function ReadLocalizedValue(Name: string; Locale: integer): string;

type
  TLangInifile = class (Tinifile)
  end;

implementation

function ReadLocalizedValue(Name: string; Locale: integer): string;
var
 langinifile: TLangInifile;
 sPath: string[60];
const
  StandError = 'Error reading language file! Make sure that file "' + ini_filename + '" is in the application folder';
begin
  GetDir(0, sPath); 
  langinifile := TLangInifile.Create(spath+'\'+ini_filename);
  Result := langinifile.ReadString(inttostr(Locale), Name, StandError); 
  langinifile.Free;
end;

end.


Плюс в том что многократно повторяющиеся элементы в ini-файле переводить не надо - удобство для переводчиков.
Минус думаю всем ясен. Придется писать громоздкую процедуру считывания локализованных заголовков ...
(Label1.caption:=ReadLocalizedValue('File'); и так по каждому элементу)

INI-Файл выглядит так:
Код

[1049]  ;Русский
File            = Файл
Exit                 = Выход



Если сразу предположить наличие многоязыковости, то времени лишнего отнимает лишь малость.


PM MAIL   Вверх
offline
Дата 2.9.2005, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 474
Регистрация: 7.2.2005

Репутация: нет
Всего: 7



Цитата
Для фриварных программ удобно делать так, чтобы сами юзеры могли быстро создавать свои переводы.


ага, я посмотрю, как ты создашь перевод китайской программы ;)
PM MAIL   Вверх
allx
Дата 2.9.2005, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 1.9.2005

Репутация: нет
Всего: нет



kirilllius
Ни разу в жизни не пользовался китайской программой smile Ан нет, была, была - TeraTerm, однако и та была а инглише.

Вопрос к народу. Кто-нибудь пробовал выносить все строки в ресурсы, и можно ли селать MUI-файлы с дельфийскими ресурсами, чтобы все автоматом работало? Может есть какой-нить компонент который этим занимается?
PM MAIL   Вверх
offline
Дата 2.9.2005, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 474
Регистрация: 7.2.2005

Репутация: нет
Всего: 7



посиотри мои ответы выше, там я скидывал ссылки на компоненты.
PM MAIL   Вверх
allx
Дата 3.9.2005, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 1.9.2005

Репутация: нет
Всего: нет



kirilllius
Спасибо! Чет ссылки среди кода сразу я не заметил.
Интересная статейка про локализацию.

Это сообщение отредактировал(а) allx - 3.9.2005, 10:03
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0627 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.