В общем, под это дело можно и отдельный топик. Итак: новая версия компонента. Полного автоматизма нет, и, как я решил, не будет. Но не пугайтесь, все стало еще проще
В архиве содержится пакадж с компонентом, который надо установить перед открытием тестового проекта (если вы захотите поиграть с проектом).
Собственно, что нового? Давайте попробую рассказать по шагам, как пользоваться этим добром теперь:
1. Бросаете на форму компонент TInterfaceTranslator (искать надо на вкладке "Flamer" в палитре
).
2. Указываете имя файла.
3. Устанавливаете Active в true.
4. Компилируете и запускаете приложение.
5. Получаете выходной файл с оригинальным интерфейсом.
То есть компонент изначально настроен на экспорт. Это легко изменить, установив в Object Inspector свойство TranslationMode = tmTranslate. Теперь компонент будет устанавливать интерфейс из файла, указанного в свойстве FileName.
Да, еще: к сожалению, никакой design-time выгрузки нет и вряд-ли будет, т.к. раз уж это дело в проекте юзается, то надо юзать по-жизни, а не только в design-time
Как переключать интерфейс? До обидного просто (примем за постулат, что Active у компонента выставлено в true и TranslationMode равно tmTranslate):
InterfaceTranslator->FileName = "russian.txt"; // автоматом русский язык стал во всех доступных формах
InterfaceTranslator->FileName = "english.txt"; // вернули басурманский взад :)
Как быть с динамически создаваемыми компонентами (формами, фреймами, кнопками и пр.)? Как быть, если у вас в проекте много форм, но хочется иметь один файл с интерфейсом и не иметь по копии компонента на каждой форме? Попробую ответить по порядку:
1. Как обычно вы создаете компоненты? Я — примерно так:
TButton* btn = new TButton(this);
btn->Parent = this;
btn->Caption = "Dynamic Button";
То есть имени у этого компонента нет, ссылаться при экспорте непонятно на что и вроде бы косяк. Нет, не косяк. Специально для этого случая в компоненте предусмотрена возможность задания имени таким компонентам, причем имя подбирается так, чтобы не конфликтовать с другими именами компонент в контейнере.
Теперь о птичках: как-же локализовать такой компонент? Очень просто, добавлением всего одной строчки:
TButton* btn = new TButton(this);
btn->Parent = this;
btn->Caption = "Dynamic Button";
InterfaceTranslator->Translate(btn);
И все. Но лучше, конечно, во избежание коллизий все-таки давать имена компонентам. Я не тестировал и пока не знаю, как поведет себя компонент при условии, что есть две формы в приложении и в каждой из них создается вот по такой безымянной кнопке. Подозреваю, что одна из них перестанет переводится, хотя не уверен и может быть все будет работать.
2. Как быть, если у вас в проекте много форм, фреймов и пр., как автосоздающихся, так и создающихся в коде? Здесь уже ручками. Поскольку я принял решение не использовать Screen->OnActiveFormChange, а Loaded не всегда полезен (особенно, когда компонент лежит на TDataModule — там вообще транслировать нечего
), то вы можете воспользоваться одним из следующих методов:
а. Самостоятельно заюзать Screen->OnActiveFormChange и дергать Translate для активной формы.
б. После создания, но перед показом формы/фрейма/пр. дернуть Translate для этой формы
в. В OnCreate нужной формы дергуть Translate
Не рекомендую тыркать компонент во все формы, ибо это излишне. Лучше всего создать дата-модуль и туда его, туда
И дергать Translate при необходимости.
В общем, сами увидите в тестовом проекте, насколько все на самом деле стало просто. Сам архив (302 Кб) вместе с тестовым exe доступен здесь:
http://www.rsdn.ru/File/4597/InterfaceTranslator.1.0.zip
Как обычно — поздравления и аплодисменты
З.Ы. Да, если что — не серчайте, что мог обмануть ваши ожидания в каком-то из пунктов. Во-первых, не все сразу. Во-вторых, я делаю так, как мне удобнее, что очевидно.