Мультиязычный интерфейс

Форум для программистов

Сообщение StayAtHome » Вс янв 18, 2004 5:02 pm

Хочу обсудить возможные способы создания программ с мультиязычным интерфейсом (МИ). Я изложу свое мнение, а вы -- свое.
Понятно, что МИ лучше всего реализовать через подключение внешних языковых файлов. И лучше их делать текстовыми. Тогда возникает вопрос -- каким образом лучше всего определить соответствие конкретного елемента
управления в окне программы и нужной строки в языковом файле. Вот возможные варианты, как они видятся мне.
1. Наиболее очевидный способ.
Каждому элементу присвоить уникальный (хотя бы в пределах окна) числовой код, а строки в языковом файле делать вида
Код: выделить все
<номер>=<строка>
Тогда можно рекурсивно пробежатся по всем элементам окна и, например, считывая их свойство Tag присваивать им нужные строки.
2. Немного измененный способ.
Можно привязываться прямо к именам создавая строки вида
Код: выделить все
<название элемента>.<название свойства>=<строка>
или
Код: выделить все
<название родительского элемента>_<название элемента>=<строка>

И опять рекурсивно пробегаться по элементам управления и их списку свойств.
3. Использовать XML? Как именно? Не знаю. А не пальба ли это из пушки по воробьям?

Каждый из способов имеет свои преимущества и недостатки.
Что делать, если у одного элемента управления несколько надписей?
(именно надписей а не вложеных элементов со своими написями, например TRadioGroup в Delphi).
При добавлении нового елемента в окно на этапе разработки, следует жестко контролировать, чтобы он получил уникальный код.
Как быть если текст надписи на элементе управления состоит из нескольких строк? Вставлять escape-последовательности типа \CRLF?
Существуют ли другие способы реализации МИ?

Хотелось бы получить не просто комментарии типа да/нет/хорошо/плохо а что-то более содержательное. :-) Или хотябы ссылку на тему.
PS. Прошу простить за, возможно, ламерские мысли.
Последний раз редактировалось StayAtHome Вс янв 18, 2004 5:03 pm, всего редактировалось 1 раз.
<span style='color:gray'>Жизнь -- это песня!</span>
<span style='font-family:Courier'>Life.exe /?</span>
StayAtHome
Подполковник
 
Сообщений: 710
Зарегистрирован: Вс фев 09, 2003 11:30 pm
Откуда: Украина
Пункты репутации: 0

Сообщение Миша Спларов » Вс янв 18, 2004 6:00 pm

2StayAtHome
<!--QuoteBegin--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td>Цитата </td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->Как быть если текст надписи на элементе управления состоит из нескольких строк? Вставлять escape-последовательности типа \CRLF?<!--QuoteEnd--></td></tr></table><div class='postcolor'><!--QuoteEEnd-->
Тут, например, можно ставить два пробела в lng файле, а потом в коде заменять два пробела на ту же новую строку.
<!--QuoteBegin--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td>Цитата </td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->При добавлении нового елемента в окно на этапе разработки, следует жестко контролировать, чтобы он получил уникальный код.<!--QuoteEnd--></td></tr></table><div class='postcolor'><!--QuoteEEnd-->
Например, меню "файл" код 01 подпункты будут иметь 01001, 10002, например. Отследить, я думаю не трудно, при том если сам файл языка будет как-бы постоянно загружен программой.

Ещё, например, могу предложить такой способ.
Код: выделить все
<language>
<menu>
 <item id="1" name="file" caption="%Файл">
  <subitem id="1" name="open" caption="%Открыть" />
  <subitem id="2" name="save" caption="%Сохранить" />
 </item>
 <item id="2" name="view" caption="%Вид">
  <subitem id="1" name="default" caption="%По умолчанию" />
 <item id="3" name="service" caption="%Службы">
  <subitem id="1" name="options" caption="Св%ойства" />
   <subsubitem id="1" name="basic" caption="Ос%новные" />
   <subsubitem id="2" name="advanced" caption="%Продвинутые" />
  <subitem id="2" name="selected" caption="%Выбранные" />
 <item id="4" name="help" caption="%Помощь">
</menu>
</language>

Плюс к "<menu>" ещё, например, настройки, там можно классифицировать по вкладкам, затем по label'ам.
Я бы использовал XML, последний вариант.
«Проектирование интерфейсов — увлекательный дизайнерский процесс. Схожее удовольствие можно получить от сложной верстки, от создания многомерных схем и решения других задач на логику и эстетику». (q) A. Лебедев
Миша Спларов
Генерал-лейтенант
 
Сообщений: 3022
Зарегистрирован: Пн апр 22, 2002 7:58 am
Откуда: Россия, Томск
Пункты репутации: 0

Сообщение SiMM » Вс янв 18, 2004 9:47 pm

<!--QuoteBegin-StayAtHome+Jan 18 2004, 21:02--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td>Цитата (StayAtHome @ Jan 18 2004, 21:02)</td></tr><tr><td id='QUOTE'><!--QuoteEBegin--> Как быть если текст надписи на элементе управления состоит из нескольких строк? Вставлять escape-последовательности типа \CRLF? <!--QuoteEnd--> </td></tr></table><div class='postcolor'> <!--QuoteEEnd-->
Как вариант - можно поступить иначе - дело в том, что PHP считает концом строки символ \xA (т.е. функции чтения из файла, типа file(), разделят файл на строки именно по этому символу), а символы \xD в пределах строк, разделённых \xA, никакого значения не имеют. Думаю, идея ясна Изображение
IRC: <a href='http://www.fileforum.ru/irc.php' target='_blank'>RUSNET #fileforum</a> (irc.tsk.ru:6669)
SiMM
Подполковник
 
Сообщений: 588
Зарегистрирован: Чт июн 13, 2002 8:41 am
Пункты репутации: 0

Сообщение MAPA3bM » Вт янв 20, 2004 2:19 am

<offtop>
А загляни-ка ты <a href='http://russian.joelonsoftware.com/Articles/BacktoBasics.html' target='_blank'>сюда</a>, прежде чем лезть в XML...
</offtop>
MAPA3bM
Полковник
 
Сообщений: 1270
Зарегистрирован: Вт дек 31, 2002 12:54 am
Откуда: Приморье
Пункты репутации: 0

Сообщение Флинт » Вт янв 20, 2004 4:39 pm

2StayAtHome
Расскажу свой вариант, а ты уж решай - подходит он тебе, или нет. Когда я решил сделать наконец свою прогу многоязычной, я перерыл довольно много инфы о разных способах написания таких программ. Единственное - про XML не встречал. А так можно разбить все способы на два типа: строковые и ресурсные. В первом соответственно пишется текстовый файл, во втором - компилится DLL, содержащая переведённые ресурсы. Сравню-ка я их...

Строковой
Плюсы:
* Простота редактирования и создания новых языковых файлов
Тут всё понятно
* Маленький размер языковых файлов
Для ресурсов надо делать DLL, а они побольше текстовиков...
Минусы:
* Большая вероятность некрасивого расположения надписей в диалогах
А это я испытал в полной мере, когда писал русификацию Total Commander'а... Ну не влезает надпись в отведённое место, и всё тут! И что делать? Сокращать до невразумительных "Копир./Удал."? Не-е-е, не хочу! Возможна и другая ситуация - когда наоборот, остаётся куча пустых промежутков, разбросанных по диалогу как попало...
* Необходимость самостоятельно загружать и парсить текстовик
А DLL подключить - раз плюнуть, две строчки кода добавить... См. ниже.

Ресурсный
Плюсы:
* Возможность варьировать не только надписи, но и размеры контролов, и даже менять их расположение
* Наличие редакторов ресурсов, т.е. удобное визуальное проектирование
Тот же Visual C++ - очень приятный редактор ресурсов, с предпросмотром и т.д.
* Простота подключения языков
Об этом ниже, модификация кода проще и нагляднее, чем в варианте со строками
Минусы:
* Низкая защищённость от ошибок
А если в диалоге пару контролов удалить???
* Затруднённость для написания новых языков сторонними разработчиками
Не все умеют ресурсы редактировать и компилить... Изображение
* Необходимость перекомпиляции DLL при каждом изменении

Я всё-таки остановился на втором варианте, очень уж мне досадил минус из строкового варианта и очень уж понравились плюсы из ресурсного... Единственное, что придётся сделать в ресурсном варианте - создать DLL-файл со всеми ресурсами, переведёнными на нужный язык и скомпилить DLL. Потом в программе (Я писал на C++/MFC, но наверняка есть и другие способы) загрузить эту DLL, поставить вызов AfxSetResourceHandle, и всё!!! Все ресурсы автоматически будут браться из подключённой DLL, в том числе и строки, и диалоги...
Последний раз редактировалось Флинт Вт янв 20, 2004 4:40 pm, всего редактировалось 1 раз.
Флинт
Майор
 
Сообщений: 368
Зарегистрирован: Пн ноя 25, 2002 9:26 am
Откуда: Москва
Пункты репутации: 0

Сообщение StayAtHome » Вт янв 20, 2004 10:19 pm

2Флинт
Спасибо за совет. подумаю над этим.
2 Все
Есть еще мнения?
<span style='color:gray'>Жизнь -- это песня!</span>
<span style='font-family:Courier'>Life.exe /?</span>
StayAtHome
Подполковник
 
Сообщений: 710
Зарегистрирован: Вс фев 09, 2003 11:30 pm
Откуда: Украина
Пункты репутации: 0

Сообщение VadiMGP » Ср янв 21, 2004 8:07 am

Если ты предполагаешь делать юникодную программу, то локализацию проще делать с ресурсами.

2Флинт Я что-то не понял, в чем низкая защищённость от ошибок у ресурса. Скорее, я сказал бы, что поскольку dll это загружаемый модуль, то, как и всякий код, он требует к себе более внимательного отношения, чем просто текстовый файл. Т.е. попросту, больше работы.
Человеческая жизнь похожа на коробку спичек. Обращаться с ней серьезно - смешно. Обращаться несерьезно - опасно.
А. Рюноскэ
VadiMGP
Подполковник
 
Сообщений: 887
Зарегистрирован: Сб апр 26, 2003 10:32 am
Пункты репутации: 0

Сообщение Флинт » Ср янв 21, 2004 2:33 pm

2VadiMGP
Я собственно имел в виду защищённость от ошибок программы. Ну например, ошибся ты, и сделал диалог с идентификатором 1546 вместо 1545. В программе вызывается показ этого диалога. Что произойдёт? Если у тебя на 1545 повешен другой диалог, то покажется он, а если нет - то грох программы (ну или в лучшем случае сообщение "Нет нужного ресурса" при правильной обработке ошибок). Другой вариант: в диалоге нет контрола. Опять грох или ошибка, т.к. прога при работе пытается вовсю его использовать.
Можно, конечно, в случае ошибки грузить ресурс из самого EXE-файла, т.е. непереведённый. Но во-первых, как ты отловишь отсутствие какого-то контрола на диалоге? Или кнопки в тулбаре? Тут не просто объём работы, тут намного сложнее...
Да, мне тут ещё один минус в голову пришёл - зависимость от версий. Текстовик можно подключать и к новой версии - ну будут пара слов не переведена, - и к старой. А с DLL могут быть большие проблемы, т.к. и тулбары могут меняться, и диалоги, и иконки/картинки...
Флинт
Майор
 
Сообщений: 368
Зарегистрирован: Пн ноя 25, 2002 9:26 am
Откуда: Москва
Пункты репутации: 0

Сообщение Aux » Вт фев 03, 2004 4:53 pm

Я делал так:
типа ini-файл componentname=value
в программе код
mainform.findcomponent(componentname).caption := value;
тока есть проблема - надо делать идентификацию типов, т.к. TComponent НЕ имеет поля caption:
if classnameis(mainform..., 'tbutton')then
(mainf... as tbutton).caption := ...
Aux
Рядовой
 
Сообщений: 8
Зарегистрирован: Вт фев 03, 2004 4:09 pm
Откуда: Рига
Пункты репутации: 0

Сообщение poiuytr » Пн фев 09, 2004 4:49 pm

Вот <a href='http://klirik.narod.ru/usefuls/tbplugins.htm' target='_blank'>здесь</a> в конце страницы чел предлагает свое решение для перевода. Там говорится о переводе плагинов к Да Бат!, но точно так же можно переводить любое другое приложение.
Hasta la victoria siempre!
poiuytr
Капитан
 
Сообщений: 233
Зарегистрирован: Ср авг 14, 2002 6:04 pm
Откуда: Рига, Латвия
Пункты репутации: 0


Вернуться в Программирование

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

cron