Как подключить GDI+ для Delphi 7 и не иметь проблем в XE

Delphi GDI+

Оказывается, Delphi 7 по-прежнему популярна и любима многими. У меня практически все примеры написаны для XE с использованием «родного» GDI+, что делает невозможным их компиляцию в Delphi 7. А потребность, как подключить GDI+ для Delphi 7, есть.

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

Подключение

Есть библиотека GDI+ для Delphi / Lazarus. Там есть все. Даже эффекты. Но подход отличается от принятого для Delphi XE, и совместная компиляция ни к чему хорошему не приводит. А хочется иметь код, который компилируется и в Delphi7, и в Delphi XE.

Поэтому качаем блок из четырех модулей: GDIPlus.zip (130 Кб). Это стандартные для XE модули, переделанные для Delphi7.

Подключаем каталог в опциях проекта. Если каталог находится на одном уровне с каталогом проекта, то выглядеть будет так:

Рис.1. Опции проекта Prolect-Options…

В предложении Uses пишем так:

Это нужно, чтобы XE, начиная с пятой (не знаю, как обстоят дела в более древних версиях XE), использовал свои Winapi.GDIPAPI, Winapi.GDIPOBJ модули.

Все готово. Теперь все, что написано о GDI+ в контексте XE, можно использовать и для Delphi 7.

GDI+ для Delphi 7

Возьмем, например, код, написанный для Delphi 7, из статьи принадлежность точки отрезку, и модифицируем его для GDI+.

Было:

Рисование средствами GDI

[свернуть]

Стало:

Этот код без проблем скомпилируется в XE7, XE10 (возможно и в XE5, проверить сейчас не могу).

Это изображение имеет пустой атрибут alt; его имя файла - p4.jpg
Рис.2. При включенном GDI+ наблюдаем заметное улучшение качества картинки и замедление времени отрисовки на 1 милисекунду.

Модификация GDIPCanvas

Когда-то давно сделал наследника TCanvas, умеющего работать, и как стандартный TCanvas, так и с вызовами GDIPlus. Заточен был на работу в XE, т.к. в Delphi 7 нет родного GDI+. В связи с появлением у меня возможности использовать ровно те же самые вызовы для Delphi 7, что и для XE, немного переделал блок GDIPCanvas.

Скачать GDIPCanvas.zip (99.5 Кб)

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

Рис.3. Опции проекта Prolect-Options… для подключения GDIPCanvas

Если каталог GDIPCanvas будет находиться на одном уровне с каталогом проекта и каталогом GDIPlus, то предложение Search path должно выглядеть так: ..\GDIPlus\;..\GDIPCanvas\

В предложение uses добавляем следующие модули:

Зачем вообще использовать GDIPCanvas. Во-первых, рисование в нем совершенно аналогичное стандартному TCanvas, во-вторых, он писался в свое время только для XE. Интересно же посмотреть, как он съест отрефакторенные модули GDIP для Delphi 7?

Это изображение имеет пустой атрибут alt; его имя файла - p4.jpg
Рис.4. Добавление GDIPCanvas

Для режима одновременно включенных GDI+ и GDIPCanvas не стал устанавливать шрифт, чтобы было видно, как GDIPCanvas отрабатывает разные фонты.

В целом, все чудесно подхватилось и работает, как ожидалось.

Нюансы GDIPCanvas для Delphi7 и XE

К сожалению, TCanvas в исполнении Delphi7, не предоставил виртуализации своих методов. Поэтому, для Delphi7, при отрисовке, надо жестко указывать тип холста.

Из-за этого пришлось писать дубль функции отрисовки текста.

Как видим, для XE5, в случае обычного TCanvas или TxIPCanvas, будет работать единственная процедура DrawLabels без перегрузки.

Также, для Delphi7 и ХЕ, будут разные подходы к объявлению типа и использованию.

Например для pbPaintGDIP():

Видим, что для Delphi7 тип холста cnv явно указан, как TxIPCanvas, в то время, как для XE это TCanvas. То есть может быть, как стандартным TCanvas, так и его наследником.

Соответственно, меняется и способ создания.

Если имеем дело с XE, и если нужен GDIPCanvas, создаем его. Иначе, просто присваиваем холст битмапа, т.е. стандартный GDI-холст. В случае Delphi7, GDIPCanvas создается в любом случае, и если возможности GDI+ не требуются, устанавливаем UseStandartGDI в True. В этом случае все вызовы будут стандартными.

Использование также меняется.

Как видим, для XE используется одна и та же процедура, в то время, как для Delphi7 — две перегруженных.

Таким образом, чтобы рисовать в GDI+ нам уже не требуется отдельная процедура. Все можно сделать в одной. Конечно, директивы чуть скрадывают код, но, думаю, суть понятна. Для рисования либо в стандартном GDI, либо в GDI+ не надо писать два совершенно разных кода.


Скачать

Друзья, спасибо за внимание!

Было бы очень здорово, если о результатах использования GDIP и GDIPCanvas вы поделились бы в комментариях. Думаю, это полезно всем. О всех изменениях и обновлениях буду сообщать в телегу Подписывайтесь, чтобы не пропустить!


Исходник с GDI+ (zip) 148 Кб.

Исполняемый файл c GDI+ (zip) 216 Кб.


Исходник с GDIPCanvas (zip) 241 Кб.

Исполняемый файл с GDIPCanvas (zip) 283 Кб.


Эти каталоги уже включены в исходники, для скачивания отдельно от них:

GDIPlus.zip 130 Кб.

GDIPCanvas.zip 99.5 Кб.


В статье про быстрый доступ к пикселям есть ссылка на скачивание версии для Delphi 7 без поддержки GDI+. Теперь можно скачать с поддержкой GDI+ и как следует откомментарить ))) Исправлена, кстати одна неприятность, так что работает лучше, чем было.

Исходники (zip) 3.09 Мб

Исполняемый файл (zip) 2.69 Мб


При компиляции в XE вначале надо сделать Build. После этого Compile (Ctrl+F9) будет работать без проблем.

5 8 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

4 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Alexey

Привет! Отличная, и, главное, очень полезная статья. Я, пока детально в код ещё не вникал, но подозреваю, что вполне вероятно использовать GDI+ не только в Delphi 7, но и в более древней Delphi 5 (да, есть люди, которые и в ней работают, как бы странно это не звучало).

Ну, и если можно покритиковать, то чутку покритикую — в статье всегда и не очень очевидно, про какую именно версию Делфи ХЕ идёт речь. Дело в том, что после выхода Delphi 2010 «бракоделы» выпустили ХЕ, потом уже была ХЕ2, ХЕ3…ХЕ8, а дальше уже Делфи 10, сиречь Сиэтл, когда они переключились на города в именовании.
Так вот, когда в статье встретил упоминание про Delphi XE, то сразу и подумал именно про XE (которая по идее должна быть Делфи 2011). И лишь потом осознал, что речь идёт про семейство в целом, причем как я понял, гарантированно лишь про ХЕ8, а все, что младше, оно как бы сказать…. Вроде тоже должно работать, но не обязано )))

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

Что же до статьи — могу только ещё раз поблагодарить, и, раз уж волей случая автору самому понадобилось поработать в классике (т.е. в Делфи 7), то смею надеяться, что это не последняя статья, да и материал вообще, который можно применить в семерине.
Лично я бы не сказал, что часто прям мне нужно что-то делать в семёрке, но тем не менее, порой бывает и такое. А ещё уверен, что статья и код будут крайне полезны именно тем, у кого семёрка в ходу и по сей день.

И вот в финале своего лонгрида хотел бы спросить про вероятность того, что в принципе, насколько реально и трудоёмко научить Делфи 7 помимо GDI+ работать ещё и с Direct2D, с теми замечательными эффектами и примерами, цикл статей о которых есть тут, на сайте?
Насколько я заглядывал в модули про Директ2Д (а это было бегло), то мне видится, что задачка не самая простая. Хотя, возможно, я ошибаюсь и не все так страшно?

Ещё раз спасибо!!!!

Александр

В версии XE нет модуля UITypes.
Если верить информации по нижеприведённой ссылке, то искомый модуль появился с версии XE2
https://sourceforge.net/p/gexperts/bugs/99/

4
0
Не нашли ответ на свой вопрос? Задайте его здесь!...x