Блог Александра Божко
Архивы
Рубрики

Редизайн интерфейса приложения.

Сегодня я снова вернусь к “жизнеописанию” своего проекта. Возможно, в этом посте вы найдете еще один аргумент, для того, что бы перейти на Delphi XE2. Начну я с небольшого вступления.

На семинаре Embarcadero в Киеве в сентябре прошлого года я услышал историю о переводе на юникод очень большого проекта. Собственно, и истории ни какой не было. Был проект, который разработчики, с одной стороны, и хотели бы перевести на старшую версию Delphi. А с другой стороны у них в проекте 5 млн. строчек кода. И, естественно, перспектива рефакторинга и последующего тестирования такого количества кода их весьма пугает. А так ли страшно это на самом деле?

Я уже говорил, что проект у меня относительно не большой. Но вчера я обнаружил, что у меня у самого 0,6 млн. строк. Т.е. в теории выйти на сопоставимые порядки сложности приложения вполне реально, даже если не решать “сверхзадач” (я ни в коем случае не призываю оценивать сложность проекта количеством кода!).

Но таким объемом кода надо эффективно управлять и контролировать его. Конечно, hint’ы и warning’и помогают хоть как-то избегать ляпов. Но довольно часто разработчики просто не обращают на них внимания (что в корне не правильно), тупо полагаясь на оптимизатор.  Даже в довольно именитых наборах компонентов, при сборке исходников hint’ы и warning’и встречаются в изобилии. И полная ревизия всех сообщений компилятора – задача не простая.

И вот здесь очень удобно использовать QA Audits – инструмент, впервые появившийся в Delphi 2010. Использовать это средство в полном объеме могут владельцы Enterprise, Ultimate и Architect редакций Delphi. Читать далее

Размышления на тему обращения к полям DataSet

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

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

В некоторой степени этот вопрос уже был затронут в болге Delphi Notes.

В начале немного теории. По умолчанию, при размещении экземпляра TDataSet на форме, Delphi автоматически создает наследников TFields для каждого поля в наборе данных, с учетом типов этих полей. В режиме проектирования (design mode) можно заменить эти поля на постоянные с помощью редактора полей. Лично я всегда предпочитаю всегда создавать поля в редакторе. Кроме того, мы можем добавить вычисляемые (calculated) и выпадающие (lookup) поля. Читать далее

Боремся со скоростью!

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

Итак, имеем следующее…

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

К набору данных привязаны cxGrid, в котором активное представление TcxDBGridDBTableView и cxPivotGrid (еще один очень интересный компонент из набора DevExpress о котором обязательно стоит рассказать). При загрузке свыше тысячи записей наблюдается явственная протормозка.

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

Я попытался вычислить количество миллисекунд, затрачиваемых на открытие DataSet’а и на загрузку данных в Grid’ы примерно так: Читать далее

Данный пост я оформлю тезисно. Да и вопросов в нем больше чем ответов.

Не буду оригинален – текучка.

После перевода приложения на Delphi 2010 вдруг перестали работать отчеты. при том все сразу. Причина банальна – Rave Reports. Раздел QC, посвященный Rave уже можно читать как увлекательный роман. Там даже есть крики отчаяния, зачем, мол, использовать в такой хорошей IDE как Delphi неработающий Rave, если есть работающий FastReport. Убедил руководство перевести 14 отчетов на FR с попутной его покупкой. Благо дело, стоит не дорого. В последний момент струхнул. Полез ковырять Rave. Выяснилось, что встроенный Pascal Script не корректно отрабатывает if. Если чего-то целочисленное сравнивать с нулем, и результат оказывается false – отчет валится.

Вынес в код приложения все, что считалось в отчете. 2 недели работы.

Вторая задача, ставшая на повестке дня – производительность.

Притормаживает программа с DevExpress гридами. У меня есть подозрения на этот счет. Но пока не готов это обсуждать. По факту решения проблемы ждите продолжения рубрик “Заметки на полях” и “Tips & Trics”.

По данной теме, пожалуй все… Был краток, как и обещал.

И немного новостей:

Очередной номер BPM. Опять 60 страниц. Во многом благодаря стараниям наших авторов. Так что, подписывайтесь на русскую версию журнала и читайте статьи в оригинале :).

Другие статьи серии:

Редизайн интерфейса приложения. #0
Редизайн интерфейса приложения. #1
Редизайн интерфейса приложения. #2
Редизайн интерфейса приложения. #3
Редизайн интерфейса приложения. #4
Редизайн интерфейса приложения. #6
Редизайн интерфейса приложения. #7
Редизайн интерфейса приложения. #8

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

Прежде всего, ASProtect. Я уже писал о том, как правильно осуществлять вызов функций ASProtect API. Это не сложно:

CheckKeyAndDecrypt( PChar(ansistring(eCode.Text)), 
PChar(ansistring(eName.Text)), True )

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

function  CheckKeyAndDecrypt      ( Key, Name : PChar; SaveKey: Boolean ): Boolean; external aspr_ide name ‘CheckKeyAndDecrypt';

Проблема же может возникнуть при вызове функций подобных этой:

function  GetRegistrationInformation   ( ModeID : Byte; var Key : PChar; var Name : PChar ): Boolean; external aspr_ide name ‘GetRegistrationInformation';

Параметры Key и Name – модифицируемые и передать выражение в качестве параметра уже нельзя.

Что делать в этом случае? Да просто изменить заголовки в файле aspr_api.pas.

function  GetRegistrationInformation   ( ModeID : Byte; var Key : PANSIChar; var Name : PANSIChar ): Boolean; external aspr_ide name ‘GetRegistrationInformation';

Вызов остается предельно простым:

var
pchKey, pchName: PANSIChar;

GetRegistrationInformation(0, pchKey, pchName);

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

Я покупал ASProtect SKE в 2006-м году и на последние версии продукта моя лицензия не распространяется. Однако, как выяснилось, самый простой вариант – скачать последнюю версию протектора и взять оттуда aspr_api.pas. Все исправления в заголовки там внесены, и с предыдущими версиями продукта работает прекрасно.Там же можно посмотреть и обновленные примеры использования.

Кроме этого, я обнаружил пару проблем с cxGrid (сохранение и восстановление заголовков полей). Но, об этом я напишу по факту решения данной проблемы.

Другие статьи серии:

Редизайн интерфейса приложения. #0
Редизайн интерфейса приложения. #1
Редизайн интерфейса приложения. #2
Редизайн интерфейса приложения. #4
Редизайн интерфейса приложения. #5
Редизайн интерфейса приложения. #6
Редизайн интерфейса приложения. #7
Редизайн интерфейса приложения. #8

Так получилось, что рассказывать о переводе приложения с GridEh на DevExpress‘овские гриды бессмысленно, если читатель не имеет представления о cxGrid. Отсюда и затянувшаяся серия “заметок на полях“. К слову, на мой взгляд по соотношению цена/функционал GridEh - все таки оптимальное решение. Тем не менее, как я писал в предыдущем посте серии, была необходимость использовать cxGrid.

Скажу честно, процесс перевода не прост. Хотя во многом его трудоемкость зависит от организации исходного варианта. В моем случае события исходных гридов обрабатывались очень плотно. Перед моим предшественником ставилась задача получить определенную эргономику грида. Переход по ячейкам с помощью Enter, новая запись по достижению последней ячейки последней записи и т.д. Кроме этого, при добавлении записей в грид производились некоторые операции по подстановке исходных значений (почему в грид, а не в датасет, я так и не понял), изменению отображения данных и прочее… Все это и привело к весьма громоздкому и “гридзависимому” коду. Читать далее

Прежде, чем непосредственно перейти к повествованию, я хотел бы обратить ваше внимание на инструментарий, который мне пришлось использовать. В первую очередь речь идет о GExperts – прекрасном расширении IDE, которое сэкономило мне немало времени и сил. Для тех, кто не знаком с этим продуктом – рекомендую. Бесплатно! Так же весьма полезными оказались Refactoring инструменты из стандартного набора Delphi. Читать далее

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

Продукты DevArt
Купить онлайн:



Читай русскоязычные Delphi блоги
Каталог блогов Blogdir.ru
Яндекс.Метрика