Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Graph.doc
Скачиваний:
19
Добавлен:
14.05.2015
Размер:
238.59 Кб
Скачать

17

Управление графикой в Visual C++

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

В Windowsопределены четыре типа контекстов устройств:

  • для экрана;

  • для принтера;

  • для оперативной памяти;

  • информационный.

Таким образом, в VisualC++ реализована независимость программы от устройств вывода: достаточно лишь указать другой контекст и вывод графики будет выполнен на другое устройство без изменений в командах рисования.

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

Информационный контекст используется для восстановления заданных по умолчанию параметров.

На рис.1 показана иерархия классов контекстов устройств библиотеки MFC.

CDC– базовый класс. Объекты этого класса используются для работы со всем экраном или с принтером.

CPaintDC– объекты этого класса используются только в обработчике сообщенияWM_PAINT, генерируемого в ответ на вызов функцийUpdateWindowилиRedrawWindow.

CClientDC– объекты этого класса обеспечивают доступ к клиентской части окна.

CWindowsDC– объекты этого класса обеспечивают вывод как в клиентскую, так и не в клиентскую части окна.

CMetaFileDC– объекты этого класса обеспечивают доступ к метафайламWindows. Метафайлы содержат команды рисования и имеют по умолчанию расширение .wmf.

Выводом графики управляют объекты следующих классов:

  • битовые массивы (класс CBitmap) – прямоугольные массивы точек, формирующие растровые изображения;

  • карандаши (класс CPen) – для рисования линий;

  • кисти (класс CBrush) – для заливки замкнутых контуров;

  • регионы (класс CRgn) – для рисования стандартных фигур (прямоугольников, эллипсов и т.д.);

  • логические палитры (класс CPalette)– для осуществления связи между приложением и экраном;

  • шрифты (класс CFont) – для задания параметров вывода текста.

Рассмотрим пример вывода отрезков прямых по щелчку мыши в клиентской части окна SDI-проектаGraph. Линии выводятся от конца предыдущей линии до позиции указателя мыши.

void CGraphView::OnLButtonDown(UINT nFlags, CPoint point) {

static int m_X, m_Y;

CClientDC dc(this); // Сформировали объект dc

dc.MoveTo(m_X,m_Y); // Переместили перо в точку (m_X,m_Y)

m_X=point.x; // Определяем координаты указателя

m_Y=point.y; // мыши при нажатии левой кнопки

dc.LineTo(m_X,m_Y);// Проводим линию

CView::OnLButtonDown(nFlags, point);

}

Здесь функция обработки нажатия левой кнопки мыши вставлена с помощью мастера ClassWizard. Координатыm_X и m_Y объявлены как статические для сохранения их значений после завершения работы функции.

Следует обратить внимание на то, что в примере не задавались параметры пера – они определены по умолчанию. На рис. 2 показан пример вывода графики.

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

Система Windows имеет в своем составе, пожалуй, только два вида объектов, число функций для взаимодействия с которыми несоизмеримо с количеством функций для всех других объектов. Речь идет об окнах и контекстах устройств. Естественно, что и библиотека классов MFC обеспечивает соответствующие классы не менее широким набором компонентов-функций.

Создание объекта класса и его связь с контекстом устройства

Все классы библиотеки MFC, непосредственно связанные с объектами Windows, обеспечивают программиста более удобным и понятным интерфейсом. Часто класс имеет в своем составе конструктор по умолчанию, т.е. без параметров, который только создает объект класса, никак не связанный с объектом Windows. Так как работа с объектами Windows происходит только через дескрипторы, класс должен иметь возможность для их хранения. Рассмотрим упомянутые механизмы и их поддержку в реализации класса CDC.

Компоненты класса

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

НDС СDC::m_hDCдескриптор контекста устройства графического вывода.

Hdc cdc::m_hAttribDc – дескриптор контекста устройства, используемый для получения параметров устройства.

По умолчанию m_hDC и m_hAttribDC равны. В принципе контекст устройства вывода m_hDC используется только для выполнения операций рисования, а через второй контекст запрашиваются параметры. Например, функция SetTextColor работает с m_hDC, a GetTextColor – с m_hAttribDC. Однако, этот механизм имеет смысл только для объектов класса CMetaFileDC, когда m_hDC настроен на метафайл, a m_hAttribDC настроен на физическое устройство вывода, параметры которого используются для рисования. Аналогичный механизм используется и для режима предварительного просмотра печати (print preview), реализованного в большом количестве приложений. Для этих целей могут применяться функции SetOutputDC и SetAtrribDC, которые позволяют приложению связывать объект класса с различными контекстами устройств для графического вывода и получения текущих параметров.

Тем не менее, иногда возникает необходимость получения параметров вывода текста от обоих контекстов. В табл.1 показаны пары функций, используемых в таких случаях.

Таблица 1. Примеры пар функций для работы с различными контекстами

m_hAttribDC

m_hDC

GetTextExtent

GetOutputTextExtent

GetTabbedTextExtent

GetOutputTabbedTextExtent

GetTextMetrics

GetOutputTextMetrics

GetCharWidth

GetOutputCharWidth

Конструктор создает объект класса, не связывая его с конкретными контекстами устройств. Для дальнейшей работы необходимо осуществить связывание контекста устройства Windows, который, возможно, следует еще и создать, с объектом класса.

Инициализация

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

Основная функция создания контекста устройства и инициализации объекта класса CDC CreateDC.

virtual BOOL CDC::CreateDC (

LPCTSTR lpszDriverName,

LPCTSTR lpszDeviceName,

LPCTSTR lpszOutput,

const void* lpInitData)

Здесь lpszDriverNameуказатель на строку содержащую имя драйвера, например EPSON; lpszDeviceNameуказатель на строку, содержащую имя устройства, например, "EPSON FX-1050" (этот параметр используется, если драйвер фактически поддерживает несколько устройств); lpszOutput указатель на строку, определяющую собственно приемник – файл, символьное имя устройства или порт вывода; lpInitData указатель на структуру DEVMODE, содержащую установки устройства; если значение параметра равно NULL, используются установки, заданные в системе по умолчанию.

Фирма Microsoft рекомендует имя устройства завершать символом ":", а имена устройств и портов не должны содержать ни ведущих, ни завершающих пробелов. В случае успешного завершения функция возвращает TRUE, иначе FALSE.

Функция

virtual BOOL CDC::CreateCompatibleDC(CDC* pDC)

создает расположенный в памяти контекст устройства, подобный (совместимый) заданному параметром pDC. Такие контексты позволяют выполнять операции рисования без непосредственной визуализации. Если pDC = NULL, функция создает контекст устройства, совместимый с экраном дисплея.

В момент создания контекста GDI автоматически устанавливает для него системный монохромный битовый массив размером 11 пиксел. Таким образом, операции графического вывода могут производиться только в том случае, если будет создан и установлен новый битовый массив для данного контекста устройства.

Функция может создать совместимый контекст устройства только для контекстов, поддерживающих растровые операции. Определить, поддерживает устройство растровые операции или нет, можно с помощью функции GetDeviceCaps.

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

void CMercuryFrame::OnPaint() {

CPaintDC dc(this);

// Создание совместимого контекста устройства

CDC dcMem;

dcMem.CreateCompatibleDC(&dc);

// Определение размеров клиентской области окна

CRect rect;

GetClientRect(&rect);

// Создание и установка битового массива нужного размера

// и требуемых свойств

CBitmap bitmap, *pBitmap;

bitmap.CreateCompatibleBitmap(&dc, rect.right, rect.bottom);

pBitmap = dcMem.SelectObject(&bitmap);

dcMem.Rectangle(...) // вызов функции рисования

// Копирование содержимого одного контекста в другой

dc.BitBlt(0,0,rect.right,rect.bottom,&dcMem,0,0,SRCCOPY);

// Восстановление первоначально созданного битового массива

if (pBitmap) dcMem.SelectObject(pBitmap);

// Удаление совместимого контекста устройства

dcMem.DeleteDC();

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]