Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпоры по Леонову, 5семестр.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
503.3 Кб
Скачать

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

В Windows включен особый слой абстракций – интерфейс графического устройства – GDI. Вместо того чтобы обращаться к оборудованию программа вызывает GDI-функции которые ссылаются на структуру данных – контекст устройства.

Контекст устройства (device context) Microsoft Windows — ключевой элемент GDI, служащий для представления физичес­кого устройства. С каждым объектом «контекст устройства» C++ связан контекст устройства Windows, идентифицируемый 32-разрядным описателем типа HDC. Библиотека MFC версии 6.0 предоставляет несколько классов контекста устройства. Базовый класс CDC содержит все необходимые для рисования функции-члены, включая несколько виртуальных. Все производ­ные классы, за исключением CMetaFileDC, отличаются только конструкторами и деструкторами. Если Вы (или каркас приложения) создали объект производного класса контекста устройства, то указатель на CDC можно затем передать функции, например, OnDraw. Для дисп­лея обычно используют производные классы CclientDC и CWindowDC. Для других устройств, таких, как принтеры или буферы в памяти, используют объекты базового класса CDC. «Виртуальность» класса CDC — важная особенность каркаса приложения. В главе 19 Вы увидите, насколько легко написать код, работающий и с дисплеем, и с принтером. Оператор в OnDraw, например,

pDC->TextOut(0, 0, "Hello");

посылает текст на дисплей, принтер или в окно предварительного просмотра печати, в зави­симости от класса объекта, на который ссылается параметр pDC функции CView.-.-OnDraw. Каркас приложения связывает описатели контекста устройства с объектами, представляющими контексты устройств дисплея и принтера.

Классы контекста дисплея CCIientDC и CWindowDC

В клиентскую область окна не входят рамка, заголовок и меню. Если создать объект CCIientDC, то получится контекст устройства, представляющий только эту область, — рисовать за ее пределами невозможно. Точка (0,0) обычно связана с верхним ле­вым углом клиентской области. Как Вы увидите далее, объект CView соответствует дочернему окну, содержащемуся внутри отдельного окна-рамки, зачастую вместе с панелью инструмен­тов, панелью состояния и линейками прокрутки. Все эти окна не входят в клиентскую область окна представления. Если, например, вверху окна имеется пристыкованная панель инстру­ментов, то (0,0) соответствует точке непосредственно под левым краем панели. В случае, когда Вы создаете объект CWindowDC, точка (0,0) соответствует левому верхнему краю неклиентс­кой области окна. С помощью этого полнооконного контекста устройства Вы можете рисо­вать по рамке окна, в области заголовка окна и т. д. Не забывайте, что у окна представления нет неклиентской области, поэтому CWindowDC более подходит для окон-рамок, а не для окон представлений.

Создание и уничтожение CDC-объектов

Важно своевременно уничтожать созданные Вами объекты CDC, когда работа с ними закон­чена. Microsoft Windows ограничивает число доступных контекстов устройства, и если не освободить контекст устройства Windows, небольшой участок памяти будет потерян до са­мого завершения программы. Чаще всего объект «контекст устройства» создается в обработ­чике сообщения, например, в OnLButtonDown. Проще всего гарантировать уничтожение объ­екта «контекст устройства» (и освобождение соответствующего контекста устройства Win­dows), создавая объект на стеке следующим образом:

void CMyView::OnLButtonDown(UINT nFlags, CPoint point) {CRect rect;

CCIientDC dc(this); // создание etc на стеке dc.GetClipBox(rect); // получение ограничивающего прямоугольника } // dc автоматически освобождается .

Обратите внимание: конструктор объекта CCIientDC принимает в качестве параметра указа­тель на окно. Деструктор CCIientDC вызывается при возврате управления из функции. Вы можете также получить указатель на контекст устройства с помощью функции CWnd::GetDC, как показано ниже. Не забывайте вызывать ReleaseDC для освобождения контекста устройства:

void CMyView::OnLButtonDown(UlNT nFlags, CPoint point) .

CRect rect;

CDC* pDC = GetDC();

dc.GetClipBox(rect);

ReleaseDC(pDC);

// указатель на внутренний объект CDC

// получение ограничивающего прямоугольника

// Не забывайте

ВНИМАНИЕ Нельзя удалять CDC-объект, указатель на который передается функции OnDraw. Удале­нием этого объекта управляет каркас приложения.

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

Когда Вы используете CDC-объект для рисования, например, эллипса, то полученное на экране (или на принтере) изоб­ражение зависит от текущего «состояниям контекста устройства. Состояние контекста вклю­чает в себя:

• связанные с контекстом объекты для рисования, такие, как перья, кисти и шрифты;

• режим преобразования координат, определяющий масштаб элементов при их рисовании. (Мы уже экспериментировали с режимами преобразования координат в главе 4.);

• различные детали, например, параметры выравнивания текста и режим заполнения мно­гоугольников.

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