9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
|
|
1 | |
Многоязычный интерфейс19.06.2013, 17:26. Показов 6435. Ответов 45
Метки нет (Все метки)
Всем привет!
Подскажите пожалуйста по сабжу. 1. Какие способы реализации бывают? 2. Какие достоинства, недостатки, подводные камни у той или иной реализации? 3. Может есть рекомендуемый способ? 4. Где можно почитать, желательно на русском и с примерами? Искал в гугле, но ничего внятного не попалось... Было несколько реализаций на delphi, vb. Но я с ними не знаком.
0
|
19.06.2013, 17:26 | |
Ответы с готовыми решениями:
45
Многоязычный интерфейс Многоязычный интерфейс Многоязычный интерфейс Организовать в программе многоязычный интерфейс |
Brainsbreaker
899 / 374 / 54
Регистрация: 01.02.2011
Сообщений: 1,608
|
|
20.06.2013, 22:29 | 2 |
0
|
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
|
|
21.06.2013, 09:56 [ТС] | 3 |
Ну собственно я в гугле находил...
Мне не подошли примеры, и естественно я ссылки не оставил... Посмотрю позже в истории, если осталось скину. 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
|
Ушел с форума
|
|
21.06.2013, 22:31 | 5 |
Разные. Официальный способ, рекомендованный 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 минут Спасибо! Да натыкался на неё ... Только вот мне не понятно всёравно как сделать локализацию с ресурсами... Если писать как рекомендует мелкософт для каждого языка свой ресурс... То мне не понятно как перегружать ресурсы ... Т.е. в для одного исполняемого файла будет несколько ресурсов..., И как их выберать будет программа.... P.S. не по теме. Если нужны ссылки которые здесь не прокатили могу в личку попробывать бросить, пока ещё в истории есть.
0
|
Ушел с форума
|
|
22.06.2013, 17:06 | 7 |
Предположим, что нужно перевести программу на два языка - русский и английский.
Для этого все строки в тексте программы, в диалогах, в ресурсах и т.п., заменяются соответствующими идентификаторами, нейтральными по отношению к языку. Например, текст кнопки "Закрыть" меняется на "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
|
Ушел с форума
|
|
22.06.2013, 18:52 | 9 |
Ресурсы можно группировать по языковому признаку.
Например, можно иметь два диалога с одним 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
|
Ушел с форума
|
|
23.06.2013, 20:53 | 11 |
Попробуйте что-нибудь типа EnumResourceNames/EnumResourceLanguages.
Так можно сразу найти все ресурсы одного типа и загрузить их куда нужно.
0
|
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|
23.06.2013, 21:04 | 12 |
Можно подумать, количество диалогов зависит от способа перевода, а не равно произведению их количества в оригинале на количество языков.
0
|
Ушел с форума
|
|
23.06.2013, 21:13 | 13 |
Конечно зависит. 10 language-neutral диалогов плюс 5 языковых файлов - это совсем не то,
что 50 диалогов, по 10 на каждый язык.
0
|
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
|
||||||
24.06.2013, 09:33 [ТС] | 14 | |||||
Подскажите плз, как получить текущий язык системы?...
Нашёл GetLocaleInfoEx, но не пойму где можно посмотреть коды языков... Т.е. можно в ф-ции указать флаг LOCALE_RETURN_NUMBER И она должна вернуть целое, код языка. А где вот посмотреть эти коды??? Мне нужно для русского и английского. Вот пример, получения языка.
http://msdn.microsoft.com/en-u... 85%29.aspx Добавлено через 18 минут Спс! Посмотрел. Но немного не то что бы мне хотелось... Я наверно просто неудачно обьяснил в посте выше... Проблем с загрузкой из ресурсов нет, а есть проблема с именами переменных в которые должна записываться строка. Т.е. хотелось бы грузить в переменные с понятным названием в цикле... Например... for (int i = IDS_1; i <= IDS_1000; i++) { здесь грузим в переменую } И чтобы переменные подставлялись в цикл по очереди, и сами переменные имели вид типа - bClose, bOpen и т.д. Я подумал и походу так не сделаешь... Можно грузить в цикле например в массив строк типа buf[255][255], Подставляя в первый индекс i , но тогда из названия buf[100], не будет понятно что там за строка и прийдётся лезть в таблицу строк чтобы посмотреть что за строка.
0
|
Ушел с форума
|
||||||
24.06.2013, 10:20 | 15 | |||||
Я делал с помощью GetSystemPreferredUILanguages, это для Windows Vista и выше.
Для систем до Windows Vista отдельный workaround через GetSystemDefaultUILanguage. Все-таки язык и локаль - не одно и то же. Например, здесь: Language Identifier Constants and Strings А зачем нужны эти страшные циклы и буферы статического размера ? Не проще ли сделать как-то так:
То есть, каждой строке в ресурсах сопоставить свой понятный ID, не просто номер. И загружать их "лениво", только по мере необходимости, а не все сразу и в цикле.
1
|
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
|
|
24.06.2013, 11:30 [ТС] | 16 |
Спасибо!
Как раз читал о них... Вот только один вопрос... Почему Вы использовали GetSystemPreferredUILanguages, а не например GetUserDefaultUILanguage? На сколько я понял Ваша ф-ция получает предпачтительный язык системы... Почему не язык интерфейса для текущего пользователя? язык системы может же отличатся от языка который использует текущий пользователь... Это от привычки наверно... В жизни стараюсь сразу всё необходимое сделать на данный момент и потом расслабиться... Вот видно и в программирование отражается... Загрузил всё сразу, и гуляй смело... Можно и так конечно... Просто лень загружать каждый раз, вот и хотел облегчить себе жизнь - подставил нужный буфер и готово ... Но по ходу облегчить таким способом не удастся... И проще будет так как Вы предложили... Хотя вот думаю не возникнет ли проблем с айпишными функциями из за wstring... Мелкософт не очень любит стандартные методы c++... Иногда прям в наглую выдаёт ошибку при компиляции и коммент типа - "используйте вот эту ф-цию вместо вашей."
0
|
Ушел с форума
|
|
24.06.2013, 13:56 | 17 |
Нужно было получить язык системы. Именно системы, не пользователя.
GetSystemDefaultUILanguage возвращает "install language", это не совсем то, что нужно. Ну а язык пользователя лучше получать через GetUserDefaultUILanguage. Вот здесь есть кое-что полезное по теме: User Interface Language Management Еще вариант - вообще отказаться от хранения строк в стандартных ресурсах. На STRINGTABLE и LoadString мир ведь не заканчивается. Можно использовать двоичный тип ресурса, в котором хранить строки в каком-то своем, внутреннем формате. И, например, реализовать иерархический доступ к строкам. Или доступ по тэгам. Или прикрутить к этому делу препроцессор, который будет обрабатывать входные файлы и автоматически составлять список текстов для перевода на каждой сборке, выдавая ошибку, если для какой-то строки не хватает перевода. Конфликтов между Windows SDK и стандартной библиотекой C++ быть не должно, иначе писать софт на Visual C++ было бы значительно труднее. Ну а предупреждения действительно бывают в отношении каких-то стандартных функций, например sprintf, хотя если задуматься, многие из этих функций действительно небезопасны и в предупреждениях есть здравый смысл, как и в том, чтобы пользоваться более надежными аналогами. Хотя это и не по стандарту.
1
|
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
|
|
24.06.2013, 17:23 [ТС] | 18 |
Да, реализации конечно должны быть интересные такими методами...
Но для меня бинарники вобще тьма... Я вот как-то не понял с разу как с ними работать так и до сих пор их обхожу... Я имею в виду не открыть/закрыть и т.д. А именно работу со строками в бинарники... В какой-то книженции или howto разбирали как скидывать в бинарник целый класс со всеми текущими данными... А потом загрузку из бенарника этого всего обратно в класс... Так вот я так и не понял этого всего... Сначала как-то нужно было пропарсить бинарник чтобы разобрать структуру строк, потом вытаскивать по строке... В общем я не понимаю в каком виде там лежат строки... Визуально не представляю... Парсить обычный текст вроде знаешь хоть как примерно может выглядеть документ/файл а вот в двоичном виде...
0
|
Ушел с форума
|
|
24.06.2013, 17:52 | 19 |
Это называется сериализация.
Самому такое лучше не делать, а воспользоваться библиотеками. Например, boost::serialization. А представлять в большинстве случаев и не нужно. Просто берете какой-нибудь формат описания данных, например XML, JSON, INI и т.п., и перекладываете всю работу на библиотеки, реализующе парсинг и работу с этим форматом. Нужно будет лишь обеспечить загрузку ресурсов и подачу их на вход парсера.
0
|
9 / 9 / 0
Регистрация: 14.01.2013
Сообщений: 102
|
|
24.06.2013, 18:18 [ТС] | 20 |
Ну вот видите... знания - это сила!
У меня нет пока ещё такого богатого опыта и соответственно я не так легко ореентируюсь в теме... Да и как начинающему мне интересно сама реализация нежели просто получение результата из парсера... В общем хотелось бы знать как оно работает там внутри... А для "рабочего" программирования т.е. если рассматривать программирования с точки зрения получения средств к существованию, а не как средства самосовершенствования, то да, тогда лучше использовать проверенные методы.
0
|
24.06.2013, 18:18 | |
24.06.2013, 18:18 | |
Помогаю со студенческими работами здесь
20
Многоязычный интерфейс для MS ACCESS многоязычный интерфейс чтения из ини файлов Python + PyQt Многоязычный интерфейс программы многоязычный сайт Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |