Описывается методика автоматизированного перевода интерфейса на другой язык
(читать далее)Как правило, необходимость перевода интерфейса возникает, когда не ждёшь. Если вы в своей программе каким-либо образом это уже предусмотрели и её использовали, вам будет просто. А вот даже если вы предусмотрели, но использовали только "кое-где", начнётся геморрой. И чем больше программа, тем больше проблем.
Некоторые среды разработки предоставляют свои функции для этого. Можно ещё воспользоваться, например, gettext, но когда надо было мне, я про неё забыл. Хотя помнил основные принципы. Из чего и родилось нечто.
Итак, у нас есть программа под винду на C++. Часть строк хранится в тексте программы, часть в файле ресурсов. Вообще, ресурсы имеют код языка и могут быть размещены в dll, поэтому, если бы разработчик думал в самом начале, можно было бы свести перевод к переводу текста ресурсов. Но разработчик не подумал и часть строк для перевода в файле ресурсов, а часть в исходном тексте.
Итак, задачи:
1. Обработать файл ресурсов (ну, это легко)
а) Выдрать строки из файла ресурсов в отдельный файл
б) переведённый строки запихать на свои места
2. Обработать все файлы с исходными текстами
Можно было бы сделать точно так же, но тогда количество файлов для перевода будет равно числу файлов с исходными текстами. А даже если сливать всё вместе, то будет трудно понять, какие строки откуда.
Сделаем следующим образом:
а) каждой строке сопоставим некий идентификатор
б) идентификатор положим как #define в специальный заголовочный файл (который потом будет включён во все файлы с исходными текстами)
в) все текстовые строки заменяем на tr(ID)
г) сами строки складываем в файл языка, где содержатся строки вида ID="string"
д) создаём файл с исходным текстом, в котором содержатся три функции -- загрузить язык, выгрузить язык и выдать фразу по идентификатору ( tr(ID) ).
Как сформировать имя идентификатора, чтобы было хоть что-нибудь понятно? В исходной строке все латинские буквы становятся заглавными, цифры остаются без изменений, все остальные символы заменяются на нижнее подчёркивание ("_"). Чтобы не думать по поводу первого символа, который не может быть цифрой, "_" можно добавлять в начало автоматом (я просто сделал, что кавычки участвуют в формировании названия, поэтому мои идентификаторы и начинаются и заканчиваются на "_".
Итак:
В исходном тексте:
"string" -> tr(_STRING_1_)
В заголовочном файле:
#define _STRING_1_ 1
В файле языка:
_STRING_1_="string"
Тут можно переводить уже.
Пример реализации:
pastebin.com/Uw2FRVcm p_trans.cpp -- программа автовыдирания и автозамены строк (см. примечания)
pastebin.com/A3CKqi5b translation.cpp -- "движок", лол (см. примечания)
pastebin.com/W2JYRZ3k translation.h -- заголовочный файл, надо включить во все файлы проекта
pastebin.com/EBWX3qiW tl.h -- пример файла с определениями строковых констант
Примечания:
1. Данный пример реализации очень сырой. Многое не работает или неизвестно, работает или нет.
2. В начале работы программы (чем раньше, тем лучше) следует вызывать LoadLanguage, а в конце (или при переключении языков) -- UnloadLanguage.
3. translation.h включается в StdAfx.h, а если его нет (отключены pre-compiled headers или вообще не студия, то надо раскомментировать в p_trans.cpp строки, добавляющие включение этого файла во все файлы исходников.
4. После работы программы p_trans исходники будут безвозвратно изменены. Необходимо сделать бэкап.
5. Если в текстовых строках больше двух обратных слэшей подряд, они заменяться не будут (т.е. "\\" заменяется на "\", "\\\\" заменяется на "\\", а остальное нет).
6. p_trans затрагивает инициализацию массивов символов строкой-константой и заменяет на инициализацию при помощи функции. Это не работает. Если у вас есть места с инициализацией массивов строкой-константой, замените в этих местах вызовы на оригинальные строки вручную, на вызов strcpy или на подобное:
#define SOME "some"
char t[10]=SOME;
Такое заменяться не будет, т.к. все директивы препроцессора пропускаются.
7. Вообще это поделка, используйте gettext.
Пожалуйста, ознакомьтесь с комментариями!
Как перевести интерфейс своей собственной программы
Описывается методика автоматизированного перевода интерфейса на другой язык
(читать далее)
Пожалуйста, ознакомьтесь с комментариями!
(читать далее)
Пожалуйста, ознакомьтесь с комментариями!