Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2008.11.02;
Скачать: [xml.tar.bz2];

Вниз

Мультиязыковая поддержка   Найти похожие ветки 

 
Still Swamp   (2008-01-31 13:07) [0]

Есть проект - около пяти сотен формочек.
Появилась забота перевести его на английский. Подозреваю что этим дело не ограничится.

До чего я додумался для визуальных объектов:
1. Сдлеать некую софтину которая обшуршивает DFM на предмет рускоязычнх сообщений и создает к ним файл. Сопоставляющий сигнатуру и содержимое.
2. Сделать форме метод которым она обшуршивает ресурс и все свои компоненты, подставляя вместо сигнатуры данные из файла.

Для кода.
1. Оббежать код собирая все что между скобками и содержит русский. Слить это в файл заменив текст коде вызовом возвращающим значение по сигнатуре.
2. Перекомпилить.

Прежде чем затеваться с таким деянием, хочу узнать, нет ли каких иных вариантов, или может кто то все вышеописанное уже реализовал?


 
clickmaker ©   (2008-01-31 13:16) [1]

Integrated Translation Manager попробуй для начала.
Он делает примерно то, что ты описал в 1.1 и создает ресурсные DLL


 
Dimaxx ©   (2008-01-31 13:18) [2]

Вариант1:

Занести у нуждающихся в локализации контролов в Caption константы типа LNG_LABEL1. При создании формы обшаривать все контролы с caption, содержащей "LNG_", тащить из ini-файла соответствующую константе строку и записывать ее на место константы.

Вариант 2:

Использовать имя компонента в качестве константы. И тащить по нему соответствующие строки.

А для сообщений сделать в ini-файле отдельную секцию и пользоваться константами, например, так:

[SystemMessages]
Warning=<нужный текст>

Далее читать из ini по идентификатору и выводить.

Такой способ наиболее прост для последующего перевода программы на другие языки. Не нужны спец. программы (кроме Блокнота) для изготовления файла для другого языка. Я вообще делал динамическую загрузку в меню всех встреченных файлов локализации и при щелчке на пункте меню с нужным языком он менялся мгновенно.


 
Still Swamp   (2008-01-31 13:38) [3]

Ну те в общем я не оригинален и более изящных методов нет?


 
Dimaxx ©   (2008-01-31 13:50) [4]

А куда изящнее?? У меня код локализации в OnCreate формы сидит и при добавлении контролов даже переписывать ничего не надо. Тока в ini-файл добавлять не забывай строки и все.


 
Anatoly Podgoretsky ©   (2008-01-31 14:32) [5]

clickmaker ©   (31.01.08 13:16) [1]
Могу поспорить, что никаких resourcestring и в помине нет.


 
Игорь Шевченко ©   (2008-01-31 19:01) [6]


> До чего я додумался для визуальных объектов:
> 1. Сдлеать некую софтину которая обшуршивает DFM на предмет
> рускоязычнх сообщений и создает к ним файл. Сопоставляющий
> сигнатуру и содержимое.
> 2. Сделать форме метод которым она обшуршивает ресурс и
> все свои компоненты, подставляя вместо сигнатуры данные
> из файла.


Собственно, сделана программка, которая смотрит русскоязычные значения свойств в dfm, заменяет их на английский текст, и генерирует код для метода Loaded формы, в котором свойствам присваиваются их русскоязычные найденные значения.


 
Still Swamp   (2008-01-31 23:09) [7]

Вообще при более плотном обдумывании мне наиболее красивой кажется идея использовать как тут было сказано Component.Property в качестве идентификатора по той простой причине что при этом русское значение в дизайнтайме остается.

Теперь два способа построения.
1. Обшуршивание DFM. Надо писать парсер какой то. Это реально но лениво. Второй недостаток - требуется какая то предварительная подготовка как то сам по себе процесс сборки файла.
2. Действительно написать некий проц в Create формы, который при старте формы создаст файл если его не было, а потом потом тут же из него грузит значения. Те после первого старта приложение автоматом создаст необходимое, останется только перевести. Тут я не совсем отчетливо представляю себе как можно оббежать в рантайме все компоненты, а ни дай бог, там чье то нестандартное изделие попадется с каким нить свойством MyHint.

Высказывайтесь за и против.

И еще вопрос попутно. Как получить список свойств объекта? А так же тип. Без этого второй вариант несколько не жизнеспособен.


 
Still Swamp   (2008-01-31 23:13) [8]

