Стоит Windows 8 Pro, Visual Studio 2010 Express Edition . |
Работа MFC с GDI (GDI+)
Цель работы:
- Ознакомиться с функциями рисования примитивов
- Использовать перья и кисти для рисования различных частей графических примитивов
- Устанавливать различные режимы отображения контекста устройства
- Динамически загружать и отображать растровые рисунки разными способами и в разных форматах
Интерфейс графических устройств
Интерфейс графических устройств Windows ( GDI - Graphic Device Interface ) представляет собой виртуальное графическое устройство для всех приложений независимо от конкретных аппаратных средств, из которых состоит компьютер. GDI является неотъемлемой частью ядра операционной системы, контролирующей и обеспечивающей все операции графического вывода приложений Windows.
Корпорация Microsoft создала GDI, чтобы отделить графические операции от фактически используемого оборудования. Для программиста предоставлены графические функции высокого уровня абстракции, которые обеспечивают одинаковые результаты выполнения независимо от используемого оборудования. От разработчиков аппаратных средств требуется обеспечить поставку и драйверов (программ управления оборудованием на низком уровне) для естественного подключения их к функциям GDI.
Пользовательская сторона GDI (пользователь GDI - это разработчик приложения) реализована с помощью контекста устройства. Контекст графического устройства - это конкретная настройка GDI на выполнение графических операций. Управление контекстом устройства обеспечивается MFC -классом CDC. Объект, созданный с помощью этого класса, содержит все необходимые настройки GDI, установленные по умолчанию или пользователем (разработчиком приложения). Фактически экземпляр класса CDC или производных от него классов и представляет собой контекст устройства, олицетворяя собой все настройки GDI.
Контекст устройства способен обеспечить вывод изображений на любое внешнее устройство, будь то экран, принтер, графопостроитель и т.д. При этом используются одни и те же функции GDI. Для отображения изображения на экране приложению необходимо иметь контекст устройства экрана, для отображения на принтере - контекст другого устройства - принтера.
Контексты экрана и принтера называются физическими контекстами или контекстами вывода. Существуют еще два контекста устройства: растр и метафайл. Растр является тем же контекстом устройства, содержащим набор пикселов и по своей структуре готовый для подключению к физическому контексту, но пока хранящийся в памяти. Метафайл является набором готовых инструкций, способных создать графическое изображение перед подключением к физическому контексту.
Контекстов устройства, как экземпляров класса CDC, одновременно может быть создано в приложении несколько и все они будут храниться в памяти готовыми для подключения, но только один из них в текущий момент времени может быть связан с конкретным физическим устройством вывода информации. т.е. только один может служить физическим контекстом ( контекстом вывода ). Существуют наследники класса CDC, создающие контексты в частных случаях, например, CPaintDC, CClientDC. Поскольку CDC является базовым классом для всех других классов контекста устройства, все его методы доступны независимо от того, с каким классом контекста устройства мы работаем в данный момент.
Объекты контекста устройства, а равным образом и все различные объекты рисунка, классифицируются в Windows как ресурсы. Операционная система может иметь ограниченное количество таких ресурсов и они могут исчерпаться, если приложение занимает их и вовремя не освобождает. Эта потеря известна как утечка ресурсов и во многом подобна утечке памяти, поскольку тоже в конечном итоге приводит к блокировке системы.
Чтобы избежать утечки подобных ресурсов, удобнее создавать их как локальные на стеке в пределах тех функций, где они будут использоваться. Соответственно при выходе из такой функции ресурс автоматически освобождается. Единственное реальное исключение, - когда объект контекста устройства создается самой Windows и передается в функцию обработки события в качестве параметра pDC. Например
void CCircleView::OnDraw(CDC* pDC) { ................... }
Некоторые свойства (атрибуты) контекста устройства представляют собой простые типы данных, встроенные прямо в контекст устройства. Но большинство графических атрибутов контекста устройства представляют собой сложные данные типа структур или даже классов со своими функциями членами. Экземпляры этих классов называются графическими атрибутами контекста устройства. Экземпляры этих классов нужно создавать, настраивать и подключать к контексту устройства, чтобы они должным образом влияли на графический вывод.
Поддержка цветов в GDI
Базовым типом данных Windows для хранения цветов является структура COLORREF. Проще всего задать цвет при помощи макрокоманды RGB, которой передаются три числовых значения от 0 до 255. Например:
COLORREF crRed = RGB(255, 0, 0); COLORREF crGreen = RGB(0, 255, 0); COLORREF crBlue = RGB(0, 0, 255);
Такой способ задания цвета в GDI называется логическим цветом. Но это только наше пожелание, а реальное отображение цвета определяется способностью аппаратного устройства. Монитор с высокой разрешающей способностью, расчитанный на отображение 24-битной или 32-битной глубины цвета не будет иметь никаких расхождений между логическим и физическим цветом. Для более слабых мониторов GDI будет сам осреднять цвета, подбирая наибольшее сходство между логическим (запрашиваемым) и физическим (реально отображаемым) цветом. Аналогичный процесс происходит и для принтеров.
Таким образом, если, например, красный цвет запрошен у физического устройства, способного его отобразить, то все нормально - мы получим то, что требовалось. Но если физическое устройство не способно отобразить запрошенный цвет, то оно применит самый близкий (с точки зрения GDI ). Для черно-белых принтеров GDI стремиться подобрать наиболее близкие цвета через оттенки серого, что иногда никуда не годится. Чтобы решить эту проблему, можно просто не запрашивать недоступные цвета. Чтобы выяснить, сколько цветов поддерживает конкретное физическое устройство, нужно обратиться к функции контекста этого устройства
int nColors = pDC->GetDeviceCaps(NUMCOLORS);
Для цветных мониторов система предоставляет стандартную палитру из 20 цветов, на основании которой формируются все другие цвета.
Класс контекста устройства CDC имеет множество методов, но существуют три основных направления применения этих методов для управления функциями GDI:
- Текст
- Векторная графика
- Растровая графика
Для каждого из них в GDI существуют свои функции управления, потому что на уровне драйверов устройств каждый из этих наборов операций имеет свою реализацию и выполняется по разному.