Окт 16 2009

Создание метафайла

Расширенный метафайл является таким же объектом GDI, как, например, объект кисти или объект DIB-секции. Объект расширенного метафайла однозначно определяется своим дескриптором типа HENHMETAFILE. Создание метафайла и запись в него команд GDI связаны с использованием метафайлового контекста устройства, который рассматривался во второй главе.
Метафайловый контекст устройства создается функцией CreateEnhMetaFile:
HDC CreateEnhMetaFile(HDC hdcRef. LPCTSTR IpFilename. CONST RECT lpRect, LPCTSTR IpDescription);
Первый параметр, hdcRef, указывает на эталонный контекст устройства, данные которого будут использованы при записи EMF. Если этот параметр имеет значение NULL, то GDI принимает в качестве эталона текущий экран.
Во втором параметре, IpFilename, может передаваться имя файла на диске или значение NULL. Если передается NULL, то метафайл создается в памяти. Если передается имя файла, то после удаления объекта метафайла функцией DeleteEnhMetaFile файловый вариант сохраняется на диске.
Третий параметр, IpRect, определяет позицию и размеры сохраняемого изображения в единицах 0,01 мм. Если параметр имеет значение NULL, то GDI вычисляет ограничивающий прямоугольник по всем командам вывода.
Последний параметр, IpDescription, содержит необязательное текстовое описание, сохраняемое в метафайле. Обычно описание содержит имя приложения и имя документа, разделенные нулевым символом. Это описание должно завершаться двумя нулевыми символами.
Функция CreateEnhMetaFile возвращает дескриптор метафайлового контекста устройства. Этот дескриптор передается затем всем графическим функциям GDI для записи «протокола рисования» в метафайл.
Когда рисование завершено, необходимо вызвать функцию CloseEnhMetaFile, которая закрывает метафайловый контекст и возвращает дескриптор расширенного метафайла. Этот дескриптор может быть использован для воспроизведения метафайла.
Как говорилось выше, если имя файла было задано при вызове функции CreateEnhMetaFile, то сохранение файла на диске происходит после вызова функции DeleteEnhMetaFile, которая удаляет объект метафайла из памяти приложения.


Окт 16 2009

Метафайлы

Метафайл — это протокол обращений к функциям GDI, сохраненный в двоичном формате. Метафайлы имеют такое же значение для векторной графики, как и битовые образы для растровой графики. Метафайл состоит из набора записей, соответствующих вызовам графических функций, таких как создание и выбор в контекст устройства пера или кисти, рисование линий, фигур, вывод текста, и иных операций.
При воспроизведении метафайлов достигается такой же результат, как и при непосредственном использовании функций GDI. Разница между их воспроизведением и непосредственным вызовом функций состоит в том, что метафайлы могут храниться в памяти или в файлах на диске, загружаться и воспроизводиться приложением столько раз, сколько это нужно.
Метафайлы используются для передачи изображений между программами через буфер обмена, а также для сохранения изображений в виде файлов на диске. Для их хранения требуется значительно меньше места, чем для хранения растровых изображений. В то же время для отображения метафайлов требуется обычно больше времени, чем для вывода растровых изображений.
Поскольку метафайл описывает изображение в терминах команд графического вывода, то изображение может быть масштабировано при воспроизведении без потери разрешения. Для битовых образов масштабирование всегда связано с потерей качества изображения.
Первоначальный 16-битный формат метафайлов WMF1 появился в Windows 2.O. Однако этот формат был аппаратно-зависимым и не содержал информацию о размерах изображения, поэтому его использование было связано со многими проблемами. В Win32 появился новый 32-битный формат EMF (Enhanced Metafile Format). Расширенные метафайлы содержат дополнительную информацию о размерах изображения и цветовой палитре, что обеспечивает их аппаратную независимость. Кроме того, они поддерживают все 32-битные функции рисования. Win32 API позволяет использовать файлы форматов WMF и EMF.
Поскольку в новых приложениях рекомендуется использовать формат EMF, то в дальнейшем будут рассматриваться только расширенные метафайлы.


Окт 16 2009

Операции, не зависящие от шаблона кисти

таким операциям относятся NOTSRCERASE, SRCERASE, SRCINVERT, SRCAND, MERGEPAINT и SRCPAINT. Следует отметить, что операции SRCINVERT и SRCAND используются системой Windows для отображения пиктограмм и курсоров мыши.
Рассмотрим, например, механизм отображения пиктограмм, которым пользуется Windows. Ресурсы предопределенных пиктограмм хранятся в динамически загружаемой библиотеке SheU.32.dll. Доступ к библиотеке можно получить, загрузив ее в приложение при помощи функции LoadLibrary, которая возвращает дескриптор экземпляра модуля (hShell32), содержащего соответствующие растровые изображения. Затем, используя индекс пиктограммы, можно загрузить любую пиктограмму из модуля hShell32. Для этого достаточно вызвать функцию Loadlmage. Например, если передать функции Loadlmage индекс 12, то будет загружена пиктограмма, обозначающая привод CD-ROM.
Функция Loadlmage в случае успешного завершения возвращает дескриптор пиктограммы hlcon. Затем при помощи вызова
GetIconInfo(hIcon, &iconInfo); можно получить информацию о загруженной пиктограмме, сохранив ее в переменной iconlnfo типа IC0NINF0. Для нас в этой структуре интересны два поля:
HBITMAP hbmMask; HBITMAP hbmColor;
Первое из этих полей содержит дескриптор растра, представляющего собой маску пиктограммы, второе поле — дескриптор растра, представляющего собой изображение пиктограммы.
Оба растра имеют размеры 48 х 48. Но для чего нужны эти два растра? Дело в том, что при выводе пиктограммы в виде прямоугольной области некоторые пикселы этой области должны изменяться, а некоторые должны остаться прежними. Изменяемая область называется непрозрачной, и в маске ей соответствует черный цвет. Остальные пикселы образуют прозрачную область — в маске ей соответствует белый цвет.


Окт 16 2009

Операции, зависящие только от источника

К таким операциям относятся SRCC0PY и N0TSRCC0PY.
Операция SRCC0PY уже использовалась ранее в примерах. Она просто копирует пикселы источника в приемник. Обычно эта операция применяется для отображения растра в исходном цвете.
Операция N0TSRCC0PY копирует в приемник цвет, противоположный цвету источника.


Окт 16 2009

Тернарные растровые операции

Последний параметр, dwRop, в функциях BitBlt, PatBlt и Stretch Bit задает растровую операцию, которая указывает для GDI, как должны комбинироваться биты исходного изображения с битами изображения-приемника и с битами шаблона текущей кисти. Результат операции определяет новое состояние изображения-приемника. Поскольку число операндов равно трем, то операция относится к классу тернарных операций.
В Win32 API существует 256 ROP-кодов (raster-operation codes). Растровые операции кодируются 32-разрядными двойными словами DWORD. В старшем слове хранится один из 256 однобайтных кодов растровой операции, а младшее слово содержит кодировку формулы, по которой растровая операция реализуется драйвером графического устройства.
Разработчики Microsoft присвоили символические имена только пятнадцати тернарным растровым операциям из 256. Видимо, это как раз те операции, которые использует операционная система.


Окт 16 2009

Отображение DIB-секции

Для вывода DIB-секции на поверхность графического устройства можно использовать два подхода: вывод как DIB-растра при помощи функции Stretch DIBits или SetDIBitsToDevice;
вывод как растрового объекта GDI, заданного дескриптором hBitmap, с использованием совместимого контекста устройства и функции BitBlt или Stretch Bit. Пример использования DIB-секций приведен в приложении ArincReceiver .


Окт 16 2009

Прямой доступ к пикселам со стороны приложения

Прямой доступ к пикселам со стороны приложения реализуется точно так же, как и при работе с DIB-растром .
Применительно к DIB-секциям аналогичный доступ реализован в классе KDibSection, в связи с решением проблемы рисования в реальном времени .


Окт 16 2009

Создание DIB-секции

Основные характеристики создаваемого растра задаются в структуре типа BITMAPINFO, адрес которой передается второму параметру функции. В этой структуре необходимо указать ширину, высоту, цветовую глубину и тип сжатия. DIB-секции поддерживают только тип BI_RGB, то есть только несжатые растры. Также задаются битовые маски, если они нужны, и цветовая таблица, если она используется.
Параметр iUsage определяет тип данных, содержащихся в массиве bmiColors, который является членом структуры BITMAPINFO. Если параметр iUsage имеет значение DIB_PAL_C0L0RS, то цветовая таблица bmiColors содержит индексы логической палитры. Значение DIB_RGB_C0L0RS указывает, что цветовая таблица содержит значения в формате RGB.
Параметр ppvBits содержит адрес переменной-указателя, в который GDI заносит адрес массива пикселов DIB-секции.
Параметр hSection может быть равен NULL. В этом случае GDI выделяет память под массив пикселов из виртуальной памяти приложения, а параметр dwOffset игнорируется. Если параметр hSection не равен NULL, то он должен быть дескриптором объекта файла, отображаемого на память, который был создан вызовом функции CreateFileMapping с флагами PAGE_READWRITE или PAGE_WRITECOPY. В этом случае размещение массива пикселов осуществляется в указанном файле со смещением, определяемым параметром dwOffset.


Окт 16 2009

Функции блиттинга

Для поддержки блиттинга GDI использует функции BitBlt и StretchBlt. Рассмотрим подробнее первую из них.
Название функции BitBlt происходит от слов «bit block transfer», означающих «перенос битового блока». На самом деле функция BitBlt позволяет делать намного больше, чем просто перенос блока пикселов. Эта функция может выполнить одну из 256 логических растровых операций над тремя наборами пикселов. Прототип функции имеет следующий вид:
BOOL BitBlt(HDC hdcDest, int nXDest, int nYDest. int nWidth. int nHeight. HDC hdcSrc, int nXSrc, int nYSrc. DWORD dwRop);
Функция BitBlt передает прямоугольный блок пикселов с поверхности устройства-источника hdcSrc на поверхность устройства-приемника hdcDest Исходный прямоугольник определяется параметрами nXSrc, nYSrc, nWidth, nHeight в логической системе координат контекста устройства-источника. Приемный прямоугольник определяется параметрами nXDest, nYDest, nWidth, nHeight в логической системе координат контекста устройства-приемника. Оба контекста устройства должны поддерживать растровые операции RC_BITBLT.
Из списка параметров функции видно, что ширина и высота исходного и приемного прямоугольников задаются одними и теми же параметрами — nWidth и nHeight. Поэтому если в устройстве-приемнике и в устройстве-источнике установлен режим отображения по умолчанию ММ_ТЕХТ, в котором логические единицы совпадают с физическими единицами, то перенос блока пикселов происходит без масштабирования.
В других режимах отображения исходный и приемный прямоугольники могут иметь разные размеры в системах координат устройства. В таком случае исходное изображение масштабируется по размерам приемного прямоугольника.
Контексты устройства-источника и устройства-приемника не обязательно должны быть разными. Функцию BitBlt можно применять и для переноса блока пикселов в пределах той же поверхности, на которой находится исходный прямоугольник.
Последний параметр dwRop задает тернарную растровую операцию, то есть способ объединения исходного пиксела, приемного пиксела и кисти для формирования нового значения приемного пиксела. Эти операции будут рассмотрены позже, а пока что будет использоваться простейшая растровая операция SRCC0PY, которая просто заменяет пикселы приемника значениями пикселов источника.
Вторая функция блиттинга Stretch Bit имеет следующий прототип:
BOOL StretchBlKHDC hdcDest. int nXDest, int nYDest. int nWidthDest. int nHeightDest. HDC hdcSrc, int nXSrc. int nYSrc. int nWidthSrc, int nHeightSrc. DWORD dwRop):
Она делает практически то же самое, что и функция BitBlt, но в списке параметров размеры исходного и приемного прямоугольников определяются независимо друг от друга. Это позволяет задавать масштабирование при переносе блока пикселов, когда исходный и приемный прямоугольники имеют разные размеры в логических координатах.


Окт 16 2009

Отображение DDB-pacтpa

Несмотря на то что DDB-растры играют важную роль в Windows-программировании, в Win32 API нет функции для непосредственного отображения DDB. В GDI задача отображения DDB решается обобщенно, как задача пересылки прямоугольного массива пикселов с одного графического устройства {устройства-источника) на другое графическое устройство {устройство-приемник).
При отображении растра устройством-приемником обычно является экран дисплея, и его представителем выступает контекст дисплея.
А что в этом случае является устройством-источником? В роли этого устройства выступает виртуальное графическое устройство, имитируемое в памяти в виде растра. Для его представления в GDI предусмотрен контекст устройства в памяти (или совместимый контекст). В главе 2 была дана краткая характеристика этого вида контекста устройства. Напомним, что совместимый контекст создается следующей функцией:
HDC CreateCompatibleDC (HDC hdc): где hdc — дескриптор существующего контекста устройства, с которым должен быть совместим создаваемый контекст. Функция CreateCompatibleDC может использоваться только с устройствами, поддерживающими растровые операции. Чаще всего hdc является дескриптором контекста дисплея, который относится к клиентской области окна приложения. Если этот параметр имеет значение NULL, то функция создает контекст в памяти, совместимый со всем экраном дисплея. Если функция завершается успешно, то она возвращает дескриптор совместимого контекста устройства.
Когда совместимый контекст устройства создан, с ним по умолчанию связан монохромный растр из одного пиксела. Поэтому, прежде чем использовать этот контекст, необходимо выбрать в него DDB-растр при помощи функции SelectObject.


Следующая страница »