е мое.... а еще листы всякие которые вообще можно не найти...


 
Still Swamp   (2008-02-01 00:25) [9]

Вопрос как получить список свойств и как с ними работать - снимается. Разобрался.


 
@!!ex ©   (2008-02-01 10:34) [10]

пять сотен формочек... нихреново...


 
Anatoly Podgoretsky ©   (2008-02-01 11:03) [11]

> @!!ex  (01.02.2008 10:34:10)  [10]

Да какая разница сколько форм, это экстенсивная характеристика, важнее как сделан проект, позволяет он использовать ITE или нет. Если нет, то все эти выше описаные манипуляции.


 
Dimaxx ©   (2008-02-01 11:41) [12]


> Тут я не совсем отчетливо представляю себе как можно оббежать
> в рантайме все компоненты, а ни дай бог, там чье то нестандартное
> изделие попадется с каким нить свойством MyHint.

А кто мешает сделать примерно так?

var I: integer;
   C: TComponent;
   S: string;

begin
...
 C:=Components[I];
 // В этих строках перебираем все классы компонентов, которые нуждаются в локализации
 if (C.ClassName="TMenuItem") and ((C as TMenuItem).Caption<>"-") then (C as TMenuItem).Caption:="bla-bla";
 if C.ClassName="TRadioButton" then (C as TRadioButton).Caption:="bla-bla";
 if C.ClassName="TButton" then (C as TButton).Caption:="bla-bla";
 if C.ClassName="TCheckBox" then (C as TCheckBox).Caption:="bla-bla";
 if C.ClassName="TGroupBox" then (C as TGroupBox).Caption:="bla-bla";
 if C.ClassName="TLabel" then (C as TLabel).Caption:="bla-bla";
...
end;


Кто тебе мешает перебрать нестандартное? Например так: if C.ClassName="TShitHint" then (C as TShitHint).MyHint:="bla-bla"??

Ты же сам знаешь какие компоненты использовал...


 
Игорь Шевченко ©   (2008-02-01 11:55) [13]


> А кто мешает сделать примерно так?


Так не надо делать


 
Still Swamp   (2008-02-01 12:23) [14]

Что такое ITE?
Какие есть еще варианты борьбы с текстом в коде?


 
Игорь Шевченко ©   (2008-02-01 13:33) [15]


> Что такое ITE?


Intergated Translation Environment


 
Dimaxx ©   (2008-02-01 14:04) [16]


> Так не надо делать

Почему?


 
Игорь Шевченко ©   (2008-02-01 14:14) [17]

Dimaxx ©   (01.02.08 14:04) [16]


> Почему?



>  // В этих строках перебираем все классы компонентов, которые
> нуждаются в локализации


Вот поэтому. Потому что существует процедура SetStrProp


 
Still Swamp   (2008-02-01 14:16) [18]

Я...я... натюрлих. Перебрать все свойства и поглядеть их типы куда веселее чем описывать каждый компонент.


 
Still Swamp   (2008-02-01 14:22) [19]

Вообще - с компонентами красиво получается. Кода на сотню строк, и переводы готовы.
А вот что делать с кодом - ума не приложу.
Ну допустим, я возму все исходники. Перешерстю их на предмет MessageBox("русский");

Заменю на
// IDFG12387GG7877ACCC3742346 = "русский"
MessageBox(GetMLS(Lang, Resource, "IDFG12387GG7877ACCC3742346"));

И что..? на меня оно потом из кода будет глядеть с укоризной.
Какие есть еще варианты?


 
Игорь Шевченко ©   (2008-02-01 15:03) [20]


> Какие есть еще варианты?


1. Например вариант с заменой IDFG12387GG7877ACCC3742346 на более благозвучное имя.
2. Поискать в тырнете готовых локализаторов - их есть. Всяко дешевле, чем самому писать


 
Anatoly Podgoretsky ©   (2008-02-01 15:10) [21]

> Dimaxx  (01.02.2008 14:04:16)  [16]

Не надо.


 
Still Swamp   (2008-02-01 15:21) [22]

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

Идея нужна. Писанина - дело второе.
А вот идеи нет.


 
Dimaxx ©   (2008-02-01 15:32) [23]


> Потому что существует процедура SetStrProp

А для чего мне тянуть за собой тонну кода, которую тянет за собой SetStrProp, которая делает практически тоже?? Всего-то надо только заменить текст в соответствии с выбранным языком. Зачем менять св-во Caption у, допустим, Label1 через SetStrProp, когда можно простым присваиванием? Считал строки и присвоил...

Объясните толком, просто я давным-давно забросил VCL и работаю на КОЛ...


 
Sapersky   (2008-02-01 15:35) [24]

Есть такой вариант. Оформляем все сообщения в виде:
Type
 TMsgType = (mtOK, mtCancel, ...);
Var
 MsgNames : array [TMsgType] of String =
   ("OK", "Cancel", ...); // в данном случае англ. локализация "встроенная"

Сначала грузим в массив MsgNames строки на нужном языке. Для большей читабельности файла локализации лучше использовать реальные названия enum"ов (mtOK=OK и т.п.), можно попробовать получить их через TypeInfo, там есть такое:
             tkEnumeration: (
               BaseType: PPTypeInfo;
               NameList: ShortStringBase));
Как вариант, использовать в качестве имён параметров строки из встроенной английской локализации (rus: OK=Да).
Использование локализованных строк:
MessageBox(MsgNames[mtOK], ...)
Т.е. это некий баланс между автоматизацией (сообщения в массив грузятся в цикле) и красотой (mtOK понятнее чем IDFG12387GG7877ACCC3742346).

Зачем менять св-во Caption у, допустим, Label1 через SetStrProp, когда можно простым присваиванием?

См.:
Есть проект - около пяти сотен формочек.


 
kami   (2008-02-01 15:38) [25]

Still Swamp   (31.01.08 13:07)
Появилась забота перевести его на английский...
или может кто то все вышеописанное уже реализовал


http://www.dk-soft.org/products/dklang/


 
Игорь Шевченко ©   (2008-02-01 15:45) [26]

Dimaxx ©   (01.02.08 15:32) [23]


> Объясните толком, просто я давным-давно забросил VCL и работаю
> на КОЛ...


Автор вроде над большим проектом работает, ему, как ты сам понимаешь, тонну кода тянуть не надо, она уже втянута unit"ом classes.

Все SetxxxProp используются при чтении ресурсов формы, поэтому ничего лишнего вроде перебора классов использовать не стоит. Разве что пальцы потренировать.


 
Dimaxx ©   (2008-02-01 23:57) [27]


> Все SetxxxProp используются при чтении ресурсов формы, поэтому
> ничего лишнего вроде перебора классов использовать не стоит.
> Разве что пальцы потренировать.

