Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
System programming / Конспект лекций / Лекция 3 Контекст устройства.doc
Скачиваний:
54
Добавлен:
08.05.2015
Размер:
129.02 Кб
Скачать

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

Обратимся еще раз к рисунку 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 цвета.

31 … 24 23 … 16 15 … 8 7 … 0

0 Blue Green Red

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

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