- Gdl windows что это
- Где применимо
- Аудитория разработчиков
- Требования к среде выполнения
- GDI+: графика нового поколения
- Часть 1. Краткое знакомство
- Заглянем «под капот»
- Что новенького?
- Требования к среде выполнения
- Поддерживаемые технологии разработки
- Начинаем работу
- Иерархия классов GDI+
- Инициализация и завершение
- Создаем первое приложение
- Пример WinForms — приложения с использованием GDI+
- Несколько замечаний о компиляции и сборке проектов
- Где взять GdiPlus.h?
- Почему выдается ошибка о типе ULONG_PTR?
- Почему компилятор не дает создать объект GDI+ при помощи new?
- Не забудьте про пространство имен Gdiplus и библиотеку импорта
Gdl windows что это
Windows GDI+ — это API на основе классов для программистов C/C++. Она позволяет приложениям использовать графику и форматированный текст как на дисплее, так и на принтере. Приложения на основе API-интерфейса Microsoft Win32 не обращаются к графическому оборудованию напрямую. Вместо этого GDI+ взаимодействует с драйверами устройств от имени приложений. GDI+ также поддерживается Microsoft Win64.
Где применимо
Функции и классы GDI+ не поддерживаются для использования в службе Windows. Попытка использовать эти функции и классы из службы Windows может привести к непредвиденным проблемам, например к снижению производительности службы и исключениям или ошибкам времени выполнения.
При использовании интерфейса GDI+ API не следует разрешать приложению скачивать произвольные шрифты из ненадежных источников. Операционная система требует повышенных привилегий, чтобы гарантировать, что все установленные шрифты являются доверенными.
Аудитория разработчиков
Интерфейс на основе классов GDI+ C++ предназначен для использования программистами C/C++. Знание графического пользовательского интерфейса Windows и архитектуры, управляемой сообщениями, является обязательным.
Требования к среде выполнения
GDI+ можно использовать во всех приложениях на основе Windows. Интерфейс GDI+ появился в Windows XP и Windows Server 2003. Сведения о том, какие операционные системы требуются для использования определенного класса или метода, см. в разделе «Дополнительные сведения» документации по классу или методу.
GDI+: графика нового поколения
Часть 1. Краткое знакомство
Автор: Виталий Брусенцев
The RSDN Group
Источник: RSDN Magazine #1
Опубликовано: 13.12.2001
Исправлено: 13.03.2005
Версия текста: 1.0
За последний год компания Microsoft подготовила разработчикам множество сюрпризов. Новые продукты и технологии буквально завладели вниманием околокомпьютерного мира. Пока неясно, насколько успешным будет дебют технологии .NET и основанных на ней программных продуктов и средств разработки. Но одно из новшеств, безусловно, уже завоевало признание разработчиков, связанных с графикой и мультимедиа, — технология GDI+. Именно она, вернее, основанный на ней новый графический интерфейс является «лицом» новых операционных систем — Windows XP и .NET Server.
Что же такое GDI+? Официальная документация скромно называет ее Class-based API, то есть основанным на классах интерфейсе прикладных программ. Так как она встроена в Windows XP и .NET Server, ее называют частью этих операционных систем. Часто встречается также определение «библиотека» или «библиотека классов». В действительности, предоставляемый GDI+ набор классов является тонкой оболочкой над множеством обычных функций, реализованных в одной динамической библиотеке GdiPlus.dll . В общем, имея все это в виду, будем для краткости далее называть ее просто библиотекой.
Итак, GDI+ — это библиотека, призванная заменить существующий уже больше 11 (или 18 — как считать) лет интерфейс GDI, являющийся графическим ядром предыдущих версий Windows. Она сочетает в себе (по крайней мере, по замыслу) все достоинства своего предшественника и предоставляет множество новых мощных возможностей. Кроме того, при ее проектировании заранее ставилась цель наименее болезненного переноса приложений на 64-битные платформы. Следовательно, хотя существующие GDI-приложения будут выполняться на новых версиях Windows, для новых проектов следует использовать GDI+.
Заглянем «под капот»
Что новенького?
Далее мы еще будем рассматривать специфические (и такие эффектные!) возможности GDI+. Здесь же только опишем основные новшества.
Достоинства C++ — реализации:
- Объектно-ориентированный интерфейс: благодаря поддержке компилятора C++ мы «бесплатно» получаем контроль над типами и временем жизни объектов.
- Прозрачное управление памятью: объекты ядра GDI+ создаются в куче с помощью собственного менеджера памяти прозрачно для программиста.
- Использование перегрузки имен функций: функции одного назначения различаются только по своим параметрам.
- Собственное пространство имен: позволяет использовать понятные имена типов — такие, как Rect, Pen и Matrix — без конфликтов с другими библиотеками.
- Перегрузка операторов: предоставляет удобные операции ‘+’ и ‘-‘ для таких типов, как Point и Size.
Архитектурные новинки библиотеки:
- Аппаратная абстракция: как уже было замечено, упрощается перенос на 64-битные платформы.
- Новый дизайн графических функций/объектов: теперь можно не бояться «оставить выбранной кисть в контексте перед удалением» — такая типичная для GDI ошибка!
- Разделение функций закраски и отрисовки: предоставляет большую гибкость в рисовании, например, позволяет заливать незамкнутые фигуры.
- Появление графических контейнеров: контейнеры позволяют «сцепить» вместе несколько операций и использовать как одну команду.
- Увеличившаяся поддержка путей (paths) и их взаимодействия с регионами: теперь пути являются полноправными объектами вне контекста рисования и могут легко трансформироваться в регионы.
Новые технологии и возможности (задержите дыхание):
- Градиентная закраска: позволяет заливать сложные фигуры оттенками с различными законами распределения цвета, рисовать векторные примитивы (например, линии) с градиентной окраской.
- Поддержка прозрачности: можно создавать кисти и растры с прозрачными и полупрозрачными областями, заливать области полупрозрачным цветом, назначать Color Key для растрового изображения и работать с его альфа-каналом, а также рисовать полупрозрачные (!) векторные примитивы и текст.
- Режимы улучшения изображения: позволяют значительно улучшить пользовательское восприятие за счет сглаживания контурных неровностей (antialiasing) и префильтрации растровых изображений.
- Сплайны: кроме уже существующих в GDI кривых Безье, поддерживается новый вид кривых — так называемые сплайны, которые имитируют поведение натянутой и изогнутой стальной полосы. Сплайны являются гладкими кривыми.
- Пути: как уже говорилось, пути теперь существуют независимо от контекста рисования и представляют собой мощное средство создания сложных векторных объектов. Кроме того, появилась возможность выравнивать (flatten) пути, то есть преобразовывать их к набору отрезков прямых.
- Координатные преобразования: объект Matrix позволяет осуществлять операции поворота, переноса, масштабирования и отражения объектов GDI+.
- Регионы: в отличие от GDI, регионы теперь не привязаны к координатам устройства и подчиняются координатным преобразованиям.
- Работа с растрами: теперь можно практически все! Поддерживается отрисовка растров с наложением внешнего альфа-канала, масштабированием, растяжением, искажением и поворотом растров. При этом можно установить режимы отображения отдельных пикселей — от простого переноса до префильтрации (наилучшее качество изображения). Стало возможным рисовать векторные примитивы, залитые текстурами (!).
- Поддержка популярных форматов графических файлов: необычайно приятное новшество для всех программистов, имеющих дело с разными графическими форматами. Поддерживаются форматы BMP , GIF , TIFF , JPEG , Exif (расширение TIFF и JPEG для цифровых фотокамер), PNG , ICON , WMF и EMF . Декодеры различных форматов выполнены с учетом их специфики, так что Вы сможете, например, отобразить анимационный GIF или добавить комментарий к TIFF -файлу. Загруженный, созданный или модифицированный файл может быть сохранен на диск в одном из подходящих форматов. Существует возможность написания собственных декодеров.
- Формат EMF+ : разумеется, все это великолепие не могло уместиться в тесные рамки старого Enhanced Metafile. Для описания новых возможностей был создан новый формат метафайла EMF+, который позволяет сохранить на диск и затем проиграть последовательность графических команд. Существует возможность записать «дуальный» метафайл, понятный старым GDI-программам. Новые программы будут читать из него GDI+ — информацию.
Требования к среде выполнения
Поддержка GDI+ встроена непосредственно в операционные системы Windows XP и .NET Server. Для того чтобы приложения, использующие эту библиотеку, выполнялись на предыдущих версиях Windows, необходимо установить дистрибутив gdiplus_dnld.exe размером около одного мегабайта. Найти его (и, возможно, другие необходимые обновления) можно на сайте Microsoft по адресу:
В его состав входят только инструкция по установке и уже упомянутая динамическая библиотека GdiPlus.dll, которую необходимо скопировать в системный каталог Windows 98/ME, Windows NT SP6 или Windows 2000. При этом возможности, предоставляемые непосредственно ядром Windows XP (в частности, технология ClearType для качественного отображения шрифтов на LCD-мониторах), будут недоступны.
ПРИМЕЧАНИЕ Я не случайно не упомянул про Windows 95. На сайте Microsoft отсутствует всяческое упоминание о поддержке GDI+ для этой операционной системы. Тем не менее, единственная доступная мне для тестирования машина с Windows 95 OSR2 выполнила тестовое приложение без каких-либо проблем. Но ввиду отсутствия какой-либо официальной поддержки для использования GDI+ крайне рекомендуется обновить систему хотя бы до Windows 98. |
Поддерживаемые технологии разработки
В этой статье рассматривается интерфейс к GDI+, реализованный для языка C++ — хотя уже существует реализация Microsoft для системы CLR, входящей в состав .NET, и, безусловно, вскоре усилиями энтузиастов появятся другие (например, для VB и Delphi).
Заметим, что GDI+ (вернее, ее обертка для CLR), входящая в состав Microsoft .NET Framework SDK, является основным средством рисования в среде .NET. Однако доступная на данный момент Beta 2 имеет довольно большие отличия от реализации для C++ (не только архитектурные, но и чисто внешние, например, различающиеся имена некоторых классов). Я постараюсь коротко описать эти отличия в конце статьи.
Набор заголовочных файлов (headers) и библиотека импорта GdiPlus.lib, необходимые для сборки демонстрационных приложений, входят в состав последнего Platform SDK. Те, кто до сих пор не обновил идущий с Visual Studio 6.0 Platform SDK образца 1998 года, могут загрузить его с сайта Microsoft по адресу:
Минимальный компонент, в состав которого входит GDI+, называется Windows Core SDK и имеет размер около 230 мегабайт.
ПРИМЕЧАНИЕ Я понимаю, что для многих читателей, имеющих доступ в Интернет через домашний модем, предложение скачать дистрибутив такого размера прозвучит как насмешка. В качестве крайней временной меры можно раздобыть только набор заголовочных файлов GdiPlus*.h, BaseTsd.h и библиотеку импорта GdiPlus.Lib из нового Platform SDK. Но гарантировать работоспособность такого решения во всех ситуациях я не возьмусь. Да и в любом случае, обновить Platform SDK необходимо. Возможно, вам удастся найти его на CD-ROM. |
На момент написания этих строк доступна версия Platform SDK за август 2001 г.
Демонстрационные примеры будут в подавляющем большинстве написаны с использованием Windows API, что позволит сосредоточиться на использовании GDI+. Но вы без труда сможете подключить эту библиотеку к своим MFC- или WTL-приложениям. Иногда я также буду приводить соответствующий пример на C# для WinForms.
Начинаем работу
Иерархия классов GDI+
Типичное рабочее место программиста на C++, как правило, включает в себя стену, на которой гордо красуется Диаграмма классов (неважно каких). Теперь рядом можно наклеить еще один плакат.
Ниже приведена иерархия классов GDI+. Я не включил в нее 8 структур данных и перечисления (enumerations) — около 50 штук.
При первом взгляде на диаграмму видно, что она очень напоминает, например, ту часть библиотеки MFC, которая отвечает за рисование, только классов гораздо больше (40 против 15 у MFC). Это и неудивительно, учитывая фирму, которая разрабатывала эти библиотеки. Основные отличия отражают новые возможности GDI+. Мы подробно рассмотрим их в следующих частях.
Как видим, большинство объектов имеют в корне иерархии класс GdiPlusBase. Вам не понадобится создавать экземпляры этого класса, так как он содержит только средства управления памятью (для него перегружены операторы new/new[] и delete/delete[], которые используют функции GDI+ GdipAlloc и GdipFree ). Все классы, инкапсулирующие работу с ресурсами GDI+, порождены от GdiPlusBase . Это не значит, что их экземпляры нельзя создавать на стеке — напротив, так даже удобнее контролировать время их жизни. Зато такая архитектура позволит, например, передавать указатель на созданный объект GDI+ в модуль, написанный с использованием других средств разработки, и безопасно его удалять в этом модуле.
Не путайте управление памятью под экземпляры классов-оберток С++, которое осуществляется перегруженными операторами new/delete, и управление собственно ресурсами GDI+, которое скрыто от разработчиков в недрах соответствующих функций, например, GdipCreateSolidFill . |
Ключевым же классом в GDI+ является Graphics (программисты на J++ вздрогнули). Именно он содержит почти две сотни методов, отвечающих за рисование, отсечение и параметры устройства вывода. Напрашивается явная аналогия с контекстом устройства (Device Context) прежнего GDI, и эти понятия действительно тесно связаны. Из четырех конструкторов Graphics два создают его из HDC. Главное отличие заключается в изменении программной модели: теперь вы не работаете с хендлом, а вызываете методы класса. Хотя программистам на MFC эта концепция уже хорошо знакома.
Дальнейшее наследование (например, класс TextureBrush порожден от Brush ) скорее отражает цели разработчиков (скрытие деталей реализации и повторное использование оберточного кода), чем инфраструктуру библиотеки, так как в inline-методах «родственных» классов просто содержатся вызовы различных функций GdiPlus.dll. Можно сказать, что Microsoft в очередной раз спроецировала обычный «плоский» API языка C на объектно-ориентированную библиотеку C++.
Оставшаяся часть классов не имеет общего родителя и предназначена для упрощения работы со структурами данных GDI+.
Инициализация и завершение
Перед тем как начать использовать классы и функции GDI+, необходимо инициализировать эту библиотеку. Для этого где-нибудь в начале своей программы нужно поместить вызов функции GdiplusStartup:
Поля структуры GdiplusStartupInput управляют различными аспектами инициализации: в частности, можно задать функцию, которая будет вызываться при возникновении ошибок, или перехватывать все обращения к функциям GDI+. Эти детали мы рассматривать не будем. К счастью, конструктор по умолчанию структуры GdiplusStartupInput выполняет инициализацию, достаточную в большинстве случаев. При этом в качестве выходного параметра output можно задать NULL.
«Магическое значение», на которое указывает выходной параметр token, необходимо сохранить.
Для завершения работы с библиотекой вызовите функцию GdiplusShutdown:
Здесь в качестве параметра и необходимо передать то самое число, которое возвратила GdiplusStartup в параметре token.
Вы можете вызвать GdiplusStartup и GdiplusShutdown из разных потоков, но необходимо убедиться, что вне этой пары функций никакого обращения к объектам GDI+ не происходит. В частности, будьте осторожны, объявляя глобальными экземпляры классов — ведь их деструкторы выполнятся уже после WinMain. Кроме того, как обычно, нельзя вызывать функции инициализации и очистки из DllMain , поскольку это может привести ко входу в бесконечную рекурсию или другим неприятностям. |
Создаем первое приложение
Настало время применить все эти сведения на практике. Для этого создадим в MS Visual C++ базовое WINAPI-приложение, которое послужит полигоном для дальнейших экспериментов. Ниже для этого приведена пошаговая процедура.
Итак, создаем новый проект Win32 Application. Выбираем опцию A typical «Hello, World!» application и нажимаем «Finish». Получившееся приложение необходимо подготовить для использования GDI+. Для этого в файле stdafx.h после строки с комментарием:
добавляем следующие строчки:
и в конце файла stdafx.cpp добавляем строку
Кроме того, в файле stdafx.h необходимо удалить или закомментировать строку
Иначе компилятор выдаст кучу ошибок об отсутствии символов MIDL_INTERFACE, PROPID, IStream и т.д.
Если полученное в результате приложение успешно собралось, значит, мы все сделали правильно. Пойдем дальше.
Найдем в сгенерированном основном .cpp файле нашего проекта функцию WinMain и добавим в начале ее код инициализации:
а в конце, перед оператором return , добавим код очистки:
Готово. Наконец-то мы можем что-нибудь нарисовать. Найдите в теле функции WndProc обработчик сообщения WM_PAINT и замените следующим кодом:
Теперь где-нибудь перед функцией WndProc создадим функцию OnPaint с кодом рисования:
В результате у нас получится примерно вот что:
Приведенный пример носит только ознакомительный характер. В реальном приложении, для того чтобы нарисовать растр, его, как правило, не нужно каждый раз загружать с дискового файла :). Далее я буду пользоваться созданным макетом программы для создания других демонстрационных приложений. В качестве примера рисования будет приводиться только код функции OnPaint . |
Пример WinForms — приложения с использованием GDI+
Для того чтобы можно было сравнить рассматриваемую реализацию GDI+ с той, что используется в .NET, приведу полный текст соответствующего приложения на новом языке C#:
Как видим, помимо чисто синтаксических отличий имеются и принципиальные, например, использование в CLR-модели свойств против использования Set-методов в C++. Кроме того, в .NET активно используются пространства имен.
Замечу, что здесь приведен полный текст программы, аналогичной по возможностям той, что мы создали в предыдущем разделе. Сравните объем исходных текстов этих двух примеров. NO COMMENTS. |
Если вы запустите приведенный пример, то увидите, что текст отрисовывается без сглаживания, характерного для предыдущего примера. Это связано с тем, что WinForms по умолчанию отключает улучшенный режим отрисовки шрифтов — и без этого причин для торможения достаточно 🙂
Несколько замечаний о компиляции и сборке проектов
Хочется указать на несколько «подводных камней», которые могут сбить с толку при первой попытке откомпилировать и собрать проект, использующий GDI+. В основном здесь упомянуты те проблемы, с которыми сталкиваются (и постоянно спрашивают о них в различных форумах) начинающие.
Где взять GdiPlus.h?
Как я уже сказал, все заголовочные файлы, библиотека импорта и документация к библиотеке входят в состав последнего Platform SDK. Они не идут в составе Visual С++ 6.0 и его сервис паков.
Почему выдается ошибка о типе ULONG_PTR?
Похоже, что компилятор находит старый заголовочный файл basetsd.h — например, из комплекта VC++. Измените пути поиска заголовочных файлов так, чтобы вначале были найдены файлы Platform SDK.
Почему компилятор не дает создать объект GDI+ при помощи new?
Такое поведение возможно при попытке откомпилировать MFC-приложение с использованием GDI+ в Debug-конфигурации.
В начале файла программы, видимо, имеется следующий фрагмент:
Либо откажитесь от создания объектов GDI+ с помощью new , либо откажитесь от проверок динамической памяти в этом файле (удалив вышеприведенную директиву #define ).
Не забудьте про пространство имен Gdiplus и библиотеку импорта
В приводимых примерах кода используются простые имена классов, такие как Brush и Rect. Это стало возможным благодаря тому, что в начале заголовочного файла программы есть директива
Если это решение не подходит (например, в проекте уже существуют классы с такими именами), то перед именами классов необходимо ставить префикс пространства имен, например
Также, если по каким-то соображениям директива
не устраивает, в опциях компоновщика нужно явно указать библиотеку импорта gdiplus.lib .
На этом пока все. В следующей части мы рассмотрим богатые возможности, которые GDI+ предоставляет для работы с растровыми изображениями.