Хм, а мона примерчик как юзать сабж? Например, Label1.Caption менять. А то походу я "жертва" Архангельского и его "стратегии"... :(


 
DVM ©   (2008-02-02 00:03) [28]

Вообще то локализация - это не тупой перевод Caption и остальных строк. Надо иметь в виду, что возможно придется кое-где и контролы сместить или в размерах изменить, т.к. надписи на другом языке могут банально не влезть.


 
ketmar ©   (2008-02-02 01:47) [29]

>[28] DVM©(02.02.08 00:03)
угу. и тут я опять рыдаю по поводу отсутсвия в Delphi нормального layout manager"а…


 
Still Swamp   (2008-02-02 11:33) [30]

На счет контролов и не влезет - ерунда.
Все формы надо изначально планировать под произвольные размеры.
1. Не делать ничего фиксированного размера.
2. Сохранять настройки пользователя.
Этого достаточно что бы избежать полностью проблем с влезет не влезет, и очень упрощает разработку, для меня самого. Не надо заниматься кройкой и шитьем.

Dimaxx
Я вот по этому разбирался.
http://megalib.com/books/923/CHMFirstPage.htm (Теория и практика использования RTTI)


 
Still Swamp   (2008-02-02 11:50) [31]

Короче концепция решения по большому счету.
Жду недостатки (только не пишите что громоздко большому кораблю большое плаванье).

1. Берем базу например FB
2. Далее делаем DLL в которую заворачиваем общение с FB а так же настройки конфига на каком языке работает клиент. DLL нужна для того что бы в проекте можно было общаться к одной базе через одно подключение.
3. Далее рисуется компонента, которая имеет возможность общаться с DLL. В компоненте приписывается путь до базы. Далее реализуются методы
- Создать дефаултный словарь из формы.
- Подменить все строки на форме родителе.
- Получить строку по идентификатору
- Сохранить строку по идентификатору.
- Делаем редактор базы для переводчиков.

Работа
Кидаем компоненту на форму.
При старте формы компонента сгружает все свои капшены в базу для языка DEFAULT, а так же удаляет все лишние записи о компонентах, которые были удалены с формы. Те фактически, следит за состоянием актуальных записей.
Переводчики начинают работу, переводчики переводят за ними.

В проекте информация о языке хранится в DLL, откуда ее выйживает каждый из компонентов проекта.

В базе требуется след идентификация
Идентификатор = ComponentName.Property
Группа - для того что бы можно было получить инфу по конкретной форме проекта. Вводится программистом в  компоненту. Должно быть уникально для каждой формы. Можно использовать CreateGUID.
Момент когда появилась новая запись, что бы переводчики могли получать инфу что когда обновилось.

Ну вот.

В редакторе базы необходимо реализовать создание идентификаторов по файлу PAS млм по маске из подкатолога.


 
ketmar ©   (2008-02-02 12:24) [32]

>[30] Still Swamp (02.02.08 11:33)
>Все формы надо изначально планировать под произвольные размеры.
гыгыгы. ты бы это Хэйлсбергу пояснил. я вообще слабо понимаю, каким местом он думал, дизайня VCL в плане визуала.

хотя нет, понимаю. он думал для Win 3.11. а потом вступило в игру страшное слово legacy.


 
ketmar ©   (2008-02-02 12:25) [33]

>[31] Still Swamp (02.02.08 11:50)
ты бы прежде чем велосипед делать, глянулд таки в сторону ITE, а?


 
Anatoly Podgoretsky ©   (2008-02-02 12:47) [34]

> Still Swamp  (02.02.2008 11:50:31)  [31]

Дальше переходим к пункту 4, который гласит - выкинуть первые три пункта и не мучаться, в Дельфи включен мощный инструмент ITE - работает, как и микрософтовские продукты MUI, через ресурсные ДЛЛ - просто, прозрачно и действительно полная локализация, а не только надписи на кнопках.

Пример есть в демос Дельфи.
Единственная проблема, возможно, это использование ТНТ, не уверен, что это работает с ним, но я не проверял.


 
Игорь Шевченко ©   (2008-02-02 12:53) [35]

Dimaxx ©   (01.02.08 23:57) [27]


> Хм, а мона примерчик как юзать сабж? Например, Label1.Caption
> менять. А то походу я "жертва" Архангельского и его "стратегии".
> .. :(


uses
 TypInfo;

...
 if IsPublishedProp(Label1,"Caption") then
   SetStrProp(Label1,"Caption", "Blah-blah");


 
DVM ©   (2008-02-02 13:12) [36]


> Still Swamp   (02.02.08 11:33) [30]


> Все формы надо изначально планировать под произвольные размеры.

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


 
ketmar ©   (2008-02-02 13:22) [37]

>[36] DVM©(02.02.08 13:12)
>думаю MS не заморачивалась с рисованием диалогов для каждого языка
>персонально.

ах, если бы это решало проблему… но фигвам. я уже писал о «фичах» ttf-растеризатора от m$.


 
Still Swamp   (2008-02-02 15:20) [38]

DVM
Я не буду гнуть пальцы естно, потому что постоянно натыкаюсь на то что не знаю, но.... можно пример где на форме что то нельзя сделать резиновым. Если можно, описание, я постараюсь представить EXE.


 
Dimaxx ©   (2008-02-03 00:17) [39]


> if IsPublishedProp(Label1,"Caption") then SetStrProp(Label1,"Caption", "Blah-blah");

Т.е. это надо (именно надо) использовать вместо уродливого (C as TLabel).Caption:="bla-bla"? Я так понимаю?


 
ketmar ©   (2008-02-03 00:44) [40]

>[38] Still Swamp (02.02.08 15:20)
кто сказал «нельзя»? можно. сделать свой layout manager — и вперёд. только геморроя там…



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

Форум: "Основная";
Текущий архив: 2008.11.02;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.006 c
2-1222075683
Nameziz
2008-09-22 13:28
2008.11.02
Обработка исключений


2-1222028467
programmer90
2008-09-22 00:21
2008.11.02
Проблема с маской


15-1221176987
Servy
2008-09-12 03:49
2008.11.02
Умножение через сложение


2-1222247658
Jiura
2008-09-24 13:14
2008.11.02
Как в Delphi скомпилировать Native DLL?


15-1220620461
Плохиш
2008-09-05 17:14
2008.11.02
Поздравляю всех с началом нового учебного года!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский