В общем, под это дело можно и отдельный топик. Итак: новая версия компонента. Полного автоматизма нет, и, как я решил, не будет. Но не пугайтесь, все стало еще проще В архиве содержится пакадж с компонентом, который надо установить перед открытием тестового проекта (если вы захотите поиграть с проектом).

Собственно, что нового? Давайте попробую рассказать по шагам, как пользоваться этим добром теперь:

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

Как обычно — поздравления и аплодисменты

З.Ы. Да, если что — не серчайте, что мог обмануть ваши ожидания в каком-то из пунктов. Во-первых, не все сразу. Во-вторых, я делаю так, как мне удобнее, что очевидно.
Автор: Flamer    Оценить