Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Приглашаем принять участие в работе над нашей Wiki.
  • Наша рассылка: subscribe.ru, content.mail.ru и Google groups.
  • Есть желающие вести новостную ленту "В мире технологий"?
  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
   Начало   Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: (ст)Обзор способов поддержки мультиязычности в приложениях  (Прочитано 6794 раз)
0 Пользователей и 1 Гость смотрят эту тему.
USBLexus
Опытный

ru
Offline Offline
Пол: Мужской
Кот рыжий


« : 18-03-2005 05:21 » 

Всем привет, как можно сделать без особых трудозатрат многоязыковую поддержку в приложении У кого какие мнения на этот счет?
« Последнее редактирование: 01-05-2007 08:11 от Алексей1153++ » Записан

#define QUESTION(b) (2*b)||(!(2*b)) (c) William Shakespeare
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #1 : 18-03-2005 05:33 » 

В принципе все просто.
1. Надо ВСЕ текстовые константы (меню, заголовки, сообщения, рабоие данные) вынести в отдельный файл.
Даже формирующийся динамически контент надо выносить по частям, скажем фраза, у вас в базе ... того то и ... того то. Выносить в три части постоянных текстов.
Потом при старте программы подгружать нужный файл.
После этого достаточно сменить контекстный файл и все поменяется на другой зяык. При переводе надо учитывать ширину окон и длину фразы для единообразия.

Записан

А птичку нашу прошу не обижать!!!
USBLexus
Опытный

ru
Offline Offline
Пол: Мужской
Кот рыжий


« Ответ #2 : 18-03-2005 05:38 » 

В принципе все просто.
1. Надо ВСЕ текстовые константы (меню, заголовки, сообщения, рабоие данные) вынести в отдельный файл.
Даже формирующийся динамически контент надо выносить по частям, скажем фраза, у вас в базе ... того то и ... того то. Выносить в три части постоянных текстов.
Потом при старте программы подгружать нужный файл.
После этого достаточно сменить контекстный файл и все поменяется на другой зяык. При переводе надо учитывать ширину окон и длину фразы для единообразия.
Я вынес в StringTable все фразы теперь вот думаю как бы сделать 2 стрингтабла и их переключать перед компиляцией, Есть еще идея сделать стрингтабл

русский текст
английский текст
русский текст
английский текст
русский текст
английский текст

и обращаться к нему как STR_INDEX+LANG LANG=0 - русский, 1 - английский

Хотелось бы почитать про остальные способы, может есть получше
Записан

#define QUESTION(b) (2*b)||(!(2*b)) (c) William Shakespeare
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #3 : 18-03-2005 05:58 » 

а как???
Записан

А птичку нашу прошу не обижать!!!
USBLexus
Опытный

ru
Offline Offline
Пол: Мужской
Кот рыжий


« Ответ #4 : 18-03-2005 06:51 » 

а как???

Примерно  так

Стрингтабл
ID_BASE      Английский текст
ID_BASE+1  Русский текст
...

LoadString(...ID_BASE+LANG)

где LANG - #define LANG     1///Русский
      или     #define LANG     0//Английский
Записан

#define QUESTION(b) (2*b)||(!(2*b)) (c) William Shakespeare
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #5 : 18-03-2005 07:00 » 

не Отлично -  твою идею я понял, но она мне не нравится.
А как относилось к твоему вопросу как это еще сделать...

В варианте с стринг таблицей я не делал бы чередование.
Ведь тогда при добавлении третьего и четвертого и т.д. языков придется переделывать всю таблицу.
Идея использовать индекс в таблице верная, как и разные файлы.
Файлы удобнее тем, что их можно менять не пересобирая программу внешне, что даст возможность спокойно распротранить программу с одним языком и добавлять переводы без апдейтов.
Вариант с пересобиранием тоже впоне приемлим если варианты перевода желательно оставлять авторскими без изменений ловкими и умными пользователями.
Я бы сделал так.
Скажем есть колличество нужных фраз для программы.
#define TEXT_COUNT 1100

Далее заводим таблицу с текстами такого вида

индекс 0 -начало английского интерфейса
индекс TEXT_COUNT-1 конец английского интерфейса
индекс TEXT_COUNTначало русского интерфейса
индекс TEXT_COUNT*2-1 конец русского интерфейса

и т.д.

Тогда можно завести маленькие дополнения.
#define LANG_COUNT 10 // колличество языков
int base_lang_index[LANG_COUNT ]; // базовый стартовый индекс для языка где LANG_COUNT будет номер языка

Вот тебе формула для расчета base_lang_index.
base_lang_index[count_num] =  count_num*TEXT_COUNT;

В данном варианте в любой из новых языков добавляется легкой пририсовкой всех текстов вниз таблици и изменением LANG_COUNT +1.
Записан

А птичку нашу прошу не обижать!!!
USBLexus
Опытный

ru
Offline Offline
Пол: Мужской
Кот рыжий


« Ответ #6 : 18-03-2005 07:14 » 

>варианты перевода желательно оставлять авторскими без изменений ловкими и умными пользователями
Вот вот именно это мне и нужно

Да твой вариант с TEXT_COUNT всяко лучше моего удивительно как я сам не догадался, ведь все так казалось бы так просто. Лучше уже наврядли чтолибо можно придумать
Записан

#define QUESTION(b) (2*b)||(!(2*b)) (c) William Shakespeare
Serega
Гость
« Ответ #7 : 18-03-2005 07:37 » 

В принципе все просто.
Надо ВСЕ текстовые константы (меню, заголовки, сообщения, рабоие данные) вынести в отдельный файл.
Даже формирующийся динамически контент надо выносить по частям, скажем фраза, у вас в базе ... того то и ... того то. Выносить в три части постоянных текстов.
Потом при старте программы подгружать нужный файл.
После этого достаточно сменить контекстный файл и все поменяется на другой зяык. При переводе надо учитывать ширину окон и длину фразы для единообразия.
На самом деле просто все только в принципе.
Отделить ресурсы от кода надо обязательно, но вот как это сделать вопрос не тривиальный
В разных языках фразы могут строиться совершенно по разному, поэтому просто собирать фразу по кусочкам не стоит, это жестко привязывает код к языковым конструкцям одного языка, а задача полностью отделить код от локализованных ресурсов
Как вариант можно использовать строки с плэйсхолдерами, подходит если результаты работы программы представлены в виде перечисления, например: найдено N строк, у такого-то обьекта такие-то параметры и т.п.
Как лучше сделать окошки тоже однозначного ответа нет,  например при простом перечислении пунктов (меню, панель свойств и т.п.) удачнее выносить в ресурсы только надписи, а если же внешний вид окна как-то привязан к лексике то так уже не получится
Записан
xelos
Гость
« Ответ #8 : 18-03-2005 07:51 » 

я в многоязычном приложении создавал отдельные файлы для каждого языка. Таким образом, когда надо сменить язык - подгружаем нужный файл:
Код:
if (Language==0)//french
{
str=curDir+"\\Driver\\french.dll";
}
if (Language==1)//english
{
str=curDir+"\\Driver\\english.dll";
}
if (hi!=NULL)
FreeLibrary(hi);

hi=LoadLibrary(str);

В программе в каждом классе окна ставил функцию, которая считывала текст из файла для каждого контрола в случае смены языка:
Код:
str.LoadString(hi,1006);
m_ButInst.SetWindowText(_T(str));

плюсом является то, что динамически можно менять язык и при добавлении нового языка необходимо добавить всего один файл... Соответственно есть один класс, который отслеживает какие языки установлены и автоматически предлагает выбрать любой из установленных языков.
« Последнее редактирование: 18-03-2005 07:54 от xelos » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 18-03-2005 18:44 » 

Хочу обратить внимание на ф-ию gettext, входящую в glibc. Точнее на механизм, который там применен.
Строки в программе пишутся как обычно - char *str="....". Перед применением строки она пропускается через ф-ию gettext(), которая возвращает ее перевод из заранее созданного файла соответвия строк исходного и целевого языков. При первом вызове gettext() автоматом загружается файл перевода под текущий язык и кодировку.

Главное достоинство: для создания и изменения файлов переводов не нужно перекомпилировать программу. Т.е. переводом может занимать сторонний от создания программы человек.
Главный недостаток: как это реализовать в винде...

Примерчик:
Код:
#include <libintl.h>
.....
char *msg_ok="OK";
char *str;

str=gettext(msg_ok); // если перевода для этой строки не найдено, то вернется указатель на исходную строку.
puts(str);
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Переводы технических терминов.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #10 : 19-03-2005 00:29 » 

PSD, классная тема!!! Если у тебя MFC, то могу предложить такой вариант (имеет правда один крупный недостаток)
Если проект готов, то берёшь .rc файл (необходимое условие - все техты должны быть в нём - никаких текстов в коде). делаешь с него копии (по одной на язык) и преводишь их. Можно просто отдать переводчику столбик со словами встречающимеся в файле (эллементарный парсер). Он возвращает тебе два столбика с ключом (оригинальный текст напр. англиский) и переводом. Делаешь "найти и заменить" в .rc файле.
Создаёшь проект - DLL пустую. Вставляешь в неё полученный (переведённый) файл и компилируешь. Получаешь
ресурсную DLL с другим языком. Например назовём её ger.dll
Потом в InitInstance где-нить в начале делаешь что-то вроде такого (зависит от условий и фантазии напр. известен язык или надо из реестра взять и тд и тп):

HINSTANCE hRes = NULL;
      hRes = LoadLibrary(_T("ger.dll"));
      if(hRes)
      {
         AfxSetResourceHandle(hRes);
      }

Способ очень быстрый. Но!!! если проект находится в стадии разработки, то приходится каждый раз "подгонять" rc файлы. Очень уж это гемморойно, когда ресурсы меняются по нескольку раз в день. Но для релиза вполне годится.

Ну и, чтоб новую тему не открывать, у меня тоже есть вопрос. Точнее проблема. Вчера выяснили, что прогу надо и на русском делать. Ну я прегнал немецкую винду в русскую (чтоб она значит без юникода русский понимала) всё в порядке. Но когда в студии (.NET 2003) пытаюсь написать что-нить на русском она это либо в худшем случае перегоняет в вопросики, либо (если в ручную отредактировать rc файл в текстовом редакторе) пишет загогулинки - отличные друг от друга, но мало напоминающие кириллицу. Существует какая нить теория как народ в студии русские ресурсы загоняет? В идеале конечно на не русскоязычной платформе (есть у меня подозрение, что под чисто русской виндой это прокатит).
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.

"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
USBLexus
Опытный

ru
Offline Offline
Пол: Мужской
Кот рыжий


« Ответ #11 : 21-03-2005 03:20 » 

Ну и, чтоб новую тему не открывать, у меня тоже есть вопрос. Точнее проблема. Вчера выяснили, что прогу надо и на русском делать. Ну я прегнал немецкую винду в русскую (чтоб она значит без юникода русский понимала) всё в порядке. Но когда в студии (.NET 2003) пытаюсь написать что-нить на русском она это либо в худшем случае перегоняет в вопросики, либо (если в ручную отредактировать rc файл в текстовом редакторе) пишет загогулинки - отличные друг от друга, но мало напоминающие кириллицу. Существует какая нить теория как народ в студии русские ресурсы загоняет? В идеале конечно на не русскоязычной платформе (есть у меня подозрение, что под чисто русской виндой это прокатит).
У меня была такая проблемма я ее решил так:
/////////////////////////////////////////////////////////////////////////////
// Russian resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
#ifdef _WIN32
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
#pragma code_page(1251)
#endif //_WIN32

русские ресурсы...

#endif    // Russian resources
Записан

#define QUESTION(b) (2*b)||(!(2*b)) (c) William Shakespeare
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #12 : 21-03-2005 09:28 » 

USBLexus, во-первых сорри. Я сослепу решил, что тема от PSD. Как-раз наверно ему отвечал.

Я так пробовал, те я сделал копии в редакторе ресурсов, и преопределил язык. Но что интересно, он их не берёт, хотя locale вроде на русский настроена. Ещё забыл сказать - проект юникодовский.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.

"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.16 | SMF © 2011, Simple Machines