Страницы

вторник, 9 сентября 2008 г.

Как обработать все resourcestrings в программе. Код.

Последнее время был занят занимался созданием механизмов для перевода наших приложений. Требования были такими:

  1. перевод должен работать по словарю
  2. словарь должен храниться в БД
  3. должны переводиться все Caption-ы у контролов, resourcestring'и и текст из БД

Основной класс, переводящий в runtime созданные формы, и подменяющий resourcestring'и был сделан за пару дней. Большая же часть времени ушла на составление словаря используемых фраз. Пару дней я потратил пытаясь разобраться как получить список всех resourcestring'ов в программе. Этот вопрос неоднократно поднимался на разных форумах, но полное решение нигде не приводилось. В общем решение нашлось, и в довольно неожиданном для меня месте. В Program Files\Borland\Delphi6\Demos\ResXplor. =)

Я собрал все необходимые классы в одном модуле. Модуль экспортирует одну функцию scCollectResourceStrings:

procedure scCollectResourceStrings( aExeFilename: string; aPerformForEveryFoundString: TscOnGetResString);

у этой функции два параметра:
1) aExeFilename: string - путь до файла с ресурсами
2) aPerformForEveryFoundString: TscOnGetResString - callback фунция, вызываемая для каждого найденного ресурса строкового типа.

TscOnGetResString = procedure (aText, aData: string) of object;

У callback функции[1] два параметра:
aText - resourcestring
aData - представляет из себя строку формата: "ID ресурса = текст ресурса".

aText и aData формируются в процедуре TStringResource.ForEveryString. Так что их формат данных можно легко изменить, подправив пару строк кода.

Скачать модуль можно здесь: http://sites.google.com/site/lazyproject/downloads

Прямая ссылка

Ссылки по теме

 

[1] О Callback-функциях можно почитать в соответствующей главе статьи Основы работы с Windows API.

5 комментариев:

  1. > Основной класс, переводящий в runtime созданные формы, и подменяющий resourcestring'и был сделан за пару дней.

    А можно от сюда по подробнее особенно про подмену resourcestring?

    ОтветитьУдалить
  2. Я использовал подмену стандартных функций LoadResString, LoadStr и FmtLoadStr своими. Для подмены использовал готовую процедуру FastcodeAddressPatch из библиотеки FastCode.

    Т.е. в один из юнитов в секцию Initialization был добавлен такой код:
    FastcodeAddressPatch(@LoadResString, @MyLoadResString);
    FastcodeAddressPatch(@LoadStr, @MyLoadStr);
    FastcodeAddressPatch(@FmtLoadStr, @MyFmtLoadStr);

    ОтветитьУдалить
  3. Добрый день а нельзя ли поподробнее как вызвать коллбек. Создать елемент класса?

    ОтветитьУдалить
  4. Не особо понятно как вызывать функцию, на входе она имеет путь к файлу.. и что еще? Если возможно в коде!

    ОтветитьУдалить
  5. Анонимный, я сейчас не помню деталей, а исходник смотреть нету времени. Посмотри объявление типа TscOnGetResString и где-нибудь почитай о том, как работать с процедурными типах (хотя бы на примере event-ов) и о работе с callback.

    ОтветитьУдалить