Графический интерфейс GDI в Microsoft Windows© Александр Фролов, Григорий ФроловТом 14, М.: Диалог-МИФИ, 1993, 288 стр. 1.1. Контекст отображенияИтак, займемся описанием "листа бумаги", на "поверхности" которого выполняется рисование графических изображений и текста - контекста отображения. Прежде всего уточним понятия контекста отображения и контекста устройства . Контекст устройства выступает в роли связующего звена между приложением и драйвером устройства (рис. 1.1) и представляет собой структуру данных размером примерно 800 байт. Эта структура данных содержит информацию о том, как нужно выполнять операции вывода на данном устройстве (цвет и толщину линии, тип системы координат и т. д.).
Рис. 1.1. Вывод данных через контекст устройства Если приложение получает или создает контекст для устройства отображения, такой контекст называется контекстом отображения. Поэтому когда, например, приложение получает контекст для отображения в одном из своих окон, такой контекст называется контекстом отображения. Если же ему требуется выполнять операцию вывода для устройства (для принтера или для экрана дисплея), приложение должно получить или создать контекст устройства. Однако следует понимать, что контексты устройства и отображения содержат описания одних и тех же характеристик и имеют одинаковую структуру. Название контекста определяется только тем, относится ли контекст к окну отображения или устройству вывода. Атрибуты контекста отображенияВ документации, которая поставляется в составе Microsoft SDK, описаны 20 атрибутов контекста отображения . Несколько атрибутов описывают систему координат, используемую для рисования графических изображений. Есть атрибуты, влияющие на цвет графических объектов и цвет фона. Для отображения можно выбрать цветовую палитру (набор цветов). Можно выбрать инструмент для рисования линий и закрашивания внутренней области замкнутых геометрических фигур, таких как многоугольники и эллипсы. Приложение может рисовать внутри области произвольной формы (или вне этой области), причем область также задается в контексте отображения. Есть атрибуты, специально предназначенные для вывода текста. Это шрифт и расстояние между символами, а также цвет текста. Когда приложение получает контекст отображения или создает контекст устройства, все атрибуты контекста имеют значения, установленные по умолчанию. Для того чтобы вы получили представление о назначении атрибутов контекста отображения, приведем их краткое описание. Цвет фонаПродолжая аналогию между контекстом отображения и листом бумаги, на котором рисуются графические изображения и пишется текст, можно сказать, что атрибут цвета фона (background color ) в контексте отображения соответствует цвету бумаги. Чаще всего для рисования и письма используется белая бумага, вероятно поэтому по умолчанию в контексте отображения выбран фон белого цвета. Приложение может изменить цвет фона, воспользовавшись функцией SetBkColor . Мы опишем эту, а также другие функции, связанные с цветом, в отдельной главе. Режим фонаВы можете установить два режима фона (background mode ) - непрозрачный (OPAQUE ) и прозрачный (TRANSPARENT ), вызвав функцию SetBkMode. По умолчанию выбран режим непрозрачного отображения, при котором в процессе вывода цвет фона удаляется. Например, приложение создало окно с синим фоном и выводит в нем строку текста черного цвета. В этом случае в режиме OPAQUE вы увидите черные буквы внутри горизонтальной полосы белого цвета, имеющей высоту, равную высоте букв. Если в этом режиме нарисовать пунктирную линию черного цвета на синем фоне, то цвет промежутка между штрихами линии будет не синий, а белый. В прозрачном режиме TRANSPARENT аналогия с листом бумаги синего цвета и черным карандашом будет полная. При выводе текста в описанной выше ситуации вы увидите черные буквы на синем фоне. Режим рисованияКогда вы рисуете что-нибудь на бумаге обычным карандашом или фломастером, цвет получившегося изображения соответствует цвету выбранного вами карандаша или фломастера. Иными словами, цвет копируется из инструмента, выбранного для рисования. Именно такой режим рисования (drawing mode) выбран по умолчанию в контекст отображения. При этом новое изображение полностью замещает (закрашивает) то, что находится под ним. Приложение Windows может выбрать и другие режимы рисования, например, рисование инвертированием цвета фона, рисование черным или белым цветом, рисование с использованием логической операции "ИСКЛЮЧАЮЩЕЕ ИЛИ" или выбрать десятки других вариантов. Например, при выделении участка графического изображения (которое может быть любого цвета) приложение может рисовать рамку, размеры которой определяются перемещениями мыши. Для того чтобы рамка была видна вне зависимости от цвета изображения, при рисовании рамки можно использовать инвертирование цвета фона или операцию "ИСКЛЮЧАЮЩЕЕ ИЛИ". Для того чтобы выбрать режим рисования , приложение должно использовать функцию SetROP2 . Цвет текстаПо умолчанию в контексте отображения для вывода текста выбран черный цвет. Поэтому, если вы не изменили ни одного атрибута контекста отображения, связанного с текстом и цветом, такие функции, как TextOut и DrawText будут выводить черный текст на белом фоне в непрозрачном режиме. Для выбора цвета текста приложение должно использовать функцию SetTextColor . ШрифтКонтекст отображения содержит информацию о том, какой шрифт (font ) используется для вывода текста. По умолчанию текст выводится системным шрифтом с переменной шириной букв в кодировке ANSI. С помощью функций CreateFont , CreateFontIndirect и SelectObject приложение может выбрать для вывода текста любой другой шрифт, установленный (зарегистрированный) в операционной системе. Для установки шрифта, как вы знаете, следует использовать приложение Control Panel. Расстояние между буквамиПо умолчанию при выводе текста расстояние между буквами (intercharacter spacing ), заданное в контексте отображения, равно 0. Для вывода текста "вразрядку" приложение может вызвать функцию SetTextCharacterExtra , установив дополнительное расстояние между буквами. Цветовая палитраЦветовая палитра (color palette ) - это таблица цветов. Некоторые устройства отображения способны работать с десятками тысяч цветов, однако из-за ограничений аппаратуры в них можно использовать одновременно только некоторые из них. Типичный пример - видеоконтроллеры SVGA в режиме отображения 256 цветов. Приложения Windows могут составить для себя палитру из 236 цветов (20 цветов используются системой) и использовать ее для вывода таких изображений, как, например, цветные фотографии, преобразованные в двоичные данные при помощи сканера. Использование цветовых палитр мы рассмотрим позже. Отметим только, что работа с палитрами - сложная задача, требующая учета многочисленных тонкостей. Современные адаптеры True Color способны отображать более 16 млн. цветов одновременно, поэтому для них механизм цветовых палитр не используется. Для работы с палитрами в составе программного интерфейса определены такие функции, как CreatePalette , SelectPalette , RealizePalette , UnrealizeObject . КистьДля закрашивания внутренней области окна приложения или замкнутой геометрической фигуры можно использовать не только различные цвета, но и графические изображения небольшого (8х8 пикселов) размера - кисти (brush ). В предыдущих томах "Библиотеки системного программиста" мы использовали кисть для закрашивания внутренней области окна, указав ее при регистрации класса окна. Вы можете выбрать в контекст отображения предопределенную в Windows или свою кисть, использовав ее для закраски внутренних областей фигур или окна приложения. По умолчанию в контекст отображения выбрана кисть белого цвета. Для выбора кисти предназначены функции CreateSolidBrush , CreateHatchBrush , CreatePatternBrush , CreateDIBPatternBrush , CreateBrushIndirect , SelectObject . Начальные координаты кистиНачальные координаты кисти (brush origin ) используются для определения координат точки внутри кисти, которая будет служить начальной при закраске внутренней области фигуры или окна. По умолчанию используются координаты (0,0), соответствующие верхнему левому углу кисти (в системе координат, выбранной в контекст отображения по умолчанию). Приложение может изменить начальные координаты кисти при помощи функций SetBrushOrg и UnrealizeObject . Режим закрашивания многоугольниковСуществует два режима закрашивания сложных самопересекающихся многоугольников (polygon-filling mode ): альтернативный (ALTERNATE ), выбранный в контекст отображения по умолчанию, и режим заполнения (WINDING ). В режиме заполнения область самопересечения закрашивается. В альтернативном режиме закрашиваются только области между нечетными и четными сторонами многоугольника, в результате чего область пересечения может оказаться либо закрашенной, либо незакрашенной. Для изменения режима закрашивания многоугольников предназначена функция SetPolyFillMode . ПероДля того чтобы нарисовать линию или геометрическую фигуру, приложение Windows должно создать собственное перо (pen ) или воспользоваться пером, выбранным в контекст отображения по умолчанию (черное перо шириной в один пиксел). Можно создать новое перо, изменив его ширину, цвет или стиль (сплошная, пунктирная, штриховая и штрих-пунктирная линии, а также линия, в которой на одну черточку приходится по две точки). К сожалению, вы можете изменить ширину только сплошной линии. Для работы с перьями приложение Windows должно использовать функции CreatePen , CreatePenIndirect , SelectObject . Текущая позиция пераДля рисования линий в интерфейсе GDI предназначена функция LineTo, которая использует понятие текущей позиции пера (current pen position ). Функция LineTo рисует линию из точки, соответствующей текущей позиции пера в точку, указанную при помощи параметров. Для установки текущей позиции пера предназначена функция MoveTo . По умолчанию текущая позиция пера равна значению (0,0), что в системе координат, выбранной по умолчанию, соответствует верхнему левому углу внутренней области окна. Заметим, что текущая позиция используется интерфейсом GDI только для рисования линий. Изображение bitmapВ контекст отображения можно выбрать изображение bitmap и затем отобразить его в окне или использовать в меню. Мы будем обсуждать изображения bitmap в отдельной главе этого тома. Сейчас отметим, что по умолчанию в контекст отображения не выбирается никакое изображение bitmap. Приложение должно выбрать его самостоятельно, используя функцию SelectObject . В программном интерфейсе GDI имеются и другие функции для работы с изображениями bitmap. Это функции CreateBitmap , CreateBitmapIndirect , CreateCompatibleBitmap . Приложения Windows широко пользуются изображениями bitmap, так как они очень удобны для отображения небольших пиктограмм или больших и сложных многоцветных рисунков, полученных при помощи специальных графических редакторов или сканеров. Заметим, что в предыдущих томах "Библиотеки системного программиста" мы использовали изображения bitmap для кнопок и органа управления Toolbar, отложив подробное их изучение на потом. Режим растяженияПриложение Windows может копировать прямоугольные участки изображений bitmap, выполняя при этом масштабирование, т. е. сжатие или растяжение. Для такого копирования может быть использована, например, функция StretchBlt, которую мы рассмотрим в главе, посвященной изображениям bitmap. Режим растяжения (stretching mode ) влияет на способ, с помощью которого происходит масштабирование изображения bitmap. По умолчанию используется режим BLACKONWHITE , при котором два или большее количество соседних пикселов преобразуются в один пиксел при помощи логической операции "ИЛИ". В результате такого преобразования получается черный пиксел, если в исходном изображении любой пиксел из преобразуемой группы имеет черный цвет. Для того чтобы получился белый пиксел, все пикселы исходного изображения в преобразуемой группе пикселов должны быть белого цвета. В режиме BLACKONWHITE черный цвет преобладает над белым цветом. Вы можете изменить режим растяжения, вызвав функцию SetStretchBltMode . При использовании режима WHITEONBLACK пикселы объединяются при помощи логической операции "ИЛИ", при этом в полученном изображении будет преобладать белый цвет. В режиме COLORONCOLOR в процессе преобразования могут быть полностью удалены отдельные строки или столбцы пикселов, что иногда дает хорошие результаты. Однако, как правило, масштабирование изображений bitmap приводит к существенному ухудшению качества при любом режиме растяжения. Область ограниченияПо умолчанию в контексте отображения задана область ограничения вывода (clipping region ), совпадающая со всей областью вывода. Например, если приложение получило контекст отображения для окна, область ограничения совпадает с внутренней областью (client region) этого окна. Приложение может создавать область ограничения вывода сложной, практически произвольной, формы, исключая или включая в нее области в виде многоугольников или эллипсов. Это позволяет получить при отображении интересные эффекты, труднодостижимые без использования областей ограничения (правда, ценой снижения скорости вывода изображения). Для работы с областями предназначены следующие функции: CreateEllipticRgn , CreateEllipticRgnIndirect , CreatePolygonRgn , CreatePolyPolygonRgn , CreateRectRgn , CreateRoundRectRgn , ExcludeClipRgn , IntersectClipRgn , OffsetClipRgn , SelectclipRgn . Режим отображенияРежим отображения, установленный в контексте отображения, влияет на систему координат. Устанавливая различные режимы отображения , приложение может изменять направление и масштаб координатных осей. По умолчанию в контексте отображения установлен режим отображения MM_TEXT . Для этого режима начало системы координат находится в верхнем левом углу внутренней области окна. Ось x направлена вправо, ось y - вниз. В качестве единицы измерения используется пиксел. Такой режим отображения удобен для вывода текста. В самом деле, мы читаем текст слева направо и сверху вниз (хотя в некоторых странах текст читают справа налево и снизу вверх). Иногда удобнее использовать обычную систему координат, в которой ось x направлена слева направо, а ось y - снизу вверх. Вы можете выбрать один из нескольких режимов отображения с таким направлением осей. В качестве единицы измерения можно использовать сотые и тысячные доли дюйма, сотые и десятые доли миллиметра и другие величины. С помощью функции SetMapMode приложение может установить в контексте режим отображения, удобный для решения той или иной задачи. В операционной системе Windows NT можно выбрать и другие системы координат, например, с наклонным расположением осей. Начало системы координат для окнаВ контексте отображения хранится информация о расположении начала системы координат для окна и для физического устройства отображения. Эта информация используется GDI при выполнении преобразования логических координат в физические, которое выполняется различными способами в зависимости от установленного режима отображения. Подробнее этот вопрос будет рассмотрен при описании систем координат, доступных для приложений Windows версии 3.1. По умолчанию начало системы координат для окна (window origin ) установлено в точку (0,0). Для перемещения начала системы координат окна можно использовать функцию SetWindowOrg . Начало системы физических координатНачало системы физических координат (viewport origin ) относится не к окну приложения, а к физическому устройству вывода (например, ко всему экрану монитора) и используется при выполнении преобразования логических координат в физические. По умолчанию начало системы физических координат установлено в точку (0,0). Для перемещения начала системы координат окна можно использовать функцию SetViewportOrg . Масштаб осей для окнаДля некоторых режимов отображения приложение может изменять масштаб осей в окне (window extent ), устанавливая для него новое значение в контексте отображения. По умолчанию используется значение (1,1), т. е. используется масштаб 1:1. Приложение может изменить масштаб осей для окна, вызвав функцию SetWindowExt . Масштаб осей физических координатКонтекст отображения содержит масштаб осей для физического устройства (viewport extent ), который вместе с масштабом осей в окне используется в процессе преобразования координат. По умолчанию для масштаба осей физических координат используется значение (1,1), т. е. масштаб 1:1. Приложение может изменить масштаб осей физических координат, вызвав функцию SetViewportExt . |