68904

Понятие контекста устройства

Лекция

Информатика, кибернетика и программирование

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

Русский

2014-09-27

126 KB

9 чел.

Лекция 3 Контекст устройства

Понятие контекста устройства

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

Традиционно сложилась следующая схема вывода (рис. 3.1.).

Рис 3.1. Порядок графического вывода в ОС MS DOS

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

Данная схема хорошо работает в случае однозадачного режима, когда адресным пространством видео памяти владеет только одна программа. Поэтому, эта схема получила распространение в ОС типа MS DOS.

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

Контекст – структура данных, формируемая операционной системой, хранящая информацию о параметрах и характеристиках устройства вывода, посредством которого программа осуществляет графический вывод информации. Благодаря введению контекста процесс вывода информации изменился и имеет следующий вид (рис. 3.2):

Рис. 3.2. Схема графического вывода в ОС WINDOWS

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

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

Программная модель контекста

В программе (см. Лекцию 2) контекст представлен своим описателем и объявляется следующим образом:

HDC hdc;

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

Первый способ.

hdc = BeginPaint(hWnd, &ps); // Начать графический вывод

// графический вывод

. . . . . . . . . . .

EndPaint(hWnd, &ps); // Закончить графический вывод

Второй способ.

hdc = GetDC(hWnd); // Начать графический вывод

// графический вывод

. . . . . . . . . . .

ReleaseDC(hWnd, hdc); // Закончить графический вывод

Разница между первым и вторым способом будет пояснена ниже.

Параметр hWnd – описатель того окна, в котором требуется перерисовка. Описатель контекста позволяет программе рисовать только в пределах клиентской области окна, описатель которого использовался при его создании. В каждом окне выделяют несколько областей:

рабочая область – вся область, занимаемая окном на экране;

неклиентская область – включает стандартные элементы окна, которые, в общем случае, отрисовываюся операционной системой: рамка, строка заголовка, кнопки закрыти, минимизации и т.п., меню;

клиентская область – вся оставшаяся от неклиентской рабочая область окна.

Описатель контекста используется во всех функциях, связанных с графическим выводом. Приведем примеры функций, непосредственно связаных с рисованием:

 Rectangle(hdc, 20, 20, 100, 300);// рисует прямоугольник с указанными координатами верхней левой и нижней правой точками;

Ellipse(hdc, 20, 20, 100, 300); // рисует эллипс, вписанный в прямоугольник с указанными координатами;

LineTo(hdc, 20, 20); // рисует линию из текущих координат пера в указанные (понятие пера будет раскрыто позже в этой лекции).

Как видно из приведенных примеров, первый параметр у всех графических функций – описатель контекста устройства.

Действительные и недействительные области экрана

Обратимся еще раз к рисунку 3.2. Изображение с контекстов переносится  в видеопамять. С этого момента времени ОС считает, что ей известно содержимое части экрана, соответствующее данному окну. Если изменений в окнах программ не происходит, видео карта сама обновляет изображение на экране, периодически   выбирая его из видеопамяти. Области экрана, графическая информация о которых известна операционной системе, называются действительными.

В момент закрытия, открытия, передвижения окон на экране появляются "черные дыры" – области, информация об изображении которых потеряна ОС или неизвестна. Такие области экрана получили название недействительных областей.

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

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

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

Для управления действительными и недействительными областями существуют две функции:

InvalidateRect(hWnd, &rect, FALSE); // сделать недействительной область, ограниченную прямоугольником rect (при этом фон окна обновится, если третий параметр функции будет TRUE);

ValidateRect(hWnd, &rect); позволяет сделать любую прямоугольную область окна действительной.

Объекты и атрибуты контекста устройства

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

  1.  Перо (PEN) определяет цвет, ширину, стиль линии, которой выполняется рисование всеми функциями API.
  2.  Кисть (BRUSH) определяет цвет и режим фона, которыми заполняются пустоты.

Для использования объектов в программе, как уже говорилось ранее, используются описатели объектов, для создания которых существуют предопределенные типы описателей: HPEN (handle to pen) для пера и HBRUSH - для кисти. Таким образом, если в программе будет необходимо использовать данные объекты, прежде всего, необходимо определить переменные-описатели, например,

HPEN MyPen; // определение описателя пера.

HBRUSH MyBrush; // определение описателя кисти.

Оба приведенных выше объекта поддерживают три основных функции работы с ними:

  1.  Создание нового объекта.
  2.  Выбор объекта (из множества предопределенных в Windows).
  3.  Удаление объекта.

Рассмотрим подробнее эти объекты и функции работы с ними.

Перо (PEN) определяет цвет, ширину, стиль линии, которой выполняется рисование всеми функциями API. Перо, устанавливаемое в контексте устройства по умолчанию, называется BLACK_PEN (черное перо). Это перо рисует сплошные черные линии толщиной в один пиксел независимо от режима отображения (mapping mode). Windows поддерживает еще два стандартных пера – это WHITE_PEN(белое перо) и NULL_PEN(пустое перо, т.е. «рисующее» прозрачным цветом).

Получить описатель одного из стандартных (предопределенных в Windows)  перьев можно используя функции GetStockObject:

MyPen = GetStockObject(WHITE_PEN);

Переменной MyPen, в данном случае, присваивается адрес памяти, где расположена структура данных, соответствующая белому перу. Если  такого пера не существует, функция возвращает нулевой (NULL) описатель. Программа может использовать выбранную кисть через ее описатель MyPen.  Выбранное перо может использоваться в любом контексте, однако, для этого его нужно передать нужному контексту (ведь, в любой момент времени в контексте выбрано какое-то свое перо). Выбор пера в конкретный контекст осуществляется путем выполнения стандартной функции выбора объекта в контекст:

HPEN OldPen;

OldPen = SelectObject(hdc, MyPen);

Выполнив функцию SelectObject, мы тем самым устанавливаем в контексте hdc новое перо, и все функции рисования на этом контексте будут выполняться на основе этого пера. При это возникает вопрос: что при этом происходит со старым пером? Описатель старого пера возвращается в программу как результат функции SelectObject, а контекст "забывает" о существовании старого пера. На это следует обратить внимание, так как, если старое перо было перед этим создано вашей программой и не используется больше никем, оно останется в памяти компьютера как "мусор". Считается хорошим стилем программирования, если программа после работы с контекстом возвращает старые объекты в контекст после завершения работы с контекстом, и сама уничтожает созданные ею объекты. Однако, если старое перо не было создано Вашей программой, удалять его нельзя.

Создать новое перо можно при помощи функции CreatePen:

MyPen = CreatePen(iPenStyle, iWidth, rgbColor);

Параметр iPenStyle определяет тип линии и может иметь одно из следующих значений:

Значение iPenStyle

Тип линии

PS_SOLID

PS_DASH

PS_DOT

PS_DASHDOT

PS_ DASHDOTDOT

PS_INSIDEFRAME

Параметр iWidth определяет ширину линии в пикселях (если значение этого параметра 0 – ширина линии равна одному пикселю).

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

Последняя операция, доступная пользователю, над пером – это удаление. Для ее реализации используется функция стандартного удаления объектов (т.е. ее можно использовать для удаления, как перьев так и кисти):

DeleteObject(MyPen);

Еще один вопрос, который не рассмотрен относительно перьев, заключается в следующем: мы определили ширину и стиль линии, но каким образом будут заполнятся пустоты, например,  между штрихами? Программа может установить цвет фона заполнения для данного контекста следующим образом:

SetBkColor(hdc, rgbColor);

а также может определить текущий цвет фона в контексте:

QColor  = GetBkColor(hdc);

Кисть (BRUSH) определяет цвет и режим фона, которыми заполняются пустоты. По умолчанию, это стандартная кисть WHITE_BRUSH. Следовательно, внутренняя область фигуры будет закрашена белым цветом. Windows имеет шесть стандартных (stock) кистей: WHITE_BRUSH (белая кисть), LTGRAY_BRUSH (светло-серая кисть), GRAY_BRUSH (серая кисть), DKGRAY_BRUSH (темно-серая кисть), BLACK_BRUSH (черная кисть), NULL_BRUSH или HELLOW_BRUSH (пустая кисть).

Получение описателя стандартной кисти и ее выбор в контекст аналогично получению стандартного пера:

HBRUSH MyBrush, OldBrush; // объявление описателей кисти

MyBrush = GetStockObject(BLACK_BRUSH); // Получение стандартной черной кисти.

OldBrush=SelectObject(hdc,MyBrush); // Выбор кисти в контекст

  //    Рисование

SelectObject(hdc,OldBrush); // Выбор в контекст старой кисти

Для создания кисти Windows имеет несколько функций.

Самый простой фон задает только чистый (solid) цвет:

MyBrush = CreateSolidBrush(rgbColor);

Вы можете также создать штриховую (hatch) кисть при помощи следующей функции:

MyBrush = CreateHathBrush(iHatchStyle, rgbColor);

где параметр iHatchStyle задает стиль штриховки:

Вы можете создать кисть, используя свою собственную штриховку:

MyBruch = CreatePatternBrush(hBitmap);

где hBitmap – описатель битового образа.

Так же, как и в случае с пером, программа должна удалить все созданные ею кисти при помощи уже знакомой нам процедуры DeleteObject:

DeleteObject(MyBrush);

В заключении разговоров об объекте можно повторить общие правила, которые мы обсудили при их рассмотрении:

  1.  Удаляйте все созданные вами объекты.
  2.  Не удаляйте объекты, пока они выбраны в контексте.
  3.  Не удаляйте стандартные объекты.

В обоих объектах, как в прочем и в самом контексте, используется понятие цвета. Windows использует 32-разрядное беззнаковое целое для представления цвета. Тип данных для цвета называется COLORREF. Младшие три байта задают красную, зеленую и голубую составляющую, величина которых находится в интервале от 0 до 255, как показано на рисунке. Таким образом, палитра может иметь 224 цвета.

                           0 Blue Green Red

Для задания цвета вы можете определить соответствующие байты слова самостоятельно, либо использовать функциюRGB:

COLORREF MyColor = RGB(255,0,0); // определение синего цвета

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

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

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

Значение по умолчанию

Функция для изменения

Функция для получения

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

(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)

SetVievportExtEx

SetMapMode

GetVievportExtEx

Перо (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


 

А также другие работы, которые могут Вас заинтересовать

19138. Состав атомных ядер. Ядерные силы. Энергия связи. Формула Вайцзекера. Радиоактивный распад. Типы распадов. Закон радиоактивного распада 221.5 KB
  Лекция 3. Состав атомных ядер. Ядерные силы. Энергия связи. Формула Вайцзекера. Радиоактивный распад. Типы распадов. Закон радиоактивного распада. 3.1. Состав атомных ядер. В 1932 г. Иваненко высказал гипотезу что в состав ядра атома входят только два вида элементарны
19139. Определение ядерной реакции. Элементарные частицы. Особенности ядерных реакций с нейтронами. Классификация нейтронов по энергии 150 KB
  Лекция 4. Определение ядерной реакции. Элементарные частицы. Особенности ядерных реакций с нейтронами. Классификация нейтронов по энергии. Сечение ядерной реакции. Микроскопическое и макроскопическое нейтронные сечения. 4.1. Определение ядерной реакции. Ядерная ре
19140. История открытия реакции деления. Осколки деления. Выходы осколков деления. Мгновенные и запаздывающие нейтроны 292 KB
  Лекция 5. История открытия реакции деления. Осколки деления. Выходы осколков деления. Мгновенные и запаздывающие нейтроны. Распределение энергии между продуктами деления. Спонтанное деление. Особенности сечений деления основных делящихся изотопов. 5.1. История откры
19141. Цепная самоподдерживающаяся реакция деления. Коэффициент размножения. Способы достижения критичности 4.71 MB
  Лекция 6 Цепная самоподдерживающаяся реакция деления. Коэффициент размножения. Способы достижения критичности. Критические и подкритические эксперименты. Первый ядерный реактор. 6.1. Цепная самоподдерживающаяся реакция деления В результате реакции деления появ...
19142. Плотность потока нейтронов. Скорость ядерной реакции. Баланс нейтронов в ядерном реакторе. Коэффициент размножения в бесконечной среде 265 KB
  Лекция 7. Плотность потока нейтронов. Скорость ядерной реакции. Баланс нейтронов в ядерном реакторе. Коэффициент размножения в бесконечной среде. Групповой подход. Библиотеки групповых констант. 7.1. Плотность потока нейтронов. Совокупность переменных {Et} называют...
19143. Создание базы данных, состоящей из одной таблицы 190.41 KB
  Повторим аналогичную операцию еще раз, в результате чего закроем текущую базу данных, получив пустое окно для новой работы. В этом положении можно создать новую базу данных, а можно открыть существующую для продолжения работы.
19144. Нейтронный цикл в реакторе на тепловых нейтронах. Формула четырех сомножителей. Вероятность избежать резонансного захвата и поглощения в замедлителе 178 KB
  Лекция 8. Нейтронный цикл в реакторе на тепловых нейтронах. Формула четырех сомножителей. Вероятность избежать резонансного захвата и поглощения в замедлителе. Оптимальные параметры размножающих сред. Одногрупповая теория критического реактора. Отражатель нейтронов. ...
19145. Бесконечная решетка. Элементарная ячейка. Распределение нейтронов различных энергий по ячейке 419 KB
  Лекция 9. Бесконечная решетка. Элементарная ячейка. Распределение нейтронов различных энергий по ячейке. Коэффициент размножения бесконечной периодической решетки. Твэлы и ТВС реакторов ВВЭР и РБМК. 9.1. Бесконечная решетка Кроме гомогенной среды топлива и замедлите...
19146. Многогрупповой подход. Многогрупповое уравнение диффузии. Внутренние и внешние итерации. Программы нейтронно-физического расчета 207 KB
  Лекция 10. Многогрупповой подход. Многогрупповое уравнение диффузии. Внутренние и внешние итерации. Программы нейтроннофизического расчета. Коэффициенты чувствительности коэффициента размножения к изменению параметров реактора. 10.1. Многогрупповой подход. Много...