Перевод в delphi приложениях


Перевод приложений delphi

такой сомнительный перевод программы с одного языка на другой в автоматическом режиме не гарантирует вам корректность ее выполнения. Далеко не гарантирует, если такие переводчики вообще существуют.

Помогите хоть примером как нибудь.

Давай определимся, зачем это нужно? Что пытаешься сделать? И исходя из этого будем думать о решении проблемы

Создал прогу на русском языке и хочу сделать из нее шареварную. Для этого надо бы перевести ее на 8 языков (с гуглом)

А, вот в чем дело. Я уж подумал, что речь идет об языках программирования. Для поддержки многоязычности твоего приложения используй ini или типовой файл, из которого будут загружаться все подписи, тексты интерфейса при запуске программы.Например:Допустим, у нас на форме одна кнопка и сама форма. Для загрузки caption формы и кнопки используем такой код:

Перевод в delphi приложениях

После того как весь код отлажен и написано руководство, перед разработчиком встает задача «донести» написанное до пользователей, говорящих на разных языках. Чем сложнее становятся современные программные продукты, тем более запутан этот процесс. Эта глава расскажет вам об одном аспекте пользовательского интерфейса, который нужно знать, прежде чем отпускать свою программу «в свободное плавание». Речь идет о способах перевода всей информации в приложении на другие языки.

Многоязычные приложения. Создание библиотек ресурсов

Согласно корпоративной стратегии Inprise. вопросам создания приложений, работающих в многоязычной среде, уделено в последних версиях Delphi большое внимание. Проблема перевода приложения на другие языки не так проста, как кажется с виду, и может отнять значительную часть времени, выделенного на разработку проекта.

Адаптация приложения к работе на различных языках и с использованием различных национальных настроек называется интернационализацией. Собственно процесс внесения национальных изменений (перевод текста ресурсов, смена форматов представления данных) называется локализацией.

Точный смысл термина локализация (locale) вовсе не идентичен понятию «страна». Он складывается из двух частей: настроек на особенности конкретной страны и на используемые в ней языки. Для некоторых стран при локализации Windows используются по два языка или разновидности, например, в Сербии и Норвегии. Также верно и обратное — один язык (в частности, английский, испанский, арабский) применяется во многих странах. При этом национальные особенности (система мер, терминология, способ сортировки, форматы представления денежных единиц и даты/времени) в этих странах отличаются. Поэтому название локализации состоит из трех букв: две обозначают язык и одна — страну. В программах для Windows вы можете встретить разновидности английского: ENLJ (США), ENG (Великобритания) и еще с десяток. Для России (локализация RUS) эта двойственность отсутствует.

Традиционный способ разделить программный код и элементы пользовательского интерфейса — это использование ресурсов. Со средствами разработки от Inprise, начиная еще с Borland Pascal for Windows, поставляются инструменты для работы с ресурсами, такие, как Resource Workshop. В Delphi сама форма, по сути дела, является ресурсом, с которым можно работать прямо в визуальной среде; для специализированных графических ресурсов предназначена утилита Image Editor.

Предлагаемая Inprise методика локализации заключается в следующем. Все зависящие от языка ресурсы объединяются в динамические библиотеки ресурсов, которые затем распространяются вместе с приложением. При запуске в новой среде на компьютере пользователя специальный код инициализации приложения считывает системные языковые настройки и затем загружает соответствующую библиотеку. Процесс этот полностью скрыт от разработчика и не требует добавления никакого кода — надо только осуществить перевод нужных ресурсов.

В Delphi 5 специально для решения задач локализации появился целый комплекс средств под общим названием Integrated Translation Environment (ITE). Он состоит из трех составных частей: Мастера создания динамических библиотек ресурсов (Resource DLL Wizard), Менеджера переводов (Translation Manager) и Репозитория переводов (Translation Repository). Им, в основном, и посвящена данная глава.

Мастер создания динамических библиотек ресурсов

В Delphi процесс интернационализации легче всего автоматизировать путем создания так называемых динамических библиотек ресурсов. На это есть специальный мастер, вызываемый через пункт New. меню File (рис. 10.1). Можно вызвать его и другим путем — через пункт меню Project\Languages\Add.

Мастер создания библиотек ресурсов работает только в том случае, если имеется открытый проект (который и предстоит интернационализировать). Перед вызовом мастера убедитесь, что в этом проекте все строки, которые вы выводите на экран и собираетесь переводить, объявлены через ключевое слово resourcestring. Они должны использоваться в программе: если они просто объявлены, но не используются, оптимизирующий компилятор Delphi уберет ссылки на них и в библиотеки ресурсов они не попадут.

Первым выводимым Мастером окном будет приветствие и краткое описание возможностей. Далее мастер показывает диалоговое окно, в котором следует выбрать проекты, подлежащие интернационализации (рис. 10.2). Термин базовый язык (Base Language, третий столбец) означает код языка, который будет присвоен основным файлам проекта; по умолчанию базовый язык берется из текущих настроек операционной системы.

Рис. 10.1. Вызов мастера создания библиотек ресурсов

Рис. 10.2. Мастер создания библиотек ресурсов. Диалоговое окно выбора проектов

Рис. 10.3. Выбор языков, на которые будет осуществлен перевод

После этого пользователь получает возможность выбрать языки, на которые он будет переводить ресурсы (рис. 10.3), а также название и папку для локализованных файлов.

Вы можете внести в создаваемый локализованный проект и другие виды ресурсов, которые могут иметь национальный характер — значки, изображения, звуки и т. п. Все они должны быть описаны в файлах с расширением rc (или dfm), которые добавляются на следующем этапе работы мастера.

Мастер автоматически выносит в библиотеку два вида ресурсов — формы приложения и текстовые строки. При этом он создает следующие файлы:

  • в папке проекта создается файл с именем проекта и расширением drc, который представляет собой совокупность всех используемых строковых ресурсов. Формат этого файла — обычный исходный текстовый формат хранения ресурсов (rc);
  • проект с тем же именем, что и исходный; он будет лежать во вложенной папке с именем, соответствующим выбранной стране локализации. В него входят все файлы, которые обычно встречаются в проектах, плюс специальные файлы ite. Первая разновидность файлов носит название имя формы, dfn, вторая — имя проекта_орс.рс. Это наши «старые знакомые» — два вида ресурсов, дополненных специальными комментариями для работы ite. Хотя они имеют текстовый формат, но редактировать их вручную не следует — методика работы с ними описана ниже, в описании утилиты Translation Manager.
  • файл группы проектов с расширением bpg. Действительно, наш проект дополнился еще одним, и теперь они составляют группу. Единственный недостаток мастера — он предлагает сохранить файл bpg в той же папке, где и созданная локализация. Целесообразнее сделать это в корневом каталоге исходного проекта.

Результатом компиляции станет динамическая библиотека с именем имя проекта имя локализации, в данном случае PROJECT 1 . UKR. Эту библиотеку

нужно поместить и распространять вместе с ЕХЕ-файлом проекта. При запуске приложения, написанного на Delphi 5, библиотека времени выполнения производит попытку настройки. Если на целевом компьютере установлен тот национальный интерфейс, который соответствует расширению динамической библиотеки ресурсов (в данном случае ukr), то все локализованные вами ресурсы будут загружены из нее.

После создания проекта библиотеки (*.dpr) перед глазами открывается такой весьма скупой код, содержащийся в нем:

// Do not edit. This file is machine generated by the Resource DLL Wizard.

($R ‘Unitl.dfm’ Forml:TForm)

Две директивы $r указывают на те ресурсы, ради которых все и «затевалось». Директива $е указывает на расширение файла, которое будет присвоено динамической библиотеке после компиляции.

Для ресурсов-текстовых строк в язык Object Pascal введено новое ключевое слово — resourcestring. Строки-константы, описанные с его помощью, будут собраны вместе в таблицу ресурсов. Если вы хотите упростить проблему локализации вашего приложения, замените везде выражения вида

ShowMessage( ‘ Ошибка открытия файла’ );

resourcestring sOpenError = ‘ Ошибка открытия файла ‘;

Целесообразно собрать все ресурсные строки вашей программы в одном месте; лучше всего для этого выделить отдельный модуль. Так поступили и разработчики VCL — найдите модули consts.pas, dbconsts.pas, BDECONST.PAS, OLECONST.PAS, MIDCONST.PAS, MXCONSTS.РА S , WEBCONST.РА S в прилагаемых к Delphi исходных текстах. Кроме строковых констант, описанных через ключевое слово resourcestring, там ничего нет. Для того чтобы перевести все сообщения среды выполнения Delphi на русский, вам достаточно перевести эти модули с помощью ite и затем включить их национальную версию в состав вашего проекта.

Использование Менеджера переводов

В версии 5 среды Delphi значительно усовершенствованы инструменты для автоматизации подготовки многоязычных версий. После выполнения мастеpa создания динамических библиотек ресурсов управление автоматически передается Менеджеру переводов (рис. 10.4). Специально для его вызова предназначен также пункт Translation manager меню View.

Рис. 10.4. Внешний вид Менеджера переводов (Translation Manager)

Окно Менеджера переводов состоит из двух частей. В левой части приводится список всех проектов на разных языках и сосредоточены административные функции. Для каждого проекта предусмотрены две папки, соответствующие разновидностям локализуемых ресурсов: Формы (Forms) и Скрипты ресурсов (Resource scripts).

В правой части содержатся более подробные данные. Остановимся и мы на них более подробно. Если в левой части выделен проект на национальном языке или его составная часть (Папки с формами или скриптами), то в правой части вы увидите статистическую информацию: сколько ресурсов переведено, сколько — нет, общее количество и процент готовности.

Если в левой части выделен конкретный ресурс, в правой появляется таблица с теми свойствами и значениями, которые подлежат интернационализации. Такая таблица показана на рисунке 10.4.

В эту таблицу Менеджера переводов попадают не все свойства визуальных компонентов, а только те, которые собственно и поддаются локализации. Что это за свойства? Их легко увидеть в Инспекторе объектов, если переключить его в режим отображения свойств по категориям. Нужные нам свойства находятся в категории LocalizabIe (рис. 10.5).

На рисунке видно, что помимо шрифта и надписей, в состав свойств, меняющихся в зависимости от языка, входят также размеры, значки, файл справки и т. п. У многих компонентов в’Delphi 5 есть свойства RiniModp и ParentBiDiMode, описывающие начертание текста. Они позволяют располагать его справа налево, как это принято в ряде ближневосточных языков.

Поскольку написание приложений для стран Востока является для нашей страны редкостью, в книге данный вопрос не рассматривается.

При разработке пользовательского интерфейса имейте в виду, что длина надписей (в буквах) на национальных языках может сильно отличаться от их длины на английском, вплоть до двукратного удлинения. Учтите это при расположении компонентов типа TLabel, TEdit и т. п. Где возможно, позвольте компонентам автоматически масштабироваться.

Рис. 10.5. Локализуемые свойства компонента TForm

Серым цветом в таблице Менеджера переводов отображаются нередактируемые столбцы, белым — редактируемые. Если вы хотите управлять составом и сортировкой столбцов, в меню Actions можно настроить параметры их отображения. Назначение столбцов таково.

В столбце ID указывается идентификатор ресурса. Для строковых констант в этой колонке отображается имя константы. Например, если вы увидели идентификатор sysConst_szeroDivide, то в файле с расширением drc можно найти соответствующую этой константе строку «Floating point division by zero». Это имя образуется из имени модуля, где описана константа, и имени самой константы, разделенных символом подчеркивания. Для компонентов на формах ID образуется по другому правилу. Если вы видите > начинающийся с о — это свойство объекта (см. рис. 10.4). Буква i будет означать, что объект унаследован с другой формы, a l — с кадра (Frame). Таким образом, идентификатор o:Formi.Font.Name соответствует имени шрифта формы Formi.

Следующая колонка показывает значения всех свойств для базового языка проекта. В проекте RichEdit этот язык — английский, а если вы создаете новый проект в русскоязычной версии Windows, то этот язык будет русским. Новые (переведенные на тот или иной язык) значения содержатся в столбце с именем этого языка.

Столбец Status показывает состояние свойства; значение Translated означает, что перевод осуществлен. У него есть три возможных значения: Translated, Untranslated и Auto Translated. Любое изменение свойства устанавливает этот флаг в Translated. Если вы не хотите реально изменять строку, можно просто переустановить свойство щелчком в данной колонке. Значение Auto Translated устанавливается, если перевод осуществлен при помощи Репозитория переводов (см. следующий раздел).

Столбцы Created и Modifie d создаются и автоматически поддерживаются системой. Наконец, если вы хотите прокомментировать значение свойства, в вашем распоряжении столбец Comment.

В таблице Менеджера переводов достаточно удобно редактировать текстовые строки, тем более что для этого есть специальный двухоконный редактор (он вызывается из панели инструментов Менеджера переводов, рис. 10.6). Но вот другие виды свойств — перечислимые (как например Font.charset), числовые — редактировать не очень удобно. А свойство icon (значки) редактировать практически невозможно — значок представлен в двоичном виде. В этом случае редактировать формы нужно при помощи стандартных возможностей среды Delphi и Инспектора объектов, а затем сохранить изменения и вернуться в Менеджер переводов. При этом свойство получит флаг Translated.

Рис. 10.6. Такой редактор встроен в Менеджер переводов

Что делать, если вы отлаживаете ресурсы сразу для нескольких стран, а требуемая локализация не установлена у вас на компьютере? В пятой версии Delphi упрощен процесс переключения между языками при отладке. Теперь для этого предусмотрен пункт главного меню Delphi Project\ Languages\SetActive. Если все библиотеки DLL скомпилированы, то простым переключением в этом пункте меню вы можете просмотреть работу каждой из них. Если выбрано значение none, то приложение запускается с тем видом ресурсов, который соответствует текущим настройкам Windows. Разработчиками Inprise предусмотрен и другой выход из этой ситуации. Вы должны внести в ключ системного реестра hkey_current_user\

Software\Borland\Locales элемент данных вида «имя_приложения»=»имя_локализации». Например, если вы хотите испытать интерфейс описываемого приложения на украинском языке, элемент данных должен выглядеть так:

[HKEY_CURRENT_USER\Software\Borland\Locales] «d:\\Program Files\\Borland\\Delphi5\\Project5

В этом случае, независимо от реально установленных национальных настроек компьютера, будет загружен украиноязычный интерфейс.

Можно переключать национальные интерфейсы и «на ходу», во время работы приложения. Пример этого приведен в приложении RICHEDIT, поставляемом среди примеров с Delphi (папка d emo s\richedit). В нем при помощи меню вы можете выбрать один из трех языков, и тут же подгрузится необходимая динамическая библиотека ресурсов. Если вы всерьез занимаетесь проблемами интернационализации, советуем обратить на этот пример самое пристальное внимание. Функции, которые осуществляют это (модуль reinit.pas). можно без изменений позаимствовать и внести в свой проект.

Использование Репозитория переводов

Для централизованного хранения переведенных на другие языки ресурсов в Delphi 5 есть специальное средство — Репозиторий переводов (Translation Repository, рис. 10.7). Эта утилита позволяет собирать переведенные строковые ресурсы из проектов и в дальнейшем использовать их во вновь создаваемых проектах.

Репозиторий создает специальный файл с расширением drs, который хранится в папке исполняемых файлов Delphi (Delphi \Bin). Вы можете создавать и редактировать свои собственные DRS-файлы, использовать и распространять их, а также пользоваться файлами, созданными другими разработчиками.

Функции Репозитория переводов на сегодняшний день достаточно малы: централизованно сохранять строки с возможностью потом загрузить их, а также предоставить возможности экспорта/импорта.

Илон Маск рекомендует:  Что такое код pg_client_encoding

Какова же польза от Репозитория? Когда вы начинаете локализацию нового проекта и добавляете в него новый язык, происходит просмотр содержимого Репозитория в поисках требуемых строк. Поиск осуществляется по идентификатору, точнее, по его числовому значению. Если строка с таким идентификатором уже имеется, ее переведенное значение автоматически добавля-

ется в ваш проект, напротив этой строки в Менеджере переводов в поле Status поднимается флажок AutoTranslated.

Рис. 10.7. Внешний вид Репозитория переводов

Вы можете один раз перевести константы из часто используемых файлов констант (consts.pas, sysconst.раз, DBCONSTs.раз и др.) или найти уже готовые файлы переводов в Интернете.

Строки в Репозиторий попадают из проекта так: в Менеджере переводов вы выделяете одну или несколько строк (со строковыми ресурсами!), нажимаете правую кнопку мыши и во всплывающем меню выбираете пункт «Repository\Add strings to Repository». В ряде случаев пункт Repository недоступен. Это может быть по двум причинам: среди выбранных вами ресурсов есть не только строки, и в случае совпадения исходного и целевого языков. Если вы хотите иметь англоязычную и русскую версии вашего приложения, нужно в Мастере создания библиотек ресурсов выбрать в качестве базового языка английский, а потом добавить к нему русскую DLL. В противном случае при работе в русской версии Windows строки на английском будут трактоваться как русские.

В проекте Richedit есть строки из модулей SysConst, Consts, ComStrs, уже переведенные на французский и немецкий. Если загрузить их в Репозиторий переводов, то это может послужить первым вкладом в вашу коллекцию ресурсов.

Импорт и экспорт данных предусмотрен в формате xml. Этот быстро набирающий популярность формат имеет хорошую перспективу стать стандартом де-факто для обмена данными.

Информация о версии вашего продукта

Если ваш программный продукт дорос до определенной степени зрелости, пора снабжать его информацией о версии. Это особенно важно, если он уже устанавливается и используется где-то, и у пользователей могут возникнуть вопросы. Когда вашу телефонную линию разрывают разные люди, и каждый сбивчиво пытается объяснить, что в такой-то формочке не работает такая-то кнопочка, нужно с холодным рассудком понять, что именно они имеют в виду. И лучшей подсказкой может послужить полная информация о версии, имеющейся у пользователя.

Вставить в ваш проект информацию о версии поможет сама Delphi. Вызвав пункт Options меню Project, на странице Version Info вы увидите структуру, которая и будет ее содержать (рис. 10.8). Для того чтобы в ваш проект попала эта структура, нужно поднять флажок Include version information in project.

Рис. 10.8. На странице Version Info вы можете задать информацию о текущей версии продукта

Что это за структура? Информация о версии помещается в особый вид ресурсов и компилируется в исполняемый файл или динамическую библиотеку проекта. Если вы запустите любой редактор ресурсов и загрузите в него какое-то приложение, помимо ресурсов Bitmap, Icon, Cursor, вы можете увидеть и тип Version. Такой тип ресурсов представляет из себя структуру двоичных данных, состоящую из поля фиксированной длины (fixeddfileinfo), поля данных локализации (translation) и набора строк переменной длины. То, что вы видите на рисунке, соответствует полям этой структуры.

Но что необходимо указать в этих полях? Чем FileVersion отличается от ProductVersion? Некоторые поля структуры являются обязательными, некоторые — нет. Обязательные поля приведены в табл. 10.1.

Таблица 10.1. Обязательные поля для информации о версии

Локализация приложений в Delphi для Win32

Умеете ли вы писать приложения для всего мира? Не так давно мой начальник в предвкушении скорого выхода нашей фирмы на международный рынок попросил рассмотреть возможность перевода многомодульного программного комплекса среднего уровня сложности с русского языка на английский с целью использования его в Латинской Америке! Конечно, я не знаю, насколько оправдано это решение с практической точки зрения и сколько языков знает среднестатистический индеец, но передо мной встала серьезная и новая для меня задача.

Тем более что идеология быстрой заменяемости строковых ресурсов в проекте (следовательно, и в готовой программе) была давно и безвозвратно нарушена по причине наличия массы более важных и безотлагательных задач — пусть это будет моя личная версия истории проблемы.

Актуальность вопроса локализации современных программных приложений сегодня уже можно поставить под сомнение, так как в современные мощные средства разработки и программные платформы, как правило, изначально заложены достаточные для некоторых типовых задач возможности локализации разрабатываемых современных решений. И это справедливо не только для Windows. В то же время перед разработчиками, как и десять лет назад, встает все та же задача по обеспечению интернационализации (или локализации) давно написанного ПО. А в случае, если создавалось оно сторонними программистами и всякие контакты с ними навсегда потеряны, сюда иногда добавляется еще и пикантная проблема отсутствия исходного текста, т.е. самого проекта. В этом случае весьма нелишним будет знать те инструменты, которые существуют для решения подобных задач.

Чтобы понять важность этапа проектирования самого решения с точки зрения последующей его адаптации для конкретного региона, можно дословно привести цитату из Википедии (http://ru.wikipedia.org): «Есть важное различие между интернационализацией и локализацией. Интернационализация — это адаптация продукта для потенциального использования практически в любом месте, в то время как локализация — это добавление специальных функций для использования в некотором определенном регионе».

Отсюда для опытного разработчика напрашивается вывод: чем точнее он учтет и реализует функциональность, связанную с интернационализацией его программного продукта, тем больше шансов свести к минимуму последующие усилия по его локализации.

Сама локализация может включать в себя перевод текстовых ресурсов графического интерфейса пользователя, документации, входящей в состав программного пакета, и более сложные работы, связанные с изменениями фрагментов исходного кода на уровне алгоритмов. Случается, что последний пункт иногда можно считать результатом просчетов на ранних стадиях работы над проектом. К примеру, такие вроде бы невинные вещи, как использование какого-то одного фиксированного формата строкового представления даты-времени в алгоритме обработки данных, могут повлечь за собой не только серьезные ошибки, но и непредвиденную трату большого количества времени на их выявление и борьбу с последствиями.

Очень часто встает отдельная, многоплановая, не всегда заметная при первом взгляде на проблему задача по локализации сообщений об ошибках, но актуальность ее в большей степени зависит уже от концепции программного пакета.

Сказать, что темой статьи является перевод пользовательского интерфейса, будет не совсем верно, потому что, как мы увидим из рассматриваемых решений, в тех случаях, когда имеет место профессиональных подход к качеству коммерческого программного продукта, грань между интернационализацией и собственно локализацией может стираться.

Мы рассмотрим только средства для локализации проектов в среде Delphi для Win32. Кстати, стоит заметить, что в этой IDE уже реализован один из способов локализации приложения.

Основное удобство этого решения заключается в его изначальном присутствии в Delphi, без дополнительной установки каких-либо программ и компонентов. Более подробную информацию о мастере добавления языков можно получить в соответствующих разделах справочной системы Delphi.

Итак, для упрощения нелегкой жизни разработчика существует ряд специализированных утилит и комплексных программных пакетов, которые позволяют значительно сократить затраты на локализацию. Кроме того, есть отдельный ряд программ, формально не относящихся к подобным утилитам, но имеющих, к примеру, удобный доступ к строковым ресурсам .exe- и .dll-файлов с возможностью их редактирования.

Возможные сравнительные характеристики сторонних продуктов

При выборе рассматриваемых решений мы руководствовались прежде всего такими критериями, как совместимость с Delphi 2006 (Win32), внятное указание на тип лицензии, наличие в пакете готовых примеров по локализации проектов. Наличие исходных текстов и возможность работы непосредственно с готовыми exe-модулями можно в общем случае считать дополнительными, но не обязательными характеристиками.

Во главу угла ставится удобство процесса локализации, ибо такие возможности, как динамическая смена языка, на поверку оказываются менее важны, чем, например, функциональное разграничение этапов подготовки локализации. Не будем забывать: программист зарабатывает на хлеб в основном все-таки не тем, что владеет иностранными языками. И ярче всего это проявляется, когда речь идет о переводе на экзотические языки.

Программный пакет «ДеЛок» («Дельфийный локализатор» — так расшифровывают название сами разработчики продукта) распространяется свободно, т.е. его можно использовать в любых проектах, включая условно бесплатные (shareware) и коммерческие.

Далее надо включить в проект локализуемого приложения файл LcUnit.pas, который входит в пакет вместе с «локализатором».

Во время создания формы, подлежащей локализации, необходимо вызвать для нее функцию TranslateComponent(). Вызов функции можно поместить в перегруженный конструктор формы (сразу после inherited) или в обработчик события OnCreate. В случае, если формы наследуются от одной базовой формы, можно поставить вызов функции TranslateComponent() только в ней.

В пакет входит файл русской справки и успешно запускаемый под Delphi 2006 демопроект, показывающий возможность переключения «на лету» русского и английского языков для основных элементов управления. Более подробно о работе модуля LcUnit.pas можно узнать из справочного файла или из файла readme_ru.txt.

На этом, пожалуй, стоит закончить весьма короткий список полноценных бесплатных решений для локализации. К сожалению, другие найденные утилиты, имеющие бесплатную лицензию, никак не дотягивали до профессиональных пакетов.

Helicon Translator

На сайте http://www.helicon.co.at/translator/ имеется 30-дневная ознакомительная версия Helicon Translator.

Важная особенность пакета заключается в том, что он позволяет работать как с файлом проекта, так и с бинарными модулями .exe, .bpl и .dll.

На этапе создания проекта транслятор в целях предотвращения ошибок может дважды уточнять версию использованной или используемой в текущий момент среды компилирования.

Недостаток исследуемой версии — отсутствие у нее явных признаков, свидетельствующих о возможности корректной работы с проектами Delphi 2006.

Advanced Localizer

Весьма серьезная фирма — разработчик ПО EMS, славящаяся своими мощными, универсализированными средствами администрирования для различных СУБД, предлагает набор компонентов для локализации под названием EMS Advansed Localizer Component Suite 1.51 (http://sqlmanager.net/products/tools/quicklocalizer).

Продукт поддерживает все версии Delphi с 5-й до Delphi 2006.

Готовые наборы строк, соответствующие одному конкретному языку, хранятся отдельно в виде INI-файла. Однако при всем удобстве решения в процессе работы со встроенными редакторами этих замечательных компонентов в режиме дизайна неоднократно выдавались сообщения с загадочными программными исключениями и дважды «сваливалась» сама среда Delphi. С пакетом поставляется help-файл и три демопроекта, из которых, в частности, можно понять, что данные с языковыми переводами можно держать не только в виде обычного текстового файла, но и в базе данных.

TsiLang

Как сказано в статье, «пользователи смогут переводить ваше приложение без вашего участия и перекомпиляции».

Теперь по поводу поддержки Delphi 2007. В апреле 2007 г., когда писалась эта статья, на сайте разработчиков можно было прочитать следующее (перевод с англ. автора): «Мы много работаем над завершением версии 6.1 и ее инсталлятора, которые будут поддерживаться в Delphi 2007. В данный момент на нашем сайте доступна новейшая версия, уже поддерживаемая в Delphi 2007. Для ее применения необходимо во время инсталляции использовать опции Turbo Delphi и вручную установить TsiLang в IDE».

Фрагмент внутреннего представления компонента класса siLang из демопроекта RicheditDemo представлен в листинге 2.

Когда в бассейне нет воды, или Про бойцов из стройбата

Задача немного усложняется, если у вас нет ни исходных текстов, ни магического map-файла программы, но вам во что бы то ни стало надо заменить какие-то строковые ресурсы графического интерфейса программы. Как раз в таких случаях можно попробовать воспользоваться поистине замечательной программой Restorator.

Блог GunSmoker-а (переводы)

. when altering one’s mind becomes as easy as programming a computer, what does it mean to be human.

четверг, 19 марта 2009 г.

Создание приложений для Windows Vista в Delphi — часть 1

Прим. пер.: речь идёт в основном о Delphi до 2007.

Итак, ваши приложения «работают»

К настоящему времени, надеюсь, Вы, как ответственный разработчик приложений, загрузили несколько из публичных бета-версий Microsoft Windows Vista, и убедились, что ваши приложения (и среда!) работают в новой ОС.

Хотя 99% всех хорошо написанных Delphi приложений будет работать под Vista без проблем (проблемы типа требования админских прав, элевации и UAC находятся за пределами этой статьи), они не имеют никаких бонусов с новых возможностей Windows Vista. Фактически, чем больше вы будете смотреть на новые возможности пользовательского интерфейса в Vista, тем больше ваши приложения будут смотреться как древние динозавры.

Но не беспокойтесь! Вполне возможно (и достаточно просто) преодолеть эти расхождения, и сделать ваши приложения выглядящими и «чувствующими» себя как дома с новым пользовательским интерфейсом Windows Vista. Давайте посмотрим на типичные проблемы приложений Delphi, и что мы можем сделать, чтобы улучшить наши программы.

Наше приложение-пример

Приложение-пример (sample application), над которым мы будем работать в этом посте, будет простой программой текстовым редактором типа Блокнота, с несколькими формами и действиями. Оно позволит вам загружать/сохранять текстовые файлы, а также показывать диалог «О программе» («About» dialog). Оно также будет спрашивать вас сохранить ваши изменения, когда вы открываете файл или выходите из программы, если вы ещё не сохранили документ.

Итак, хотя наше приложение просто работает под Windows Vista, под капотом всё еще есть несколько проблем.

О, нет. только не снова это (или: Новые шрифты)

Первая проблема, которую и проще всего исправить — и которая больше всего занимает времени в уже готовых больших проектах — это шрифт. В Windows Vista шрифт по-умолчанию для пользовательского интерфейса становится Segoe UI. Только это ещё половина проблемы. Самое интересное, что не только появился новый шрифт, но и размер шрифта по-умолчанию увеличился. По-умолчанию, приложения в Windows XP использовали Tahoma 8. Приложения в Windows Vista (которые «вписываются»), однако, используют Segoe UI 9. Это означает, что не только нам надо сменить свои шрифты (если нас запустили на Windows Vista), но нам также нужно проверить каждую форму, чтобы убедиться, что весь текст видимый и при необходимости делать нужные корректировки.

Давайте начнём с создания нового модуля с именем uVistaFuncs.pas. В него мы будем добавлять специфичные для Vista методы. Для начала мы добавим методы для проверки — а не запущены ли мы под Windows Vista, и для применения правильного шрифта и размера шрифта для указанной формы. Тогда, в FormCreate главной формы и нашей диалоговой форме «О программе» мы просто вызовем SetVistaFonts(Self), предварительно убедившись, что модуль uVistaFuncs вписан в uses.

Вы заметите, что заголовок в диалоговом окне «О программе» всё ещё использует шрифт по-умолчанию: Tahoma. Это от того, что мы меняли шрифт в режиме проектирования и поэтому свойство ParentFont стало False. Вы часто будете встречаться с такой ситуацией в своих программах. Чтобы проще всего было находить такие косяки — лучше всего вписать в uVistaFuncs “Segoe Script” вместо “Segoe UI”. При этом старый шрифт в запущенной программе заметить будет гораздо проще. В нашем случае нам нужно было просто присвоить TitleLabel.Font.Name после вызова SetVistaFonts.

Прим. пер.: в Delphi в модуле Graphics есть глобальная переменная DefFontData, в которой содержится шрифт по-умолчанию. Поэтому вместо вызова функции установки шрифтов в каждом окне (SetVistaFonts) можно рассмотреть вариант установки свойства ParentFont формы в True и модификации DefFontData в initialization своего модуля (для Vista: Name := ‘Segoe UI’; Height := -12;). Кстати, в старых версиях Delphi DefFontData — это всегда «MS Sans Serif» размером 8. В новых (вроде бы начиная с D2006) — это или «MS Sans Serif» 8 или системный шрифт «MS Shell Dlg 2» (доступен только в Windows Vista), если его удалось получить. Кроме того, вместо использования намертво зашитых шрифтов (типа Tahoma, MS Sans Serif, MS Shell Dlg 2 и Segoe UI) может быть лучше спросить систему о шрифте для UI. Этот подход в деталях разобран здесь.

Илон Маск рекомендует:  Инкапсуляция, полиморфизм, наследование

Где моя индукция (или: зачем секретное окно)?

Windows Vista представляет несколько новых элементов, которые помогают улучшить взаимодействие пользователя с системой. Вы можете прочитать (слегка устаревшую) статью про индуктивный пользовательский интерфейс (inductive user interfaces). Фактически, индуктивный пользовательский интерфейс помогает пользователю ориентироваться в том, что происходит на экране.

Некоторые примеры этого в Windows Vista включают в себя новую анимацию минимизации и максимизации окон. Как заметил в своём интервью Ales Holecek, многие пользователи не понимают концепции окон и связи окна с кнопкой в панели задач. Они не понимают, куда девается окно, когда оно минимизируется и остаётся только кнопка на панели задач. Чтобы исправить это (и покрасоваться новым 3D UI — Aero) в Vista, окна гладко анимируются в 3D в, и из, своих кнопок в панели задач при минимизации или максимизации.

Давайте. Попробуйте сами. но только не со своими Delphi приложениями! Если вы минимизируете или максимизируете приложение Delphi в Vista, то анимация будет как у закрывающегося и открывающегося окна: окно пропадает (fades away) или плавно появляется. Причина в том, что каждое приложение Delphi имеет скрытую секретную «форму application». Это Тайное Окно является владельцем кнопки в панели задач, которую вы видите у своих Delphi программ (и оно же является причиной, почему контекстные меню кнопок панели задач у Delphi приложений отличны от контекстных меню других программ). Когда вы сворачиваете или восстанавливаете свои формы в Delphi, внутренняя магия Delphi вклинивается в эти сообщения и вместо этого просто скрывает или показывает окна. Ваши формы на самом деле никогда по настоящему не минимизируются и не восстанавливаются в истинном смысле системы.

Давайте отвлечёмся на один момент для того, чтобы обсудить еще одну особенность Windows Vista. Мы скоро вернёмся к нашему Тайному Окну. Итак, эта новая возможность в Vista (она также является элементом индуктивного интерфейса) позволяет нам увидеть предпросмотр окна просто проведя мышью по кнопке приложения в панели задач. Это облегчает поиск нужной кнопки в панели задач, да и вообще смотрится, пожалуй, здорово. Та же техника используется и при прорисовке нового Flip 3D — 3D-представления классического экрана ALT+TAB. Если вы опробуете эти возможности на обычном, развёрнутом Delphi-приложении, то всё будет работать корректно. Однако, если вы попробуете повторить это со свёрнутым приложением, то увидите пустое окно с иконкой приложения в центре вместо нормального предпросмотра.

Почему наши Delphi программы так плохо себя ведут? Наверное, это какой-то заговор Microsoft? Нет! Это снова Тайное Окно! Когда вы двигаете мышью по кнопке панели задач и форма развёрнута, то в предпросмотре показывается содержание активного окна. Однако, когда все формы минимизированы, то скрытая “форма application” показывается на предпросмотре.

Теперь, давайте посмотрим, как мы можем исправить проблему! Мы пойдём способом, описанным Peter Below. Первое, что нам нужно сделать — избавиться от кнопки в таскбаре от нашей скрытой «формы application». В FormCreate нашего приложения мы должны поменять флаги нашей «формы application»:
Потом для каждой формы, для которой мы хотим иметь кнопку на панели задач (как минимум это будет главная форма), нам нужно переопределить CreateParams:
Наконец, для каждой формы, которая имеет кнопку в панели задач и может минимизироваться, нам надо обрабатывать оконное сообщение WM_SYSCOMMAND:
Это заблокирует внутренние механизмы Delphi, которые заменяют сворачивание и разворачивание формы на скрытие и показ. Теперь наши формы должны вести себя корректно. Они правильно анимируются при минимизации/восстановлении, и они правильно отображают свой предпросмотр.

Однако, у нас осталась ещё одна серьёзная проблема. Если мы запустим наш пример и нажмём Help/About, а потом щёлкнем по нашей кнопке в панели задач, то главная форма покажется поверх нашего диалога! Потому что, по-умолчанию, Delphi устанавливает невидимую форму приложения как родителя всем модальным формам. Чтобы исправить это, вы должны установливать Form.PopupParent перед каждым вызовом Form.ShowModal:
Скачать приложение-пример — шаг 3 (ссылка ведёт на статью-оригинал).

Пусть ваши приложения сияют

Если только вы не свалились с луны, то знаете, что приложения, запущенные под Windows Vista (на машинах с графическим 3D-акселератором), рисуются с полупрозрачными, стекло-подобными рамкой и неклиентской частью. Это называется, метко, Стеклом. В DWM (Desktop Windows Manager) есть API функции, которые помогут вам расширить поверхность Стекла внутрь клиентской области вашего приложения. Хотя это не всегда бывает нужно, но может иногда помочь вашему приложению больше вписываться в образ “Vista-программы”.

Мы начнём с того, что добавим несколько новых функций в наш файлик uVistaFuncs.pas: CompositingEnabled и ExtendGlass. Исходники функций основаны на этом коде. Функция CompositingEnabled возвращает вам, есть ли поддержка 3D возможностей для Стекла, а ExtendGlass позволяет вам расширить поверхность Стекла на клиентскую поверхность наших форм. Затем мы добавим панель снизу нашей формы. Это нужно из-за того, что API вызовы DWM для расширения Стекла требуют чёрной поверхности для рисования. Наконец, мы добавим метод в нашу главную форму, который будет проверять, доступно ли Стекло и, если да, то менять цвет панели на чёрнуй и расширять поверхность Стекла на нашей главной форме:

Windows Vista представляет новый элемент пользовательского интерфейса под названием Task Dialog. Он соединяет много различных диалогов в единый API для согласованнанности. Хотя с помощью Task Dialog API можно создать невероятно сложный диалог — мы начнём с простой замены для MessageDlg. Наш метод будет использовать Vista Task Dialogs, если они доступны, или же вызов старого MessageDlg, когда их нет. Здесь есть прекрасный пример того, как это сделать (бесплатный вариант компонентов Task Dialogs).

Как только мы добавили новый метод для использования Task Dialogs в наш модуль uVistaFuncs.pas, то одно простое изменение метода SaveHandled позволит нашему запросу как лучше соответствовать пользовательскому опыту в Vista, так и обеспечить более тщательную обратную связь с конечным пользователем.

Рисунок — это Всё


Мы почти добрались. Это изменение нам вообще-то следовало сделать давно — когда мы портировались с Windows 2000 до Windows XP. Нам нужно заменить наши плоские, пикселизованные значки в нашем приложении на красивые, сглаженные и, по возможности, с alpha-тенью. Я обнаружил, что наилучшим способом добиться этого является использование PngComponents и TPngImageList (прим. пер.: другой проект — TPNGImage — входит в состав Delphi, начиная с Delphi 2009). Простое изменение TImageList на TPngImageList позволит нам загружать PNG-картинки с alpha-каналом и использовать их в нашем приложении.

Новые общие диалоги

Windows Vista также представляет новые общие диалоги, включая переработанные диалоги открытия и сохранения. Эти новые диалоги включают в себя несколько новых возможностей Windows Vista, включая новую область ссылок избранное (её можно настраивать через щелчок правой кнопкой), новые виды и сворачиваемый диалог сохранения.

Mechanics of software

Programming is thinking, not typing

Локализация интерфейса и сообщений в приложениях .NET и Delphi

Не так давно в журнале уже затрагивалась тема локализации (см. «Мир ПК», №6/07, с. 68). В своей статье «Локализация приложений в Delphi для Win32» Михаил Перов рассказал о различных инструментах — коммерческих и бесплатных. Вернуться к сюжету мне пришлось по двум причинам: во-первых, хотелось бы описать непосредственно суть проблемы, вызвавшей появление ряда дополнительных инструментов, и, во-вторых, показать на примере, что разработчики вполне могут решить задачу своими силами.

В действительности технология локализации предлагается поставщиком как для среды разработки Microsoft Visual Studio.NET 2003/2005 (подгружаемые ресурсы), так и для CodeGear Delphi (Data Translation Wizard).

Основное неудобство штатных средств проявляется прежде всего при вовлечении в цикл локализации других исполнителей. В самом деле, вряд ли разработчики смогут самостоятельно сделать корректный перевод текста на несколько языков. Просить же далекого от программирования переводчика (а в заказных проектах зачастую ими являются ключевые пользователи) «набить текст», пользуясь средой Visual Studio или Delphi, не самая лучшая идея. Также всегда есть неприятные, хотя и преодолимые проблемы при локализации уже существующих приложений, где такая возможность не была предусмотрена изначально.

В связи с этим разработана простая, как нам кажется, но удобная с точки зрения контроля процесса технология локализации, подходящую как для автономных разработчиков, так и для небольших групп.

Локализация для .NET

Примечание: см. также более общий подход к локализации для .NET и Mono: gettext for .NET/Mono.

Ресурсы редактируются в удобной для переводчика табличной форме в среде MS Excel (рис. 1). Выбор Excel позволяет привлечь к переводу практически любого пользователя, однако при большом количестве задействованных людей, которым рассылаются файлы при децентрализованной работе, могут возникнуть другие проблемы: корректное слияние изменений, версии. Их можно решить, например, используя файл, размещенный на сервере SharePoint: в этом случае пользователь сам синхронизирует сделанные изменения через веб-сервис. При работе внутри сети предприятия возможно простое разделение доступа к файлу на сетевом диске или в системе управления исходным кодом (Visual SourceSafe, SVN и др.). То есть данная схема вполне может масштабироваться до небольших групп переводчиков, работающих в автономном режиме.

Рис. 1. Файл со строковыми ресурсами

  • 1 и 2 — таблица должна содержать как минимум две колонки: «Message» (идентификатор) и «Neutral» (значение по умолчанию). Идентификатор должен быть уникален для каждой строки.
  • 3 — таблица должна иметь название «Messages».
  • 4 — для локализации можно добавлять неограниченное число колонок с заголовком в виде «язык-страна», соответствующим значениям культур, поддерживаемых платформой.NET.
  • Пустые ячейки: будет использовано значение из колонки «Neutral», соответственно эта колонка должна быть заполнена всегда.

Далее, исходный Excel-файл обрабатывается утилитой, генерирующей ресурсные файлы для платформы .NET. Файлы включаются в проект разработчиком, компилируются как встроенные ресурсы (embedded resource) и затем с использованием небольшой вспомогательной библиотеки классов загружаются в приложение с минимальным написанием программного кода (рис.2).

Рис. 2. Схема локализации для .NET

Чтобы избежать коллизий при наличии нескольких исходных файлов, с которыми работают разные сотрудники, рекомендуется придерживаться именования, соответствующего проекту, например

Для генерации используется утилита ResourceMaker, конвертирующая файл Excel во множество файлов .NET с расширениями *.resx. Для обеспечения минимального уровня автоматизации утилита запускается из командной строки с параметрами:

Рекомендуется использовать имя файла ресурсов (BaseName) «Messages», чтобы в дальнейшем при использовании строковых ресурсов в приложении уменьшить количество необходимого для этого кода.

Утилита генерирует один или более файлов *.resx для каждого определенного вами языка в формате: . resx для значений по умолчанию (neutral), . ru-Ru. resx для русского, . fr-Fr. resx для французского и т. д.

Далее вам нужно включить эти ресурсы в проект приложения и перестроить его, после чего они будут готовы к использованию.

Для удобной работы с ресурсами применяется небольшая библиотека Arbinada. Utils. Localizer. Вам необходимо скомпилировать эту сборку и добавить на нее ссылку в вашем проекте. Чтобы просто извлечь строку по ее идентификатору, используйте следующий код:

Чтобы избежать написания большого количества однообразного кода, для локализации визуальных элементов (текст — labels, опции — checkboxes и т. д.) в ваших веб-формах или пользовательских элементах управления (user controls) вы можете использовать класс WebFormLocalizer внутри события Page_Load:

Этот фрагмент программы меняет текст (caption) у элементов веб-формы по их идентификатору (WebControl. ID) на соответствующий, найденный в ресурсах. В прилагаемом к статье примере поддерживаются элементы типов: Label, CheckBox, LinkButton, Button и DataGrid.

Для DataGrid используется трехуровневая сигнатура для идентификатора ресурса:

Поддерживаются BoundColumn и TemplateColumn. Для ButtonColumn суффикс может принимать значения Edit, Cancel и Update. Более подробно вы можете посмотреть в исходном тексте файла WebFormLocalizer.cs.

Локализация для Delphi

Технология не имеет принципиальных отличий, она была успешно адаптирована для Delphi 2007 Win32 (рис. 3).

Рис. 3. Схема локализации для Delphi

Как видно из приведенной схемы, непосредственной компиляции в ресурсы Windows-приложения не происходит. Вместо этого мы используем XML-файлы, содержащие метаинформацию об используемых языках и собственно переведенные строки (рис.4, 5).

Рис. 4. Метаинформация об используемых языках локализации

Рис. 5. Строковые ресурсы

Вместо написания нескольких строк текста выбираем в палитре компонент TA3FormLocalizer и в качестве источника назначаем ему LocalizerStore (рис.6).

Рис. 6. Локализация формы в Delphi. Просто «кидаем компонент».

В самом приложении необходимо только проинициализировать хранилище локализованных данных.

После запуска приложение показывает информацию на выбранном языке (в примере используются текущие настройки локализации Windows для пользователя).

Рис. 7. Локализованное Delphi-приложение

Взяв исходные тексты (файл A3Localization. pas), вы сможете изучить имеющиеся возможности по локализации широкого круга VCL-компонентов (стандартные элементы управления форм, сетки, компоненты доступа к БД TDataSet с локализацией на уровне названий полей, TActionList и другие). При необходимости в подсистему легко добавить недостающую функциональность, например по локализации ваших собственных компонентов, на основе механизма информации о типах времени выполнения (RTTI — runtime type information), не меняя статической связанности модулей.

Исходные тексты

Zip-архивы, содержащие примеры локализации для веб-приложения .NET и Delphi-приложения под Windows, вы можете скачать по ссылке в конце страницы или на прилагаемом к журналу диске.

Сергей Тарасов, октябрь 2005. Декабрь 2007 (с добавлениями).

Многоязыковая поддержка в Delphi

Содержание статьи

Всё чаще и чаще наши разработчики представляют свои программные продукты всему миру. Это не только дает возможность нашим соотечественникам хорошо заработать, но и ставит перед ними задачу разработки модуля многоязычной поддержки. Я уверен, что, например, англичанин явно не будет изучать русский или, тем более, украинский что бы понять, что написано на кнопках управления в популярной отечественной программе. Приходим к выводу, что реализация многоязычной поддержки далеко не последнее дело в процессе создания программы, от которого зависит её популярность.

Этой достаточно актуальной проблеме я и посвящаю статью, ставя перед собой следующую задачу: создать программный код, который бы не сильно влиял на размер программы и позволял осуществлять перевод заголовков элементов управления продукта на другие иностранные языки без вмешательства разработчика программы и ее повторной компиляции при добавлении нового языка.

Как это делают другие?

Я решил всерьез заняться вопросом поиска оптимального алгоритма и, прежде всего, захотел узнать, какой формат имеют языковые модули известных программ. Для изучения была выбрана программа «Архивариус 3000». В каталоге программы оказалась папка Languages с файлами: Ukrainian.txt, Latvian.txt. Открыв файл Ukrainian.txt, я увидел типичную структуру ini файла. Приведу пример одной из строк файла:

Как можно предположить SFormAbout – это название кнопки, а «Про программу» – её заголовок. То есть структура файла имеет вид:

где Name – имя компонента, а Caption – заголовок компонента. Что нам мешает попробовать также организовать Russian.txt и English.txt для своей программы?

Этим мы и займёмся, максимально автоматизировав все процессы.

Программирование

Итак, создадим кнопку и назовём её CNew. При её нажатии:

TStringList — объект подобный TMemo, только не VCL (не имеет графического представления), поэтому он не сильно влияет на размер программы. Строка f:=TStringList.Create; — инициализирует переменную f и присваивает ей тип. Так как на форме находится только BNew в сохранённом файле NewLang.txt будет только одна строка:

Напишем следующую функцию:

В параметр ей передаётся строка, в которой присутствует знак «=». Результат функции – текст, содержащийся после знака = . То есть, если параметр k имеет значение CNew=Кнопка , то результатом функции будет строка: Кнопка . Создайте AComboBox1, задайте Items[1]=Russian и Items[2]= English (имена языковых файлов). Создайте событие OnChange для этого объекта и напишите следующий код:

Илон Маск рекомендует:  option в HTML

Теперь мы должны согласиться с таким правилом: если при изменении языка у компонента должно изменится поле Caption, то Name компонента должен начинаться с символа C , если меняется Text – с символа T . Например, создадим на форме кнопку CButton1, CButton2, CButton3, метку CSample, опцию CheckBox и поле TSample. Из всех этих компонентов только поле имеет параметр Text, поэтому его имя начинается на T .

Как вы, наверное, уже заметили, TComboBox мы назвали AComboBox1. Это необходимо для того, что б при смене языка ни Caption (которого у этого компонента вообще нет), ни Text не менялись.

Дальше нажмите кнопку BNew – создастся файл NewLang.txt, переименуйте его в Russian.txt и создайте ещё один такой же English.txt. Содержимое этих файлов должно быть следующим:

Измените содержимое Russian.txt:

Как вы уже поняли, мы пишем перевод после знака = . Теперь запустите программу и в ComboBox`e выберите English – язык интерфейса изменится:

Выбрав Russian, результат будет следующий:

Кнопка создания нового языка, как вы понимаете, не обязательна. Но она удобна в процессе отладки программы. Поэтому, когда вы завершите свой проект – смело её удаляйте.

Как всё работает

Доступ к компоненту на форме можно получить, используя функцию Form1.Components[b] , где b – номер компонента на форме. Всего таких компонентов на форме Form1.ComponentCount. При сохранении в файл NewLang.txt, номер строки соответствует номеру компонента на форме. Тогда, при смене языка, нужно определить что менять b-тому компоненту и на что менять. Что менять узнаём из имени, а на что – считывая b-ю строку файла с этим языком. Заметьте, что при считывании очень важен порядок, и если вместо:

то текст метки будет «Создать новый язык». Поэтому называть компоненты необходимо так, что бы при создании файла языка было ясно, какой элемент будет носить присвоенный нами ему заголовок.

Процесс локализации приложения Delphi 2009 добровольными переводчиками?

У меня есть бесплатное научное приложение, которое используется тысячами людей в почти 100 странах. Многие предложили перевести бесплатно. Теперь, когда D2009 делает это проще (с интегрированными и внешними инструментами локализации, а также с поддержкой поддержки Unicode), я хотел бы, чтобы это произошло на нескольких языках и неуклонно добавляло столько, сколько будет поддерживать пользовательская энергия.

Я думаю, что я буду распространять электронную таблицу со списком строк (десятки, но не сотни) для перевода, вернуть их и сравнить материалы на одном и том же языке от 2-3 пользователей, а затем работать для решения расхождения по консенсусу. Затем я включу локализацию, используя интегрированную среду перевода, и распространю локализованные обновления.

Кто-нибудь делегировал перевод пользователям? Любые ошибки, D2009-конкретные или иначе?

EDIT: Кто-нибудь сравнивал поддержку локализации, встроенную в D2009, в сравнении с dxgettext?

Я никогда не был другом запатентованных инструментов локализации для приложений Freeware или Open Source. Используя dxgettext, порт Delphi GNU gettext выглядит намного лучше для меня:

  • Интеграция в программу (даже намного позже ее разработки) проста.
  • Извлечение переводимых строк может выполняться программами командной строки и поэтому легко вводится в автоматическую сборку.
  • Новый перевод может быть добавлен просто путем создания нового каталога с правильной структурой, копирования пустого файла перевода в него и начала перевода строк. Это то, что каждый пользователь может сделать для себя, нет необходимости привлекать оригинального автора для создания нового перевода. С этим процессом также выполняется мгновенное удовлетворение. После перезапуска программы новые переводы отображаются сразу.
  • Изменение существующего перевода еще проще, чем создание нового. Таким образом, если пользователь находит правописание или другие ошибки или потребности в улучшении перевода, они могут легко их исправить и отправить изменения автору.
  • Новые версии программ работают со старыми переводами, система деградирует очень изящно — новые и нетранслируемые строки просто отображаются немодифицированными.
  • Переводы могут выполняться только с помощью блокнота, но есть несколько бесплатных инструментов для создания и управления файлами перевода; см. ссылки на странице dxgettext. Они локализованы и имеют некоторые преимущества по сравнению с таблицей:
    • Можно указать расположение строк в исходном коде (имеет смысл только для приложений с открытым исходным кодом).
    • Отображается процент переведенных строк.
    • Модификации уже переведенных строк также выделены.
  • Вся система зрелая и перспективная — я использовал dxgettext для программ Delphi 4, и не должно быть никаких изменений, необходимых для Delphi 2009 — файлы перевода всегда кодировались в кодировке UTF-8.

Использование электронной таблицы для перевода не представляется приемлемым решением для меня, когда у вас есть несколько языков. Предположим, новая версия программы добавляет две новые строки и изменяет только 10 строк — вам не нужно будет добавлять новые строки и выделять измененные строки во всех десятках файлов электронных таблиц и отправлять их снова вашим переводчикам? Используя dxgettext, вы просто отправляете измененный po файл всем им.

Edit:

Есть интересные комментарии о проблемах с dxgettext и библиотеками. Я никогда не испытывал этого, так как я полностью прекратил использование строк ресурсов. Большая часть наших программ находится на немецком языке, и лишь немногие из них переведены на английский язык или переведены на несколько языков.

Наши внутренние библиотеки используют «_ (. )» вокруг всех переводимых строк. Существуют определения ENGLISH и USEGETTEXT , которые задаются для каждого проекта. Если определены ENGLISH или USEGETTEXT , тогда английские тексты будут скомпилированы в DCU, иначе немецкий текст будет скомпилирован в DCU. Если USEGETTEXT не определен, то «_()» скомпилируется как функция, которая возвращает свой параметр as-is, иначе используется поиск перевода dxgettext.

Перевод в delphi приложениях

Данная статья показывает, как можно перевести на русский язык строки, заголовки которых недоступны для “простого присваивания”, например заголовки окна функции MessageDlg.

Вы создали свое приложение, форму, в вашей программе все или почти все заголовки строк на русском. И наверняка вы используете такую функцию, как MessageDlg.

Рассмотрим функцию:
Не знаю, как вам, но для меня «Ошибка чтения файла! Продолжить?» на фоне заголовка «Warning» и кнопок «Yes» и «No» смотрится “не по-русски”.

Delphi добрую массу строковых констант берёт из модуля Consts. Для реализации перевода соответствующего модуля необходимо сделать следующее:

Открыть через Delphi файл Consts.pas. Лучше всего это сделать так: создайте пустое приложение, в разделе uses пропишите модуль Consts и, удерживая клавишу Ctrl, кликните мышью прямо по слову Consts – откроется файл Consts.pas из папки …BORLAND\DelphiX\Source\Vcl примерно следующего содержания: В разделе resourcestring файла Consts.pas перевести на русский язык те строки, которые вам необходимы. Можете перевести все, если хотите.
Сохраните копию Consts.pas и пустое приложение вместе в отдельной папке.
Обязательно подключите модуль Consts.pas(если вы его не подключили) к сохранённому приложению и сохраните приложение ещё раз.
Обратите внимание: приложение должно использовать модуль Consts.pas, сохранённый вами вместе с самим приложением, а не из папки …\DelphiX\Source\Vcl. Чтобы убедиться в этом, закройте страницу Consts.pas, затем, удерживая Ctrl, кликните мышью в разделе модулей по слову Consts – должен открыться файл Consts.pas непосредственно из того места, где вы его сохранили.
Запустите приложение. После того, как вы его запустили, в папке с приложением должен появиться файл Consts.dcu.
В папке с сохранённым приложением у вас помимо прочих файлов типа Unit1.pas или project1.res должны быть следующие: Consts.pas и Consts.dcu.
Если вы хотите, чтобы перевод на русский действовал только в данном приложении, то вам больше ничего делать не нужно, т.е. достаточно одного только их присутствия в папке данного приложения.

Если же вы хотите, чтобы перевод коснулся всех приложений, то:
– файл Consts.pas вам необходимо скопировать поверх уже имеющегося в папку …\BORLAND\DelphiX\Source\Vcl
– файл Consts.dcu в папку …\BORLAND\DelphiX\Lib поверх уже существующего.

Возможно, вышеперечисленный процесс можно и упростить, но так, по крайней мере, делал я. Уже переведённый мною файл Consts.pas вы можете скачать здесь.

Если вы хотите, чтобы модули вашего производства использовались всеми приложениями Delphi, то файлы вашего модуля x.pas и x.dcu, где x – название вашего модуля, необходимо сохранить в папках:
…\BORLAND\DelphiX\Source\Vcl
…\BORLAND\DelphiX\Lib
соответственно.

То же, что и с модулем Consts, можно выполнять и с другими модулями. Вот, собственно и всё. В результате вы получите переведённый на русский язык ряд диалоговых заголовков, предупреждений и кнопок, генерируемых самим Delphi.

Библиотека Интернет Индустрии I2R.ru

Малобюджетные сайты.

Продвижение веб-сайта.

Контент и авторское право.

Многоязычный интерфейс приложений в Delphi

Наверняка, вам хоть раз в жизни приходилось разрабатывать многоязычное приложение. Например, вам нужно, чтобы ваше приложение «ругалось» как на английском, так и на русском языке. В таком случае, обычно, один язык встраивается в приложение, как правило, английский, а потом пользователю предоставляется возможность выбрать язык интерфейса программы.

Для этих целей существует много коммерческих и бесплатных компонент-переводчиков, однако использовать их довольно неудобно, поскольку, необходимо помещать копию компонента на каждую форму приложения. Я предлагаю совершенно другой подход, а именно — использовать модуль-переводчик, который будет переводить все формы приложения. При достаточно высокой скорости перевода интерфейса, размер программы увеличиться всего на 3Кб (именно столько «весит» модуль).

Алгоритм работы такой: функция TranslateForm обходит все компоненты формы и переводит их на указанный язык, используя для этого специальный словарь. Словарь имеет формат Ini-файла, поэтому, как и для всех остальных Ini-файлов, для этого файла существует ограничение размера — не более 64 Кб, если я, конечно, не ошибаюсь. Решить эту проблему можно достаточно просто — использовать несколько словарей для разных языков.

Приведу раздел объявления нашего модуля (interface):

interface
uses SysUtils, Classes, Controls, Forms, Dialogs, Quickrpt, . ;
function Translate(Text : string; Lang : string; Dict : TIniFile):string;
procedure TranslateForm(Form : TForm; Lang : string; DictFileName : string);

Процедура TranslateForm, как я уже писал, обходит все компоненты формы, а функция Trasnlate — выполняет перевод. Переводятся текстовые свойства компонент, например, Caption и Hint. При вызове функции нужно указать следующие параметры:

Form : TForm; Lang : string; DictFileName : string

Параметр Form определяет форму, которую нужно перевести. Параметр Lang — это язык на который нужно перевести свойство компонента. Тот язык, с которым работает программа в данный момент, будем называть ключевым. Подразумевается, что в данный момент (до перевода) программа работает с ключевым языком, потому что поиск (перевод) слов будет произведен с использованием ключевого языка. Чтобы было понятнее, приведу пример словаря:

[Rus]
File=Файл
Open=Открыть
Translate=Перевести
Application=Приложение
New=Создать
Open=Открыть
Text=Текст
Save=Сохранить
Save As. =Сохранить как.
Print=Печать
Print Setup=Параметры печати
Exit=Выход
Edit=Правка
Cut=Вырезать
Copy=Копировать
Paste=Вставить
Undo=Отмена
View=Вид
Status bar=Панель состояния
Tool bar=Панель инструментов
Tools=Сервис
Settings=Параметры
.

Для перевода интерфейса приложения с английского на русский язык нужно вызвать процедуру TrasnlateForm так:

TranslateForm(Form1, ‘Rus’, ‘trans.dic’);

При этом ключевым языком считается английский (см. секцию Rus в примере 2). Аналогично можно создать секцию Eng и использовать русский язык в качестве ключевого. Для того, чтобы перевести все формы приложения используйте следующие операторы:

for i:=0 to Screen.FormCount-1 do
TranslateForm(Screen.Forms[i],’Rus’,’trans.dic’);

Если вы хотите изменить язык приложения во время его запуска, отредактируйте файл проекта так:

for i:=0 to Screen.FormCount-1 do
TranslateForm(Screen.Forms[i],’Rus’,’trans.dic’);
Application.Run;

То есть перевод форм нужно выполнить до выполнения метода Application.Run;

Теперь рассмотрим весь исходный код модуля-переводчика:

Пример 3. Файл trans.pas

uses SysUtils, Classes, Controls, Forms, Dialogs, Quickrpt, QRCtrls, StdCtrls,
Buttons, ComCtrls, ExtCtrls, DBCtrls, DB, DBGrids, Menus, Grids, Mask,
IniFiles;

function Translate(Text : string; Lang : string; Dict : TIniFile):string;
procedure TranslateForm(Form : TForm; Lang : string; DictFileName : string);

< Непосредственный перевод текста >
function Translate(Text : string; Lang : string; Dict : TIniFile):string;
var s : string;
begin
Result:=Text;
S:=Dict.ReadString(Lang, Text, »);
if S=» then Dict.WriteString(Lang, Text, »);
if S<>» then Result:=S;
end;

procedure TranslateForm(Form : TForm; Lang : string; DictFileName : string);
var Dict : TIniFile;
I,J : Integer;
Obj : TObject;
begin

if not fileexists(DictFileName) then
ShowMessage(‘No exists’ + DictFileName);

Form.Caption:=Translate(Form.Caption, Lang, Dict);
Application.Title:=Translate(Application.Title, Lang, Dict);

Obj:=Form.Components[i];
if Obj is TMenuItem then
begin
TMenuItem(Obj).Caption:=Translate(TMenuItem(Obj).Caption, Lang, Dict);
TMenuItem(Obj).Hint:=Translate(TMenuItem(Obj).Hint, Lang, Dict);
end;

if Obj is TButton then
begin
TButton(Obj).Caption:=Translate(TButton(Obj).Caption, Lang, Dict);
TButton(Obj).Hint:=Translate(TButton(Obj).Hint, Lang, Dict);
end;

if Obj is TBitBtn then
begin
TBitBtn(Obj).Caption:=Translate(TBitBtn(Obj).Caption, Lang, Dict);
TBitBtn(Obj).Hint:=Translate(TBitBtn(Obj).Hint, Lang, Dict);
end;

if Obj is TSpeedButton then
begin
TSpeedButton(Obj).Caption:=Translate(TSpeedButton(Obj).Caption, Lang, Dict);
TSpeedButton(Obj).Hint:=Translate(TSpeedButton(Obj).Hint, Lang, Dict);
end;

if Obj is TPanel then
begin
TPanel(Obj).Caption:=Translate(TPanel(Obj).Caption, Lang, Dict);
TPanel(Obj).Hint:=Translate(TPanel(Obj).Hint, Lang, Dict);
end;

if Obj is TGroupBox then
begin
TGroupBox(Obj).Caption:=Translate(TGroupBox(Obj).Caption, Lang, Dict);
TGroupBox(Obj).Hint:=Translate(TGroupBox(Obj).Hint, Lang, Dict);
end;

if Obj is TLabel then
begin
TLabel(Obj).Caption:=Translate(TLabel(Obj).Caption, Lang, Dict);
TLabel(Obj).Hint:=Translate(TLabel(Obj).Hint, Lang, Dict);
end;

if Obj is TStaticText then
begin
TStaticText(Obj).Caption:=Translate(TStaticText(Obj).Caption, Lang, Dict);
TStaticText(Obj).Hint:=Translate(TStaticText(Obj).Hint, Lang, Dict);
end;

if Obj is TQRLabel then
begin
TQRLabel(Obj).Caption:=Translate(TQRLabel(Obj).Caption, Lang, Dict);
TQRLabel(Obj).Hint:=Translate(TQRLabel(Obj).Hint, Lang, Dict);
end;

if Obj is TEdit then
TEdit(Obj).Hint:=Translate(TEdit(Obj).Hint, Lang, Dict);

if Obj is TMaskEdit then
TMaskEdit(Obj).Hint:=Translate(TMaskEdit(Obj).Hint, Lang, Dict);

if Obj is TMemo then
TMemo(Obj).Hint:=Translate(TMemo(Obj).Hint, Lang, Dict);

if Obj is TRadioGroup then
begin
TRadioGroup(Obj).Caption:=Translate(TRadioGroup(Obj).Caption, Lang, Dict);
TRadioGroup(Obj).Hint:=Translate(TRadioGroup(Obj).Hint, Lang, Dict);
for J:=0 to TRadioGroup(Obj).Items.Count-1 do
begin
TRadioGroup(Obj).Items[j]:=Translate(TRadioGroup(Obj).Items[j], Lang, Dict);
end;
end;

if Obj is TCheckBox then
begin
TCheckBox(Obj).Caption:=Translate(TCheckBox(Obj).Caption, Lang, Dict);
TCheckBox(Obj).Hint:=Translate(TCheckBox(Obj).Hint, Lang, Dict);
end;

if Obj is TField then
TField(Obj).DisplayLabel:=Translate(TField(Obj).DisplayLabel, Lang, Dict);

if Obj is TTabSheet then
begin
TTabSheet(Obj).Caption:=Translate(TTabSheet(Obj).Caption, Lang, Dict);
TTabSheet(Obj).Hint:=Translate(TTabSheet(Obj).Hint, Lang, Dict);
end;

if Obj is TOpenDialog then
TOpenDialog(Obj).Title:=Translate(TOpenDialog(Obj).Title, Lang, Dict);

if Obj is TSaveDialog then
TSaveDialog(Obj).Title:=Translate(TSaveDialog(Obj).Title, Lang, Dict);

if Obj is TPrintDialog then
TPrintDialog(Obj).Title:=Translate(TPrintDialog(Obj).Title, Lang, Dict);

if Obj is TPrinterSetupDialog then
TPrinterSetupDialog(Obj).Title:=Translate(TPrinterSetupDialog(Obj).Title, Lang, Dict);

Естественно, перед использованием модуля его нужно добавить в оператор uses:

1. Теперь нужно отметить особенность функции Translate. Если слова нет в словаре, она его автоматически добавляет. Потом вам только останется самому ввести перевод этого слова!

2. Напомню, что поиск словаря, так как он является ini-файлом, по умолчанию производится в каталоге C:\Windows (точнее, в каталоге, возвращаемом функцией GetWindowsDirectory), поэтому предварительно нужно поместить туда словарь или явно указать имя файла. При этом удобно использовать функцию ExtractFileDir так:

3. Исходный код модуля-переводчика может распространятся согласно положениям лицензии GPL, текст которой вы можете прочитать на моем сайте — http://dkws.narod.ru/.

Посмотрим, что у нас вышло, как говорится, «до» (см. рисунок 1) и «после» (см. рисунок 2).

Delphi/Перевод переменных

Переменные можно перевести из одного типа в другой. Например, нужно в компоненте Edit отобразить число. Чтобы, изменить текст в Edit’e, нужно изменить его свойство Text. Что написано в Text, то отобразится в самом Edit’e. Тип свойтсва Text — string. Как отобразить число в Edit’e? Все очень просто. Существует команда IntToStr . Давайте мы её разберем.

Чтобы изменить свойство Text, нужно его «назвать». Общий вид вызова свойства какого-либо компонента имеет вид:

Теперь напишем простую программу, которая переводит переменную типа integer в тип string.

А как отобразить дробное число в Edit’e? Также как с целым числом, только команда другая — FloatToStr . Напишем такую же программу, только вместо integer — real.

Теперь усложним нашу программу — теперь она будет складывать числа в 2-х Edit’ах, а показывать результат в Edit 3-й. У вас появился вопрос: «Как сложить два числа из Edit’a?» Нужна обратная команда — StrToInt , она переводит string в integer.

Но мы поступили хитро — мы не использовали ни одной переменной. Можно было использовать их, но так было сложней. И напоследок про команду — StrToFloat , такая же как предыдущая, только вместо integer — real.

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL