Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Лекция 5. Отображение информации с помощью модуля GDI

Поиск

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

В однозадачных ОС (MS-DOS), любая программа может рисовать непосредственно на экране. В многозадачных ОС программы так действовать не должны, т.к. при одновременной работе нескольких программ пользователь должен видеть на экране согласованную картину, сформированную в результате их совместной работы. Экранная область, принадлежащая программе A, должна быть защищена от информации, выводимой программой B. Доступом к видеоадаптеру, как и к другим устройствам, управляет ОС. Она позволяет программам выводить информацию только в пределах их окон. В Windows графическое отображение выполняет модуль GDI.

Windows-приложение не может рисовать что-либо непосредственно на экране, принтере или каком-нибудь другом устройстве вывода. Все операции рисования производятся на воображаемом "устройстве", представляемом с помощью контекста устройства. Контекст устройства – эта служебная внутренняя структура Windows, в которой хранятся все характеристики устройства и его текущего состояния, необходимые модулю GDI для рисования. До начала рисования приложение должно получить от модуля GDI дескриптор контекста устройства. Этот дескриптор надо передавать в качестве первого параметра всем функциям рисования GDI. Без корректного дескриптора контекста устройства, GDI не будет знать, на каком именно устройстве и в какой его области рисовать пикселы. В контексте устройства хранятся параметры, позволяющие GDI выполнять отсечение и рисовать графические примитивы только внутри заданных областей. Одни и те же функции GDI могут рисовать примитивы на различных устройствах, т.к. специфика устройства скрыта в контексте устройства.

MFC избавляет программиста от необходимости непосредственной работы с дескрипторами контекстов устройств. Дескриптор контекста устройства и функции рисования GDI инкапсулированы в класс "Контекст устройства" – CDC. От него унаследованы классы для представления различных контекстов устройств (см. табл. 5.1).

Таблица 5.1. Классы различных контекстов устройств

Имя класса С чем связан этот контекст устройства
CPaintDC Клиентская область окна (только в обработчиках OnPaint)
CClientDC Клиентская область окна
CWindowDC Окно, включая неклиентскую область
CMetaFileDC Метафайл GDI (аналог макроса, в котором запоминаются вызовы функций GDI и потом их можно многократно воспроизводить)

Объекты этих классов можно создавать как автоматически, так и динамически. В конструкторе и деструкторе каждого класса вызываются функции GDI для получения и освобождения дескрипторов контекста устройства. Например, создать контекст устройства в обработчике OnPaint можно так:

CPaintDC dc(this); // Вызовы каких-либо функций-членов для рисования примитивов

Конструктору CPaintDC передается указатель на окно, с которым будет связан контекст устройства.

Класс CPaintDC предназначен для рисования в клиентской области окна при обработке сообщений WM_PAINT. Но приложения Windows могут выполнять графическое отображение не только в OnPaint. Например, требуется рисовать в окне окружность при каждом щелчке мышью. Это можно делать в обработчике сообщения мыши, не дожидаясь очередного сообщения WM_PAINT. Для подобных операций отображения предназначен класс CClientDC. Он создает контекст устройства, связанный с клиентской областью окна, которым можно пользоваться за пределами OnPaint.

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

void CMainWindow::OnLButtonDown(UINT nFlags, CPoint point) { CRect rect; GetClientRect(&rect); CClientDC dc(this); dc.MoveTo(rect.left, rect.top); dc.LineTo(rect.right, rect.bottom); dc.MoveTo(rect.right, rect.top); dc.LineTo(rect.left, rect.bottom); }

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

CClientDC dc(NULL); dc.Ellipse(0, 0, 100, 100);

 

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

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

Таблица 5.2. Основные атрибуты контекста устройства

Атрибут Значение по умолчанию Функция-член CDC для задания значения Функция-член СDC для получения значения
Цвет текста Черный SetTextColor GetTextColor
Цвет фона Белый SetBkColor GetBkColor
Режим фона OPAQUE SetBkMode GetBkMode
Режим преобразования координат MM_TEXT SetMapMode GetMapMode
Режим рисования R2_COPYPEN SetROP2 GetROP2
Текущая позиция (0,0) MoveTo GetCurrentPosition
Текущее перо BLACK_PEN SelectObject SelectObject
Текущая кисть WHITE_BRUSH SelectObject SelectObject
Текущий шрифт SYSTEM_FONT SelectObject SelectObject

Различные функции рисования CDC пользуются атрибутами по-разному. Например, цвет, ширина и стиль (сплошная, штриховая и т.п.) линии для рисования отрезка функцией LineTo определяются текущим пером. При рисовании прямоугольника функцией Rectangle модуль GDI рисует контур текущим пером, а внутреннюю область заполняет текущей кистью. Цвет текста, фона и шрифт используются всеми функциями отображения текста. Фоновый цвет применяется также при заполнении промежутков в несплошных линиях. Если фоновый цвет не нужен, его можно отключить (сделать "прозрачным"):

dc.SetBkMode(TRANSPARENT);

Атрибуты CDC чаще всего изменяются с помощью функции SelectObject. Она предназначена для "выбора" в контексте устройства объектов GDI 6-ти типов:

