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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: (ст)Обзор способов поддержки мультиязычности в приложениях  (Прочитано 12485 раз)
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
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
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 » new

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
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines