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

Метки:  , , ,

В ранних ПК и операционных системах, аппаратная и программная части отображения информации были реализованы таким образом, что вывод на экран [монитора] мог осуществляться напрямую любой исполняющейся в данный момент программой (кодом). При дальнейшем развитии технологий, в частности эволюции многозадачных операционных систем семейства Windows, с целью сохранения целостности/контроля ОС, возможность прямого неконтролируемого вывода на экран (как это было во времена MSDOS) убрали. По причине того, что современные ОС являются многозадачными, то есть в них [псевдо]параллельно выполняются сразу множество процессов, отображение информации должно быть подчинено строгому регламенту. С целью обеспечения возможности вывода на устройство (экран, принтер, память) одновременно от множества источников (процессов/приложений), в Windows был разработан специализированный механизм под названием контекст устройства (device context, DC) и подмножество обеспечивающих его работу функций. Указанные функции определяют размер клиентской области, шрифт, цвета и другие GDI-атрибуты и возвращают (предоставляют) приложению так называемый дескриптор контекста устройства (Device Context Descriptor). Поскольку контекст устройства является одним из основополагающих понятий в понимании механизмов вывода информации на устройство, я постараюсь дать некоторое количество определений для погружения в тему:

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

В операционной системе Windows существует несколько типов контекстов устройства, а именно:

  • Контекст устройства отображения (display);
  • Контекст устройства печати (printer);
  • Контекст устройства памяти (memory, CompatibleDC);
  • Контекст информационного устройства (information);

Таким образом:

  • если приложение создает/получает собственный контекст для отрисовки в собственном окне, такой контекст называется контекстом устройства отображения.
  • если приложению необходимо выполнить операцию ввода-вывода на аппаратное устройство (экран, принтер, память), такой контекст называется контекстом устройства печати, контекстом устройства памяти или контекстом информационного устройства.
Все виды контекстов устройств имеют идентичную структуру и содержат одни и те же атрибуты (характеристики).

Нас же в рамках данной статьи интересует контекст устройства отображения:

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

Существует несколько типов контекста отображения:

  • Контекст отображения класса окна (class display context);
  • Общий контекст отображения (common display context);
  • Личный контекст отображения (private display context);
  • Контекст отображения окна (window display context);
  • Родительский контекст отображения (parent display context);

Соответственно, методы получения (освобождения) контекста отображения различны для контекстов описанных типов. И где же он непосредственно используется? В процессе изучения функционала GDI становится очевидным, что во многих WinAPI-функциях вывода графических примитивов в Windows одним из входных параметров является указатель на контекст устройства отображения.

В GDI все операции рисования должны выполняться через контекст устройства [отображения].

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

device context

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

Структура контекста устройства

Надо учитывать, что контекст устройства является структурой, состоящей, в свою очередь, из описателей объектов графических примитивов (характеристик), используемых при работе с контекстом:

Атрибут контекста Значение по умолчанию Функция для изменения Функция для получения
Режим отображения (Mapping mode) MM_TEXT SetMapMode GetMapMode
Начало координат окна (Window origin) (0,0) SetWindowOrgEx GetWindowOrgEx
Начало координат области вывода (Viewport Origin) (0,0) SetViewportOrgEx GetViewportOrgEx
Протяженность окна (Window extent) (1,1) SetWindowExtEx GetWindowExtEx
Протяженность области вывода (Viewport extent) (1,1) SetViewportExtEx, SetMapMode GetViewportExtEx
Перо (Pen) BLACK_PEN SelectObject SelectObject
Кисть (Brush) WHITE_BRUSH SelectObject SelectObject
Шрифт (Font) SYSTEM_FONT SelectObject SelectObject
Битовый образ (Bitmap) NOT SelectObject SelectObject
Текущая позиция пера (Current pen position) (0,0) MoveToEx, LineTo, PolylineTo, PolyBezierTo GetCurrentPositionEx
Режим фона (Background mode) OPAQUE SetBkMode GetBkMode
Цвет фона (Background color) Обычно Белый (по Панели управления) SetBkColor GetBkColor
Цвет текста (TextColor) Обычно Черный (по Панели управления) SetTextColor GetTextColor
Режим рисования (Drawing mode) R2_COPYPEN SetROP2 GetROP2
Режим растяжения (Stretching mode) BLACKONWHITE SetStrethBltMode GetStrethBltMode
Режим закрашивания многоугольников (Polygon filling mode) ALTERNATE SetPolyFillMode GetPolyFillMode
Межсимвольный интервал (Intercharacter spacing) 0 SetTextCharacterExtra GetTextCharacterExtra
Начало координат кисти (Brush origin) (0,0) SetBrushOrgEx GetBrushOrgEx
Область отсечения (Clipping region) Not. Окно (рабочая область) с обновляемым регионом обрезается. SelectObject, SelectClipRgn GetClipBox

Обычно данная структура содержит значения по умолчанию, определенные разработчиками из Microsoft.

Каждый DC имеет текущие параметры: кисть, перо, шрифт и так далее, то есть текущий (рабочий) объект определенного типа. Поэтому могут (к примеру) быть выбраны одновременно перо и кисть, но нельзя выбрать перо дважды.

Вы имеете возможность менять указанные атрибуты по собственному желанию уже после того, как получили дескриптор контекста устройства отображения. Но не надо забывать, что когда пользовательскому приложению требуется изменить какой-либо элемент структуры контекста устройства, оно должно производить эти действия исключительно через предназначенные для этого функции WinAPI, поскольку напрямую элементы структуры контекста устройства для изменения не доступны. Все описанные выше инструменты (и их параметры) доступны для выбора и переназначения, поскольку функции GDI используют только выбранные в контекст устройства параметры и инструменты рисования.

Соответственно, перед использованием того или иного графического объекта в контексте устройства, он должен быть предварительно "выбран" при помощи вышепривиденных (в таблице) функций.

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

Факт получения контекста устройства отображения можно воспринимать в виде своего рода негласного разрешения на отрисовку в собственной клиентской области окна. Как только вы получили контекст, то можете начинать рисовать.

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

Фактически дескриптор контекста устройства представляет собой число, которое является уникальным для каждого окна.

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

Контекст устройства отображения является критическим для системы ресурсом. Поэтому его необходимо освободить сразу по окончании использования.

Комментарии: 1

  1. Михаил

    Спасибо за статью

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *