Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.76/34: Рейтинг темы: голосов - 34, средняя оценка - 4.76
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
1

Многоязычный интерфейс

19.06.2013, 17:26. Показов 6435. Ответов 45
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет!
Подскажите пожалуйста по сабжу.
1. Какие способы реализации бывают?
2. Какие достоинства, недостатки, подводные камни у той или иной реализации?
3. Может есть рекомендуемый способ?
4. Где можно почитать, желательно на русском и с примерами?
Искал в гугле, но ничего внятного не попалось...
Было несколько реализаций на delphi, vb.
Но я с ними не знаком.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.06.2013, 17:26
Ответы с готовыми решениями:

Многоязычный интерфейс
У меня такой вопрос:-Можно ли в программе написанной на С++ в меню добавить строку Language и...

Многоязычный интерфейс
Доброго времени суток. Подскажите пожалуйста каким образом делается многоязычный интерфейс, на...

Многоязычный интерфейс
Добрый день! Помогите реализовать многоязычность в программе.

Организовать в программе многоязычный интерфейс
Подскажите, пожалуйста, как правильно пишутся мультиязычные приложения? (Тоесть приложение может...

45
Brainsbreaker
899 / 374 / 54
Регистрация: 01.02.2011
Сообщений: 1,608
20.06.2013, 22:29 2
Цитата Сообщение от IPavel Посмотреть сообщение
Было несколько реализаций на delphi, vb.
Где можно с ними ознакомиться?
0
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
21.06.2013, 09:56  [ТС] 3
Цитата Сообщение от Digit@ll Посмотреть сообщение
Где можно с ними ознакомиться?
Ну собственно я в гугле находил...
Мне не подошли примеры, и естественно я ссылки не оставил...
Посмотрю позже в истории, если осталось скину.

P.S. Мужики ну подскажите по интернализации интерфейса!!!!!!

Добавлено через 4 часа 58 минут
Ещё на delphi.
http://www.delphiworld.narod.r... g_app.html

Добавлено через 2 минуты
Вот что нашёл в истории у себя...
Ещё было чего - то но уже не помню где.
0
Brainsbreaker
899 / 374 / 54
Регистрация: 01.02.2011
Сообщений: 1,608
21.06.2013, 21:05 4
Ну да, проще всего будет сделать через таблицу строк из ресурсов. Тебе нужна будет ф-ция LoadString, разбери ее и дальнейший алгоритм с ее использованием сам поймешь. IPavel, благодарю.
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
21.06.2013, 22:31 5
Цитата Сообщение от IPavel Посмотреть сообщение
1. Какие способы реализации бывают?
Разные. Официальный способ, рекомендованный Microsoft - писать свои версии
ресурсов (диалоги, строки, рисунки и т.п.) для каждой целевой локализации.
При таком подходе можно сохранить цельный вид приложения: строки не вылазят
за границы контролов, тексты выглядят естественно, ориентация компонентов
на экране тоже может меняться, например, в странах, где пишут справа-налево,
традиционно древовидное меню (как в проводнике) должно находиться в правой
части экрана, а не в левой, как мы привыкли видеть. Минусы подхода тоже есть.
Большое количество диалогов становится трудно сопровождать, легко получить
рассинхронизацию и трудноуловимые ошибки.

Большинство остальных способов - это или кустарщина, построенная на INI- или
XML-файлах с переводами, динамически подключаемыми приложением, или часть
какого-нибудь фреймворка (Qt, например).

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

У нас в программе использовалась примерно следующая схема.
Все тексты хранились в XML-файлах, где каждой строке был присвоен свой уникальный ID.
Например, UI-Common-LinkHelp соответствовал строке "Помощь" в русском XML, строке
"Help" в английском XML и строке "Hilfe" в немецком. UI - это имя подсистемы (User
Interface), Common - это название диалога, а LinkHelp - это название контрола в окне.
Во время запуска приложения нужный XML-файл обрабатывался специальным парсером,
который выдавал на выходе готовый класс а-ля std::map - на вход подается ID строки,
на выходе строка в нужном языке, в UTF-8 или UTF-16, по ситуации. Этот класс
использовался компонентами, работающими с текстами и пользовательским интерфейсом.

Поддерживать такую схему локализации оказалось довольно просто. Когда появлялись
новые тексты, мы задавали для новых строк новые ID, а потом просто вписывали их в
XML-файлы и отдавали это все переводчикам с краткими инструкциями или текстом на
оригинальном языке, который следует заменить.

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

По поводу что почитать. Попробуйте вот это:
Developing International Software (Microsoft Press).
http://www.amazon.com/Developi... 0735615837
Довольно неплохая книжка, объясняющая многие аспекты темы.

Еще рекомендую поискать по русскоязычным сайтам типа RSDN, там попадаются
толковые руководства на эту тему.
3
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
22.06.2013, 04:35  [ТС] 6
@Убежденный,
Спасибо большое!
Ну собственно у меня не шаре варе...
Пишу не большую игрушку, в стиле роглик...
Больше для набора опыта и практике...
Ну и хочется заложить в неё полный комплект фичь...
И опыт и вещь может получиться хорошая...

Если правильно понял по Вашей реализации то написанный клас был похож на мап только не совсем понял что писалось в него...
Обычно в мапе несколько строк в переменной, в одну пишем текст, а в другую что?
В принципе метод кажется перспективным...
Только бы вот хоть где-нибудь найти бы пример на c++.
А то как я уже писал выше видел только под delphi, vb.

Добавлено через 8 минут
Цитата Сообщение от Digit@ll Посмотреть сообщение
Ну да, проще всего будет сделать через таблицу строк из ресурсов. Тебе нужна будет ф-ция LoadString, разбери ее и дальнейший алгоритм с ее использованием сам поймешь. IPavel, благодарю.
Спасибо!
Да натыкался на неё ...
Только вот мне не понятно всёравно как сделать локализацию с ресурсами...
Если писать как рекомендует мелкософт для каждого языка свой ресурс...
То мне не понятно как перегружать ресурсы ...
Т.е. в для одного исполняемого файла будет несколько ресурсов...,
И как их выберать будет программа....

P.S. не по теме.
Если нужны ссылки которые здесь не прокатили могу в личку попробывать бросить, пока ещё в истории есть.
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
22.06.2013, 17:06 7
Цитата Сообщение от IPavel Посмотреть сообщение
Если правильно понял по Вашей реализации то написанный клас был похож на мап только не совсем понял что писалось в него...
Обычно в мапе несколько строк в переменной, в одну пишем текст, а в другую что?
В принципе метод кажется перспективным...
Только бы вот хоть где-нибудь найти бы пример на c++.
Предположим, что нужно перевести программу на два языка - русский и английский.
Для этого все строки в тексте программы, в диалогах, в ресурсах и т.п., заменяются
соответствующими идентификаторами, нейтральными по отношению к языку.
Например, текст кнопки "Закрыть" меняется на "UI-DlgName-BtnClose".
Дальше определяются два std::map - один для английского языка, второй для русского.
В первом map-е ключ "UI-DlgName-BtnClose" отображается на строку "Close", во
втором - на строку "Закрыть". При запуске программа определяет текущий язык,
заданный в настройках, и создает нужный map. После чего все тексты переводятся с
использованием этого map-а. И программа показывает тексты на нужном языке.

Здесь не затронуты многие аспекты локализации.
Например, что делать, когда текст не влезает в элемент управления или выглядит в
нем как-то "не так". Или когда нужно локализовать изображения, или отображать
дату/время в соответствии с региональными настройками.

Все это требует отдельных и продуманных подходов, я еще не встречал обобщенного
решения, которое годилось бы на все случаи жизни.
1
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
22.06.2013, 18:45  [ТС] 8
@Убежденный, спасибо за объяснение!
Рисованные битмапы с текстом есть, поэтому придётся наверно реализовывать через ресурсы...
Хотя я так и не в теме как работать с несколькими ресурсами в одной программе...
Жалко что книженция которую вы посоветовали на буржуйском...
Хоть и читаю на английском... Но мой инглишь пока ещё далеко не идеален...
Не знаете, нет ли перевода?
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
22.06.2013, 18:52 9
Цитата Сообщение от IPavel Посмотреть сообщение
Хотя я так и не в теме как работать с несколькими ресурсами в одной программе...
Ресурсы можно группировать по языковому признаку.
Например, можно иметь два диалога с одним ID, но под разными языками.
А можно сделать для каждого языка свою dll с ресурсами. Варианты разные.
Для загрузки ресурсов на нужном языке можно использовать FindResourceEx.
1
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
23.06.2013, 19:28  [ТС] 10
Мужики помогите советами!
Разобрался с таблицами строк в ресурсах, создание dll содержащих одни ресурсы.
Теперь не могу допереть как лучше грузить строки из ресурсов ...
Загружать каждую строку при запуске программы в отдельный буфер на мой взгляд панацея...
Если у меня например будет пару тысяч строк - это же целый файл придётся использовать для загрузки, и строк в этом файле будет столько же сколько строк в таблице,
причём одних и тех же с различием только падаваемого буфера и и идентификатора строки...
Да и при каждом новом слове придётся добавлять код в этот файл для загрузки строки...
Хотелось бы как нибудь это всё автоматизировать.....
А если грузить в массив строкнапример так
char str[255][255]
И потом по индексу грузить строки...
То не понятно вобще будет какая строка под каким индексом находится...
Я имею в виду str[100] - надо будет лезть в таблицу строк и смотреть что написано в 100 строке...
В общем подскажите пожалуйста как бы автоматизировать процесс загрузки и при этом чтобы можно было из названия буфера понять что должно выводится???
Например хорошо было бы как нибудь так bufClose, bufOpen, bufStop и т.д....
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
23.06.2013, 20:53 11
Попробуйте что-нибудь типа EnumResourceNames/EnumResourceLanguages.
Так можно сразу найти все ресурсы одного типа и загрузить их куда нужно.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
23.06.2013, 21:04 12
Цитата Сообщение от Убежденный Посмотреть сообщение
Большое количество диалогов становится трудно сопровождать, легко получить
рассинхронизацию и трудноуловимые ошибки.
Можно подумать, количество диалогов зависит от способа перевода, а не равно произведению их количества в оригинале на количество языков.
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
23.06.2013, 21:13 13
Цитата Сообщение от taras atavin Посмотреть сообщение
Можно подумать, количество диалогов зависит от способа перевода, а не равно произведению их количества в оригинале на количество языков.
Конечно зависит. 10 language-neutral диалогов плюс 5 языковых файлов - это совсем не то,
что 50 диалогов, по 10 на каждый язык.
0
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
24.06.2013, 09:33  [ТС] 14
Подскажите плз, как получить текущий язык системы?...
Нашёл GetLocaleInfoEx, но не пойму где можно посмотреть коды языков...
Т.е. можно в ф-ции указать флаг LOCALE_RETURN_NUMBER
И она должна вернуть целое, код языка.
А где вот посмотреть эти коды???
Мне нужно для русского и английского.
Вот пример, получения языка.
C++
1
2
3
4
5
6
7
int   ret;
DWORD value;
 
ret = GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
                      LOCALE_RETURN_NUMBER,
                      (LPWSTR)&value,
                      sizeof(value) / sizeof(WCHAR) );