· перья (pens)

· кисти (brushes)

· шрифты (fonts)

· битовые карты (bitmaps)

· палитры (palettes)

· области (regions).

В MFC перья, кисти и шрифты представлены классами CPen, CBrush и CFont. Свойства пера "по умолчанию": сплошная черная линия толщиной 1 пиксел; кисть "по умолчанию": сплошная белая; шрифт "по умолчанию": пропорциональный высотой примерно 12 пт. Вы можете создавать объекты-перья, кисти и шрифты с нужными вам свойствами и выбирать их в любом контексте устройства.

Допустим, динамически были созданы объекты pPen и pBrush – черное перо толщиной 10 пикселов и сплошная красная кисть. Для рисования эллипса с черным контуром и красным заполнением можно вызвать следующие функции-члены:

dc.SelectObject(pPen); dc.SelectObject(pBrush); dc.Ellipse(0, 0, 100, 100);

Функция-член SelectObject перегружена для работы с указателями на различные объекты GDI. Она возвращает указатель на предыдущий выбранный в контексте устройства объект того же типа, что и объект, переданный функции в качестве параметра.

 

1.2 Режимы преобразования координат

Один из самых сложных для освоения аспектов GDI – применение режимов преобразования координат. Режим преобразования координат – это атрибут контекста устройства, задающий способ пересчета логических координат в физические координаты устройства. Логические координаты передаются функциям рисования CDC. Физические координаты – это координаты пикселов в экранном окне или на листе принтера (т.е. на поверхности изображения).

Допустим, вызывается функция Rectangle:

dc.Rectangle(0, 0, 200, 100);

Нельзя сказать, что эта функция нарисует прямоугольник шириной 200 пикселов и высотой 100 пикселов. Она нарисует прямоугольник шириной 200 логических единиц и высотой 100 единиц. В режиме преобразования координат по умолчанию, MM_TEXT, 1 логическая единица равна 1-му пикселу. В других режимах масштаб может быть иным (см. табл. 5.3). Например, в режиме MM_LOMETRIC 1 логическая единица равна 1/10 мм. Следовательно, в показанном вызове Rectangle будет нарисован прямоугольника шириной 20 мм и высотой 10 мм. Режимы, отличные от MM_TEXT, удобно применять для рисования в одинаковом масштабе на различных устройствах вывода.

Таблица 5.3. Режимы преобразования координат, поддерживаемые модулем GDI

Константа для обозначения режима Расстояние, соответствующее логической единице Ориентация координатных осей
MM_TEXT 1 пиксел x вправо, у вниз
MM_LOMETRIC 0.1 мм x вправо, у вверх
MM_HIMETRIC 0.01 мм x вправо, у вверх
MM_LOENGLISH 0.01 дюйма x вправо, у вверх
MM_HIENGLISH 0.001 дюйма x вправо, у вверх
MM_TWIPS 1/1440 дюйма (0.0007 дюйма) x вправо, у вверх
MM_ISOTROPIC Определяется пользователем (масштаб по осям x и y одинаков) Определяется пользователем
MM_ANISOTROPIC Определяется пользователем (масштаб по осям x и y задается независимо) Определяется пользователем

 

Система координат в режиме MM_TEXT показана на рис. 5.1. Начало координат располагается в левом верхнем углу поверхности изображения (в зависимости от контекста устройства, это может быть левый верхний угол экрана, окна, клиентской области окна). Ось х направлена вправо, ось y вниз, 1 логическая единица равна 1-му пикселу. В остальных, "метрических", системах ось y направлена вверх, так что система координат оказывается правой, но начало координат по умолчанию всегда помещается в левый верхний угол поверхности изображения.

Рис. 5.1. Система координат в режиме MM_TEXT.

 

1.3 Функции преобразования координат

Для преобразования логических координат в координаты устройства (физические координаты) предназначена функция CDC::LPtoDP. Для обратного преобразования есть функция CDC::DPtoLP.

Допустим, надо вычислить координаты центра клиентской области окна в физических координатах. Для этого не требуется никаких преобразований, т.к. размеры клиентской области в пикселах возвращает функция CWnd::GetClientRect:

CRect rect; GetClientRect(&rect); CPoint point(rect.Width()/2, rect.Height()/2);

Для вычисления координат этой точки в режиме MM_LOMETRIC потребуется функция DPtoLP:

CRect rect; GetClientRect(&rect); CPoint point(rect.Width()/2, rect.Height()/2); CClientDC dc(this); dc.SetMapMode(MM_LOMETRIC); dc.DPtoLP(&point);

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

Иногда Windows-программисты употребляют термины "клиентские координаты" и "экранные координаты". Клиентские координаты – это физические координаты, заданные относительно левого верхнего угла клиентской области окна. Экранные координаты – это физические координаты, заданные относительно левого верхнего угла экрана. Преобразование между двумя этими системами выполняется с помощью функций CWnd::ClientToScreen и CWnd::ScreenToClient.

 



Поделиться:


Последнее изменение этой страницы: 2016-08-01; просмотров: 292; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.133.113.24 (0.009 с.)