Motto

В тихом саду здравомыслия
Пусть на вас постоянно падают
кокосовые орехи пробужденности.
Чогьям Трунгпа РИНПОЧЕ


Версия для мобильного


понедельник, 6 июня 2011 г.

Переход на юникод 2. План перехода и сторонние библиотеки.

Как я уже писал, я выбрал для перехода стратегию, требующую того, чтобы код приложения собирался как в Delphi 6, так и в Delphi 2010. Эта стратегия была выбрана как наиболее универсальная и позволяющая в любой момент переключиться на стратегию 3 и продолжить работу с копией кода программы заточенной только под одну юникодную версию Delphi.

Исследование ситуации

Итак, начинать надо с пакетов. Без них всё-равно не собрать программу. Первым делом я запустил Lazy Delphi Builder, просканировал папки с исходниками и стал пробовать компилировать каждый из пакетов, поочерёдно выписывая в блокнот имена пакетов, отказывавшихся собираться на Delphi 2010. Получился первый список проблемных пакетов. Конечно, на самом деле я не компилировал каждый из пакетов. Ведь понятно, что если пакет X не скомпилировался, то и все пакеты, которые зависят от пакета X также не компилироваться не будут.

Большая часть самописных библиотек зависела от сторонних библиотек, так что переход на юникод надо было начинать со сторонних либ.

Общий план перехода

  1. Обновить все библиотеки от сторонних производителей.
  2. Добиться, чтобы программа стабильно работала на Delphi 6 после завершения работы над первым пунктом.
  3. Если сторонние пакеты больше не поддерживаются, перевести их на юникод собственноручно или заменить аналогами поддерживающими юникод.
  4. Добиться, чтобы программа компилировалась и стабильно работала после завершения работы над третьим пунктом.
  5. Сделать необходимые изменения в коде самописных пакетов, чтобы они могли собираться как в Delphi 6 так и в Delphi 2010 и продолжали стабильно работать в Delphi 6.
  6. Сделать необходимые изменения в коде приложения, чтобы его можно было собрать и в Delphi 6 и в Delphi 2010.
  7. После сборки в Delphi 2010 протестировать работу, и начать исправлять ошибки связанные с переходом на Delphi 2010. При каждом исправлении проверять, что приложение собирается и работает и 6й и в 2010й версии Delphi.

Сторонние библиотеки

Из сторонних библиотек у меня использовались:

  • FastMM – быстрый менеджер памяти от Использовалась одна из последних версий. С ней проблем не будет.
  • JCL и JVCL – использовались мало, периодически обновлялись.
  • Virtual Treeview – использовалась в паре утилит.
  • Open XML 3.1 (XmlDom) – библиотека для работы с XML.
  • FastCode – масса очень сурово оптимизированных функций.
  • kbmMemTable – шустрая реализация in-memory dataset-a. Последняя бесплатная версия была только для Delphi 6.
  • Ararat Synapse – работа с сетью.
  • ThemeManager – поддержка Windows тем в версиях Delphi младше 7.
  • AlphaSkins – красивые контролы с поддержкой скинов. Использовалась версия 6.4.
  • старенькая RxLib
  • Ehlib – очень хороший DbGrid и набор Db-контролов. Использовалась бесплатная для ex-USSR версия 3.6. Об обновлении до версии 5.x я напишу отдельно.
  • Quick Report – генератор отчётов. Использовалась версия поставляющаяся с Delphi 6. QReport использовался в паре мест в основном для сохранения совместимости со старыми версиями программы. К моменту перехода, все основные отчёты были переведены на Fast Report.
  • FibPlus – работа с БД Firebird. Версия 6.8.5 выпущенная до введения поддержки юникода.
  • Altium Dream VCL – дизайнер форм и скриптовый движок. Проект перестал поддерживаться в 2003 году. Сейчас даже сайта не осталось.
  • Fast Report – лучший генератор отчётов. Использовалась одна из последних версий (4.x).

Обновление сторонних библиотек

Theme Manager и FastCode

Theme Manager не нужен в Delphi 2010. А FastCode просто не существует для 2010й версии. Так что было решено их убрать. Кода использующего эти библиотеки мало. Для FastCode - это просто запись в секции uses проекта. А для Theme Manager это один компонент на весь проект. Для начала, компонент TThemeManager был убран с формы и его создание было вынесено в код (Runtime). Весь код использующий FastCode и ThemeManager был окружен директивами компилятора:

{$IFDEF VER140} 
// всё что находится внутри IFDEF блока, будет компилироваться только в Delphi 6. 
{$ENDIF}

Jcl, JVCL, Virtual Treeview, SynapseLib, Fastmm

C FastMM, SynapseLib, Virtual TreeView, jcl, jvcl проблем не было. Эти библиотеки были обновлены до последней версии без особых приключений. Кое-где пришлось подкорректировать код, в связи с изменившимися типами данных или объявлениями методов, но таких коррекций было немного и затронули они только Virtual TreeView и JVCL.

XmlDom 3 –> Adom 5

Тут мы с коллегами обсуждали что лучше, избавится от этой библиотеки, переписав код так, чтобы использовалась что-нибудь стандартное или обновить. Решили попробовать обновить до последней версии, и вернуться к обсуждению если при обновлении возникнут серьёзные проблемы. Проблем не было.

Сейчас эта библиотека называется Adom. Изменились названия некоторых методов, и имена всех юнитов. На время обновления была оставлена возможность собирать проект как с использованием XmlDom 3, так и с Adom 5, с помощью тех же директив компилятора. В данном случае код использующий эту библиотеку был окружен директивой {$IFDEF I_WANT_ADOM}.

Код uses части модулей использующих эту библиотеку выглядел примерно так:

uses
  {$IFDEF I_WANT_ADOM}
  dkADomCore,
  {$ELSE}
    {$IFDEF VER140}
    XDOM_3_1,
    {$ENDIF}
    {$IFDEF VER210}
    {$Message Fatal 'Cannot compile for delphi 2010 without I_WANT_ADOM directive!'}
    {$ENDIF}
  {$ENDIF}

Alpha Skins

Alpha Skins пришлось обновить до 7й версии. После обновления возникла пара проблем, связанных с тем, что одно из свойств стало вести себя немного по-другому. Но все проблемы были разрешены в течение одного дня.

На самом деле мне пришлось обновлять AlphaSkins дважды. Я использую бесплатную версию компонентов AlphaSkins, которая поставляется без исходников. Сначала я просто скачал и установил последнюю доступную (7.21) версию для Delphi 2010, в 6й Delphi оставив версию 6.4. Между тем как я установил версию 7.21 и начал с ней разбираться прошло некоторое время. Но в процессе компиляции оказалось, что у компонента TsSkinManager изменились названия пары свойств а один из модулей был переименован. Пришлось обновлять и версию для Delphi 6. И тут оказалось, что за прошедшее время вышла следующая версия Alpha Skins, а версию 7.21 больше никак не скачать, ни для D6 ни для D2010. Так что пришлось дважды скачивать последнюю версию для двух версий Delphi. Всё-таки, всегда лучше иметь компоненты с полными исходниками.

RxLib

RxLib - тут был выбор, либо обновиться до последней версии RxLib с поддержкой юникода, либо перейти на JVCL. Аккуратно взвесим за и против было решено переходить на JVCL. О переходе с Rx-ов на JVCL я напишу отдельно.

kbmMemTable

Так как бесплатная версия существовала только для Delphi 6, а новые версии стали платными, решили просто избавиться от неё. Тем более что использовался этот компонент всего в паре мест. Оставалось выбрать другой датасет для замены. Сначала я хотел заменить на стандартный ClientDataset, но в одном месте столкнулся со странной ошибкой парсера ClientDataset-a. После этого kbmMemTable был заменён на JvMemoryData (пришедший в JVCL из RxLib). Из нестандартных фич kbmMemTable использовалась только опция сохранения и загрузки датасета в файл в формате CSV. Для эмуляции такого поведения был написан свой собственный класс, умеющий загружать и сохранять датасет в CSV формат, совпадающий с форматом kbmMemTable.

Fast Report 4

Fast Report - с ним проблем не было. Существующая подписка позволяла получить версию поддерживающую и Delphi 6 и Delphi 2010.

FibPlus

FibPlus тоже пришлось обновлять практически в первую очередь. Вся работа с БД завязана на них. Хотя и скрепя сердце. Всё-таки платить 350$ в год, за библиотеку, у которой в год выходит всего одно-два обновления, как-то не комильфо.

Quick Report

В Delphi 2010 его просто нет. А так как он сохранялся в проекте только для улучшения обратной совместимости со старыми версиями программы, было решено не тащить этот код в юникодную версию программы. С ним поступили так же как с ThemeManager-ом. Все компоненты Quick Report были удалены с форм и стали создаваться в коде. А этот код был окружен директивами {$IFDEF VER140}. Дело облегчалось тем, что тот код, использующий Quick Report уже был вынесен в отдельный package, использование которого отключалось всё той же директивой. Вообще, если быть более точным, то для отключения поддержки QuickReport, я завёл свою собственную директиву, чтобы было проще отключать подключать поддержку QR вручную.

Dream VCL

Больше всего проблем доставило обновление DreamVCL. В качестве замены Dream-ам была куплена библиотека TMS Advanced Scripter Pro. И именно замена Dream-ов на TMS Scripter Pro съела больше всего времени. Подробнее о поиске библиотеки для замены, читайте в следующем посте "Переход с DreamVCL на TMS Scripter Pro".


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

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

  1. А не могли бы Вы выложить бесплатные компоненты, которые уже невозможно скачать: Dream VCL, kbmMemTable?

    ОтветитьУдалить
  2. Кирилл

    kbmMemTable должна быть доступна для скачивания после регистрации на офф-сайте http://www.myc4d.com

    Dream VCL - не имею права выкладывать. К слову, это не бесплатная библиотека.

    ОтветитьУдалить
  3. У нас используется TMS ScripterStudio уже лет 8, достаточно стабильная вещьо. Для .NET тоже решили от них использовать компоненты, хуже API я не видел, дешево и очень сердито.

    ОтветитьУдалить
  4. Анонимный7 июня 2011 г., 9:14

    Если я не ошибаюсь, то kbmMemTable входит в бесплатную kbmMW CodeGear Edition, но без *.pas

    ОтветитьУдалить
  5. Вообще у меня предубеждение к продукции TMS. Вызвано оно тем, что даже демки у них на сайте часто падают с AV.
    TMS Scripter Studio Pro мы решили дать шанс. Эта библиотека очень хорошо работает если использовать её так, как её задумал автор. Но при попытке расширить функционал или использовать нестандартно постоянно натыкаешься на то что многие нужные методы скрыты в private и перекрыть их в наследнике невозможно.

    ОтветитьУдалить
  6. Анонимный8 июня 2011 г., 17:12

    К TMS претензий всегда было много:
    юниты по мегабайту
    в каждом компоненте можно найти одни и те же куски кода
    комментарии на испанском или ещё каковском
    местами попросту уродский код

    Всё, конечно, субьективно.

    ОтветитьУдалить
  7. Мочить так мочить, вот вырезка из описания TMS FlexCell API:
    Now, something that might be a little unexpected if you are not aware of, is that we
    decided to provide that functionality in a few very powerful and overloaded methods,
    instead of a million standalone methods.

    ОтветитьУдалить
  8. А чем RemObjects PascalScript не угодил? В силу использования в InnoSetup должен быть весьма надежен.

    ОтветитьУдалить
  9. Я тоже не в особом восторге от TMS-а. Их Scripter Studio Pro сделан так, что его легко использовать только так как задумали авторы. А вот если начинать кастомизировать под себя, то выясняется что куча полезных методов упрятана в private или не помечена как virtual. Ещё хуже, из-за того, что в таком коде жёстко зашиты некоторые полезные константы, которые в идеале должны быть настраиваевыми. Из-за этого приходится извращаться, копировать код.
    Комментарии на испанском тоже доставляют.

    Bonart:
    RO Pascal Script не угодил отсутствием дизайнера форм и удобной утилиты для импорта .pas файлов.

    ОтветитьУдалить
  10. Анонимный3 июня 2012 г., 7:41

    как подключать поддержку QR вручную?

    ОтветитьУдалить
    Ответы
    1. 1) Вынести всё относящееся в отдельные юниты
      2) Окружить подключение этих юнитов директивами {$IFDEF USE_QR} {$ENDIF}
      3) Окружить любой код, имеющий отношение к QR директивами {$IFDEF USE_QR} {$ENDIF}
      4) Для подключения QR в настройки проекта Conditional Defines добавить USE_QR
      5) Для отключения QR из настроек проекта Conditional Defines убрать USE_QR

      Удалить

Постоянные читатели