Если конечно я всё правильно понял...
http://msdn.microsoft.com/en-u... 85%29.aspx

Добавлено через 18 минут
Цитата Сообщение от Убежденный Посмотреть сообщение
Попробуйте что-нибудь типа EnumResourceNames/EnumResourceLanguages.
Так можно сразу найти все ресурсы одного типа и загрузить их куда нужно.
Спс! Посмотрел.
Но немного не то что бы мне хотелось...
Я наверно просто неудачно обьяснил в посте выше...
Проблем с загрузкой из ресурсов нет, а есть проблема с именами переменных в которые должна записываться строка.
Т.е. хотелось бы грузить в переменные с понятным названием в цикле...
Например...
for (int i = IDS_1; i <= IDS_1000; i++)
{
здесь грузим в переменую
}
И чтобы переменные подставлялись в цикл по очереди, и сами переменные имели вид типа - bClose, bOpen и т.д.
Я подумал и походу так не сделаешь...
Можно грузить в цикле например в массив строк типа buf[255][255],
Подставляя в первый индекс i , но тогда из названия buf[100], не будет понятно что там за строка и прийдётся лезть в таблицу строк чтобы посмотреть что за строка.
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
24.06.2013, 10:20 15
Цитата Сообщение от IPavel Посмотреть сообщение
Подскажите плз, как получить текущий язык системы?
Я делал с помощью GetSystemPreferredUILanguages, это для Windows Vista и выше.
Для систем до Windows Vista отдельный workaround через GetSystemDefaultUILanguage.

Все-таки язык и локаль - не одно и то же.

Цитата Сообщение от IPavel Посмотреть сообщение
Нашёл GetLocaleInfoEx, но не пойму где можно посмотреть коды языков
Например, здесь:
Language Identifier Constants and Strings

Цитата Сообщение от IPavel Посмотреть сообщение
Проблем с загрузкой из ресурсов нет, а есть проблема с именами переменных в которые должна записываться строка.
Т.е. хотелось бы грузить в переменные с понятным названием в цикле...
Например...
for (int i = IDS_1; i <= IDS_1000; i++)
{
здесь грузим в переменую
}
А зачем нужны эти страшные циклы и буферы статического размера ?
Не проще ли сделать как-то так:
C++
1
std::wstring const SomeText = Localizer.Text(IDS_SOME_TEXT);
?

То есть, каждой строке в ресурсах сопоставить свой понятный ID, не просто номер.
И загружать их "лениво", только по мере необходимости, а не все сразу и в цикле.
1
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
24.06.2013, 11:30  [ТС] 16
Цитата Сообщение от Убежденный Посмотреть сообщение
Я делал с помощью GetSystemPreferredUILanguages, это для Windows Vista и выше.
Для систем до Windows Vista отдельный workaround через GetSystemDefaultUILanguage.

Например, здесь:
Language Identifier Constants and Strings
Спасибо!
Как раз читал о них...
Вот только один вопрос...
Почему Вы использовали GetSystemPreferredUILanguages,
а не например GetUserDefaultUILanguage?
На сколько я понял Ваша ф-ция получает предпачтительный язык системы...
Почему не язык интерфейса для текущего пользователя? язык системы может же отличатся от языка который использует текущий пользователь...


Цитата Сообщение от Убежденный Посмотреть сообщение
А зачем нужны эти страшные циклы и буферы статического размера ?
Не проще ли сделать как-то так:
C++
1
std::wstring const SomeText = Localizer.Text(IDS_SOME_TEXT);
?

То есть, каждой строке в ресурсах сопоставить свой понятный ID, не просто номер.
И загружать их "лениво", только по мере необходимости, а не все сразу и в цикле.
Это от привычки наверно...
В жизни стараюсь сразу всё необходимое сделать на данный момент и потом расслабиться...
Вот видно и в программирование отражается... Загрузил всё сразу, и гуляй смело...

Можно и так конечно...
Просто лень загружать каждый раз, вот и хотел облегчить себе жизнь - подставил нужный буфер и готово ...
Но по ходу облегчить таким способом не удастся...
И проще будет так как Вы предложили...
Хотя вот думаю не возникнет ли проблем с айпишными функциями из за wstring...
Мелкософт не очень любит стандартные методы c++... Иногда прям в наглую выдаёт ошибку при компиляции и коммент типа - "используйте вот эту ф-цию вместо вашей."
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
24.06.2013, 13:56 17
Цитата Сообщение от IPavel Посмотреть сообщение
Почему Вы использовали GetSystemPreferredUILanguages,
а не например GetUserDefaultUILanguage?
Нужно было получить язык системы. Именно системы, не пользователя.
GetSystemDefaultUILanguage возвращает "install language", это не совсем то,
что нужно. Ну а язык пользователя лучше получать через GetUserDefaultUILanguage.
Вот здесь есть кое-что полезное по теме: User Interface Language Management

Цитата Сообщение от IPavel Посмотреть сообщение
Просто лень загружать каждый раз, вот и хотел облегчить себе жизнь - подставил нужный буфер и готово ...
Но по ходу облегчить таким способом не удастся...
И проще будет так как Вы предложили...
Еще вариант - вообще отказаться от хранения строк в стандартных ресурсах.
На STRINGTABLE и LoadString мир ведь не заканчивается. Можно использовать двоичный тип
ресурса, в котором хранить строки в каком-то своем, внутреннем формате. И, например,
реализовать иерархический доступ к строкам. Или доступ по тэгам. Или прикрутить к этому
делу препроцессор, который будет обрабатывать входные файлы и автоматически составлять
список текстов для перевода на каждой сборке, выдавая ошибку, если для какой-то строки
не хватает перевода.

