Из этой статьи Вы узнаете, как поместить текст во внутреннюю область окна, а также получите представление о контексте устройства.

Сущность текста

     Текст в Wndows является объектом GDI (Graphic Device Interface). Обычно Вы отображаете его во внутренней области вашего окна (вообще, Вы можете поместить текст и вне вашего окна, но об этом поговорим в другой раз). Вывод текста в DOS и Windows сильно различается: в DOS окно представляется таблицей 80х25 символов и целиком используется одной программой; в Windows все программы соместно используют экран, поэтому, необходимы правила, по которым одно окно не могло бы искажать информацию, выводимую в других. В Windows это обеспечивается путем ограничения области вывода программы внутренней областью окна. Размер внутренней области определяется при создании окна, но затем может быть изменен  по вашему желанию.

     Прежде чем рисовать что-либо в окне Вы должны получить от Windows разрешение на эту операцию. При выводе Вам не нужно полностью контролировать весь экран, Вы просто посылаете в Windows запрос на рисование во внутренней области окна. Windows определяет размер внутренней области окна, шрифт, цвета и прочие аттрибуты программного интерфейса и возвращает Вам указатель на контекст отображения. После этого Вы можете использовать этот контекст отображения для рисования.

Контекст отображения

     Давайте определим понятие контекста устройства и контекста отображения. Контекст устройства выступает в роли связующего звена между приложением и драйвером устройства и представляет собой структуру данных размером примерно 800 байт. Эта структура данных содержит информацию о том, как нужно выполнять операции вывода на данном устройстве (цвет и толщину линий, тип системы координат и т.д.).

     Если приложение получает или создает контекст для устройства отображения, такой контекст называется контекстом отображения. Поэтому когда, например, приложение получает контекст для отображения в одном из своих окон, такой контекст называется, контекстом отображения. Если же ему требуется выполнять операцию вывода для устройства (для принтера или для экрана дисплея), приложение должно получить или создать контекст устройства. Однако следует понимать, что контексты устройства и отображения содержат описания одних и тех же характеристик и имеют одинаковую структуру. Название контекста определяется только тем, относится ли контекст к окну отображения или устройству вывода.

Атрибуты контекста отображения

     В документации, которая поставляется в составе 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 приложение может выбрать для вывода текста любой другой шрифт, установленный (зарегистрированный) в операционной системе.

Расстояние между буквами

     По умолчанию при выводе текста расстояние между буквами (intercharacter spacing), заданное в контексте отображения, равно 0 Для вывода текста вразрядку приложение может вызвать функцию SetTextCharacterExtra, установив дополнительное расстояние между буквами.

Цветовая палитра

     Цветовая палитра (color palette) - это таблица цветов. Некоторые устройства отображения способны работать с десятками тысяч цветов, однако из-за ограничений аппаратуры в них можно использовать одновременно только некоторые из них. Типичный пример - видеоконтроллеры SVGA в режиме отображения 256 цветов Приложения Windows могут составить для себя палитру из 236 цветов (20 цветов используются системой) и использовать ее для вывода таких изображении, как, например, цветные фотографии, преобразованные в двоичные данные при помощи сканера. Работа с палитрами - сложная задача, требующая учета многочисленных тонкостей. Современные адаптеры True Color способны отображать более 16 млн. цветов одновременно, поэтому для них механизм цветовых палитр не используется.

Кисть

     Для закрашивания внутренней области окна приложения или замкнутой геометрической фигуры можно использовать не только различные цвета, но и графические изображения небольшого (8х8 пикселов) размера - кисти (brush). Вы можете выбрать в контекст отображения предопределенною в Windows или свою кисть, использовав ее для закраски внутренних областей фигур или окна приложения. По умолчанию в контекст отображения выбрана кисть белого цвета. Функции выбора кисти CreateSolidBrush, CreateHatchBrush, SelectObject, CreatePatternBrush, CreateDIBPatternBrush, CreateBrushIndirect.

Начальные координаты кисти

     Начальные координаты кисти (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. Это функции CreateBitmapIndirect, CreateCompatibleBitmap, CreateBitmap. Приложения Windows широко пользуются изображениями bitmap, так как они очень удобны для отображения небольших пиктограмм или больших и сложных многоцветных рисунков, полученных при помощи специальных графических редакторов или сканеров.

Режим растяжения

     Приложение Windows может копировать прямоугольные участки изображений bitmap, выполняя при этом масштабирование, то есть сжатие или растяжение. Для такого копирования может быть использована, например, функция StretchBlt, которую мы рассмотрим в главе, посвященной изображениям bitmap. Режим растяжения (stretching mode) влияет на способ, с помощью которого происходит масштабирование изображения bitmap. По умолчанию используется режим BLACKONWHITE, при котором два или большее количество соседних пикселов преобразуются в один пиксел при помощи логической операции ИЛИ. В результате такого преобразования получается черный пиксел, если в исходном изображении любой пиксел из преобразуемой группы имеет черный цвет. Чтобы получился белый пиксел, все пикселы исходного изображения в преобразуемой группе пикселов должны быть белого цвета. В режиме BLACKONWHITE черный цвет преобладает над белым цветом. Вы можете изменить режим растяжения, вызвав SetStretchBltMode. При использовании режима WHITEONBLACK пикселы объединяются при помощи логической операции ИЛИ, при этом в полученном изображении будет преобладать белый цвет. В режиме COLORONCOLOR в процессе преобразования могут быть полностью удалены отдельные строки или столбцы пикселов, что иногда дает хорошие результаты. Однако, как правило, масштабирование изображений bitmap приводит к существенному ухудшению качества при любом режиме растяжения.

Область ограничения

     По умолчанию в контексте отображения задана область ограничения вывода (clipping region), совпадающая со всей областью вывода. Например, если приложение получило контекст отображения для окна, область ограничения совпадает с внутренней областью (client region) этого окна. Приложение может создавать область ограничения вывода сложной, практически произвольной, формы, исключая или включая в нее области в виде многоугольников или эллипсов. Это позволяет получить при отображении интересные эффекты, труднодостижимые без использования областей ограничения (правда, ценой снижения скорости вывода изображения). Для работы с областями предназначены функции CreateEllipticRgn, CreateEllipticRgnIndirect, CreateRectRgn, CreatePolygonRgn, CreatePolyPolygonRgnExcludeClipRgn, IntersectClipRgn, OffsetClipRgn, SelectclipRgn.

Режим отображения

     Режим отображения, установленный в контексте отображения, влияет на систему координат. Устанавливая различные режимы отображения, приложение может изменять направление и масштаб координатных осей. По умолчанию в контексте отображения установлен режим отображения ММ_ТЕХТ. Для этого режима начало системы координат находится в верхнем левом углу внутренней области окна. Ось Х направлена вправо, ось Y - вниз. В качестве единицы измерения используется пиксел. Такой режим отображения удобен для вывода текста В самом деле, мы читаем текст слева направо и сверху вниз (хотя в некоторых странах текст читают справа налево и снизу вверх). Иногда удобнее использовать обычную систему координат, в которой ось Х направлена слева направо, а ось Y - снизу вверх. Вы можете выбрать один из нескольких режимов отображения с таким направлением осей. В качестве единицы измерения можно использовать сотые и тысячные доли дюйма, сотые и десятые доли миллиметра и другие величины. С помощью функции SetMapMode приложение может установить в контексте режим отображения, удобный для решения той или иной задачи.

Начало системы координат для окна

     В контексте отображения хранится информация о расположении начала системы координат для окна и для физического устройства отображения. Эта информация используется GDI при выполнении преобразования логических координат в физические, которое выполняется различными способами в зависимости от установленного режима отображения. По умолчанию начало системы координат для окна (window origin) установлено в точку (0, 0). Для перемещения начала системы координат окна можно использовать функцию SetWindowOrg.

Начало системы физических координат

     Начало системы физических координат (viewport origin) относится не к окну приложения, а к физическому устройству вывода (например, ко всему экрану монитора) и используется при выполнении преобразования логических координат в физические. По умолчанию начало системы физических координат установлено в точку (0, 0). Для перемещения начала системы координат окна можно использовать функцию SetViewportOrg.

Масштаб осей для окна

     Для некоторых режимов отображения приложение может изменять масштаб осей в окне (window extent), устанавливая для него новое значение в контексте отображения. По умолчанию используется значение (1, 1), то есть масштаб 1:1. Приложение может изменить масштаб осей для окна, вызвав функцию SetWindowExt.

Масштаб осей физических координат

     Контекст отображения содержит масштаб осей для физического устройства (viewport extent), который вместе с масштабом осей в окне используется в процессе преобразования координат. По умолчанию для масштаба осей физических координат используется значение (1, 1), то есть масштаб 1:1. Приложение может изменить масштаб осей физических координат, вызвав функцию SetViewportExt.

Инструменты для рисования

     Итак, теперь Вы узнали, на чем рисовать в своем приложении. Теперь посмотрим, какие инструменты оно может использовать. Для рисования в распоряжении приложений Windows есть перья, кисти, текстовые шрифты и битовые изображения. Разумеется, все эти инструменты могут быть черно-белые или цветные, причем цветовое разрешение определяется в основном только возможностями видеоконтроллера. Расскажем кратко об основных особенностях и областях применения перечисленных выше инструментов.

Перья

     Перья используются для рисования линий и простейших геометрических фигур. Приложение может выбрать одно из трех предопределенных перьев либо создать собственное, выбрав нужный цвет и стиль. Как мы уже говорили, интерфейс GDI операционной системы Windows позволяет рисовать сплошные линии различной ширины, а также пунктирные, штриховые и штрихпунктирные линии шириной в 1 пиксел.

Кисти

     Внутренняя область окна и замкнутых геометрических фигур может быть закрашена при помощи кисти. С помощью функции GetStockObject можно выбрать черную, белую, темно- или светло-серую кисть или нулевую кисть (null brush). Можно выбрать одну из китей предназначенных для штриховки, для чего следует использовать функцию CreateHatchBrush. Все эти кисти встроены в операционную систему. Если вас не устраивает ни одна из встроенных кистей, вы можете создать собственную, определив ее как изображение bitmap размером 8х8 пикселов. Такая кисть может иметь любой внешний вид и любой цвет.

Шрифты

     Для того чтобы рисовать текст, используются шрифты. Операционная система Windows может работать с растровыми, векторными и масштабируемыми шрифтами. Кроме этого приложения Windows могут испотьзовать шрифты, встроенные в устройство вывода (обычно это принтерные шрифты). Растровые шрифты содержат битовые образы всех символов. Для каждого размера шрифта необходимо иметь свой набор символов. Кроме того, различные устройства вывода имеют разное соотношение горизонтальных и вертикальных размеров пиксела, что приводит к необходимости хранить отдельные наборы образов символов не только для разных размеров шрифта, но и для разного соотношения размеров пиксела физическою устройства отображения. Растровые шрифты плохо поддаются масштабированию, так как при этом наклонные линии контура символа принимают зазубренный вид. Векторные шрифты хранятся в виде набора векторов, описывающих отдельные сегменты и линии контура символа, поэтому они легко масштабируются. Однако их внешний вид далек от идеального. Как правило, векторные шрифты используются для вывода текста на векторные устройства, такие, как плоттер. Масштабируемые шрифты TrueType впервые появились в Windows версии 3.1 и сильно способствовали росту популярности этой операционной системы Шрифты TrueType поддаются масштабированию без существенных искажений внешнего вида.  Помимо обычных шрифтов существуют символьные или декоративные шрифты, содержащие вместо букв различные пиктограммы. Например, стандартный масштабируемый шрифт Wingdings, который поставляется в составе Windows. Прежде чем использовать шрифт, его надо выбрать в коктекст отображения.

Битовые изображения

     Если вам нужно вывести на экран сложное изображение, полученное при помощи сканера и содержащее множество мелких деталей, едва ли имеет смысл рисовать его при помощи перьев и кистей. Хотя последнее и возможно, такая процедура будет выполняться слишком долго. В битовом изображении bitmap каждый пиксел представлен своим цветом. Есть черно-белые и цветные изображения, изображения, рассчитанные на определенный тип устройства вывода (использовались в ранних версиях Windows) и не зависящие от типа устройства вывода (впервые появились в Windows версии 3.0). Рисование битовых изображений выполняется путем копирования соответствующего массива графических данных в видеопамять. Разумеется, приложение не имеет непосредственного доступа к видеопамяти. Для выполнения операции копирования приложение обращается к GDI, вызывая соответствующую функцию. Как правило, копирование битовых изображений выполняется не GDI, а драйвером или даже аппаратурой видеоконтроллера, что благоприятно сказывается на скорости выполнения операции вывода. Работа с битовыми изображениями не самое простое из того, что может быть в программировании для Windows. Особенно это касается использования битовых изображений в формате, не зависящем от типа устройства вывода, или содержащих цветовые палитры. Ситуация дополнительно усложняется отсутствием единого формата bmp-файлов, содержащих изображения, и необходимостью (в профессиональных приложениях) распознавать bmp-файлы, подготовленные в операционной системе OS/2, а также контролировать формат bmp-файлов. Однако только битовые изображения дают возможность получить на экране компьютера красивые рисунки, приближающиеся (на хороших мониторах) по качеству к слайдам, а также работать с движущимися изображениями.