Цитата Сообщение от IPavel Посмотреть сообщение
Хотя вот думаю не возникнет ли проблем с айпишными функциями из за wstring...
Мелкософт не очень любит стандартные методы c++... Иногда прям в наглую выдаёт ошибку при компиляции и коммент типа - "используйте вот эту ф-цию вместо вашей."
Конфликтов между Windows SDK и стандартной библиотекой C++ быть не должно, иначе писать
софт на Visual C++ было бы значительно труднее. Ну а предупреждения действительно бывают в
отношении каких-то стандартных функций, например sprintf, хотя если задуматься, многие из
этих функций действительно небезопасны и в предупреждениях есть здравый смысл, как и в том,
чтобы пользоваться более надежными аналогами. Хотя это и не по стандарту.
1
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
24.06.2013, 17:23  [ТС] 18
Цитата Сообщение от Убежденный Посмотреть сообщение

Еще вариант - вообще отказаться от хранения строк в стандартных ресурсах.
На STRINGTABLE и LoadString мир ведь не заканчивается. Можно использовать двоичный тип
ресурса, в котором хранить строки в каком-то своем, внутреннем формате. И, например,
реализовать иерархический доступ к строкам. Или доступ по тэгам. Или прикрутить к этому
делу препроцессор, который будет обрабатывать входные файлы и автоматически составлять
список текстов для перевода на каждой сборке, выдавая ошибку, если для какой-то строки
не хватает перевода.
Да, реализации конечно должны быть интересные такими методами...
Но для меня бинарники вобще тьма...
Я вот как-то не понял с разу как с ними работать так и до сих пор их обхожу...
Я имею в виду не открыть/закрыть и т.д.
А именно работу со строками в бинарники...
В какой-то книженции или howto разбирали как скидывать в бинарник целый класс со всеми текущими данными...
А потом загрузку из бенарника этого всего обратно в класс...
Так вот я так и не понял этого всего...
Сначала как-то нужно было пропарсить бинарник чтобы разобрать структуру строк, потом вытаскивать по строке...
В общем я не понимаю в каком виде там лежат строки...
Визуально не представляю...
Парсить обычный текст вроде знаешь хоть как примерно может выглядеть документ/файл а вот в двоичном виде...
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
24.06.2013, 17:52 19
Цитата Сообщение от IPavel Посмотреть сообщение
В какой-то книженции или howto разбирали как скидывать в бинарник целый класс со всеми текущими данными...
А потом загрузку из бенарника этого всего обратно в класс...
Это называется сериализация.
Самому такое лучше не делать, а воспользоваться библиотеками.
Например, boost::serialization.

Цитата Сообщение от IPavel Посмотреть сообщение
Сначала как-то нужно было пропарсить бинарник чтобы разобрать структуру строк, потом вытаскивать по строке...
В общем я не понимаю в каком виде там лежат строки...
Визуально не представляю...
А представлять в большинстве случаев и не нужно.
Просто берете какой-нибудь формат описания данных, например XML, JSON, INI и т.п., и
перекладываете всю работу на библиотеки, реализующе парсинг и работу с этим форматом.
Нужно будет лишь обеспечить загрузку ресурсов и подачу их на вход парсера.
0
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
24.06.2013, 18:18  [ТС] 20
Цитата Сообщение от Убежденный Посмотреть сообщение
Это называется сериализация.
Самому такое лучше не делать, а воспользоваться библиотеками.
Например, boost::serialization.



А представлять в большинстве случаев и не нужно.
Просто берете какой-нибудь формат описания данных, например XML, JSON, INI и т.п., и
перекладываете всю работу на библиотеки, реализующе парсинг и работу с этим форматом.
Нужно будет лишь обеспечить загрузку ресурсов и подачу их на вход парсера.
Ну вот видите... знания - это сила!
У меня нет пока ещё такого богатого опыта и соответственно я не так легко ореентируюсь в теме...
Да и как начинающему мне интересно сама реализация нежели просто получение результата из парсера...
В общем хотелось бы знать как оно работает там внутри...
А для "рабочего" программирования т.е. если рассматривать программирования с точки зрения получения средств к существованию, а не как средства самосовершенствования, то да, тогда лучше использовать проверенные методы.
0
24.06.2013, 18:18
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.06.2013, 18:18
Помогаю со студенческими работами здесь

Многоязычный интерфейс для MS ACCESS
Есть ли идеи или где почитать как лучше сделать формы поддреживающие 2 или 3 языка на MS Access ...

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

Python + PyQt Многоязычный интерфейс программы
Привет Уважаемые форумчане ! Назрела необходимость добавить в программу возможность переключения...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru