Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекций Часть II.doc
Скачиваний:
14
Добавлен:
20.11.2018
Размер:
1.48 Mб
Скачать

П 3.5. Рисование геометрических фигур

3.5.1 Установка атрибутов контекста отображения для рисования.

Режим рисования позволяет выводить изображения инвертировани­ем цвета фона, черным или белым цветом и т. д. По умолчанию для ри­сования используют цвет выбранного в контекст пера. Новый режим ри­сования устанавливает функция SetROP2:

int SetROP2( HOC hdc, int fnDrawMode);

Параметр fhDrawMode Определяет режим рисования и принимает значения из табл. 3.2. В случае успешного выполнения функция возвра­щает значение предыдущего режиме рисования, иначе - нуль.

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

HBRUSH CreateSolidBrush( COLORREF crColor) - создает кисть цвета crColor

HBRUSH CreateHatehBrush( int fnStyle, COLORREF drref) - создает штрихованную кисть

Параметр fhStyle определяет стиль штриховки и принимает одно из следующих значений:

Значение

Стиль штриховки

HS

BDIAGONAL

Линии под углом в 45 градусов

HS

CROSS

В клетку без наклона

HS

DIAGCROSS

В клетку с наклоном в 45 градусов

HS

FDIAGONAL

Линии под углом в 135 градусов

HS

HORIZONTAL

Горизонтальные линии

HS

VERTICAL

Вертикальные линии

Параметр clrref определяет цвет линий штриховки.

HGDIBJ Select0bject( HDC hdc, HGDIOBJ hgdiobj ) - выбирает в контекст кисть

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

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

BOOL Delete0bject( HGDIOBJ hgdiobj);

Параметр hgdiobj может указывать на перо, кисть, шрифт, изображе­ние, область или палитру. В случае успешного удаления возвращает не­нулевое значение.

Пример. Создать кисть в клетку из горизонтальных и вертикальных линий малинового цвета, выбрать ее в контекст, закрасить фигуры и удалить созданную кисть.

Решение этой задачи может иметь следующий вид:

HBRUSH hOldBrush, hNewBrush;

hNewBrush =CreateHatchBrush(HS_CROSS, RGB(255,0,255));

hOldBrush =(HBRUSH)SelectObject(hdc, hNewBrush);

//Здесь могут быть закрашены фигуры Select0bject(hdc, hOldBrush);

DeleteObject(hNewBrush);

По умолчанию линии рисуют черным пером шириной в 1 пиксель. Функция CreatePen создает перо указанного стиля, ширины и цвета:

HPEN CreatePen( intfnPenStyle, int nWidth, COLORREF crColor);

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

Значение

Стиль линии пера

PS SOLID

Сплошная

PS DASH

Штриховая

PS DOT

Пунктирная

PS DASHDOT

Шгрихпунктирная, одна точка на одну черточку

PS DASHDOTDOT

Шгрихпункгирная, две точки на одну черточку

PS NULL

Невидимая

PS WSIDEFRAME

Линии для обводки замкнутых фигур

Параметр nWidth задает ширину пера. В зависимости от режима ото­бражения ширина может быть указана в пикселях, долях дюйма или до­лях миллиметра. Ширина прерывистых линий может быть равна только единице. Параметр crColor задает цвет линий.

В случае успешного выполнения функция CreatePen возвращает де­скриптор созданного пера, иначе - NULL.

Обратите внимание на особенности рисования толстых линий. Линия стиля PS_SOLID располагается по обе стороны базовой линии, указан­ной в функции рисования линии. Причем концы линии всегда закругля­ются. Линия стиля PS_INSIDEFRAME всегда расположена с внутренней стороны обводящей линии.

В контекст перо выбирают, вызывая функцию SelectObject. Если соз­данное перо более не нужно, в контекст выбирают предыдущее перо. Созданное перо удаляют вызовом функции DeleteObject.

Пример. Создать перо для рисования сплошных линий шириной в 3 пик­селя голубого цвета, выбрать его в контекст, нарисовать линии и удалить созданное перо.

Решение этой задачи может иметь следующий вид:

HPEN hOldPen, hNewPen;

hNewPen =CreatePen(PS_SOLID, 3, RGB(0,255,255));

hOldPen =(HPEN)SelectObject(hdc, hNewPen);

//Здесь могут быть нарисованы линии Select0bject(hdc, hOldPen);

DeleteObject(hNewPen);

По умолчанию текущая позиция пера равна (0,0). Многие из функ­ций рисования линий вывод начинают с текущей позиции. Для установ­ки другой позиции пера вызывают функцию MoveToEx:

BOOL MoveToEx( MDC hdc, int X. int Y, LPPOINT IpPoint);

Параметры Х и Y задают новую позицию в логических единицах, IpPoint указывает на структуру типа POINT:

typedef struct

{ LONG x;

LONG у;

} POINT;

В поля x и у этой структуры после вызова этой функции будут запи­саны координаты предыдущей позиции. При lpPoint=NULL предыдущая позиция не сохраняется.

В случае успешного перемещения функция возвращает ненулевое значение.

Режим отображения влияет на систему координат. Приложение мо­жет изменить направление и масштаб координатных осей.

По умолчанию установлен режим отображения ММ_ТЕХТ. В этом режиме начало системы координат находится в левом верхнем углу ра­бочей области, ось х направлена вправо, ось у - вниз, позиции отсчиты­вают в пикселях.

Режим отображения изменяют вызовом функции SetMapMode:

int SetMapMode( HDC hdc, int fnMapMode);

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

Значение

Описание

MMANISOTROPtC

Произвольные направления для осей коор­динат, произвольные логические единицы

MMHIENGLISH

Логическая единица равна 0.001 дюйма. Ось' х направлена вправо, ось у - вверх

MMHIMETRIC

Логическая единица равна 0.01 миллиметра. Ось х направлена вправо, ось у - вверх

MM ISOTROPIC

Логические единицы произвольны и одина­ковы по обеим осям

MMLOENGLISH

Логическая единица равна 0.01 дюйма. Ось х направлена вправо, ось у - вверх

MMLOMETRIC

Логическая единица равна 0.1 миллиметра. Ось х направлена вправо, ось у - вверх

MM_TEXT

Логические единицы равны размерам пиксе­ля. Ось х направлена вправо, ось у - вниз

MMTWIPS

Логическая единица равна двадцатой части точки принтера (1/1440 дюйма). Ось х на­правлена вправо, ось у- вверх

В режимах MM_ANISOTROPIC и MM_SOTROPIC для установки ориентации осей и единиц вызывают функции SetWindowExtEx и SetViewport ExtEx.

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

По умолчанию начало системы координат установлено в точку (0,0). Для перемещения начала системы координат окна вызывают функцию SetWindowOrg:

BOOL SetWindowOrgEx( HOC hdc, int х, int y, LPPOINT IpPoint);

Параметры функции SetWindowOrgEx подобны параметрам функции MoveToEx. Коэффициенты масштабирования по координатным осям равны 1:1, по умолчанию. Для обеспечения аппаратной независимости приложения Windows работают с логическими координатами, которые затем преоб­разуются в физические. При этом можно задавать размеры в миллиметpax или дюймах или устанавливать любые коэффициенты масштабивания.

Для изменения масштабов последовательно вызывают две функции: сначала функцию SetWindowExtEx, а потом SetViewportExtEx.

Синтаксис функции SetWindowExtEx:

BOOL SetWindowExtEx( HDC hdc, int nxWinExt, int nyWinExt, LPS1ZE IpSize);

Параметры nxWinExt и nyWinExt задают горизонтальный и bертикальный. размеры окна в логических единицах. Параметр IpSize указывает на структуру типа SIZE:

typedef struct { LONG ex;

LONG cy;

} SIZE;

В эту структуру будут записаны значения предыдущих логических размеров окна (если IpSize не равен NULL).

Синтаксис функции SetViewportExtEx:

BOOL SelVtewportExtEx (HOC hdc, int nxViewExt, int nyVtewExt, LPSIZE IpSize);

Параметры nxViewExt и nyViewExt определяют горизонтальный и вертикальный размеры окна в физических единицах. Параметр IpSize указывает на структуру типа SIZE. В эту структуру будут записаны предыдущие физические размеры окна (если IpSize не равен NULL).

Тогда логические координаты точки (xWin, yWm) в физические ко­ординаты (xView, yView) преобразуют по формулам:

xView =(xWinxWin0) *(nxViewExt / nxWinExt) + xViewO,

yView= (yWin-yWin0) *(nyViewExt / nyWinExt) +yViewO.

где (xWinO, yWinO) и (xViewO, yViewO) указывают на смещение соответ­ственно логической и физической Системы координат.

Отсюда видно, что значения отношений

nxViewExt и nyViewExt

nxWinExt nyWinExt

и есть устанавливаемые значения коэффициентов масштабирования.

При таком подходе обеспечивается большой выбор коэффициентов мас­штабирования и направлений осей координат. Действительно, значения nxWinExt в nyWiaExt, а также nxViewExt и nyViewExt могут бьип. любыми допустимыми значениями типа int Вдобавок, меняя знак коэффициента масштабирования, можно изменить направление оси координат.

Смещение физической и логической систем координат по умол­чанию равно (0, 0). Для установки смещения используют функции SetViewportOrg Ex и SetWindowOrgEx.

Функция SetViewportOrgEx устанавливает новое начало (xViewO, yViewO) физической системы координат:

BOOL SetViewportOfgEx( HOC fldc» int xViewO, int yWewO, LPPOINT IpPoint);

Значения xViewO и yViewO задают в физических единицах. В структуру, адрес которой передается через параметр IpPoint, записы­ваются старые координаты начала системы координат. Функция возвра­щает TRUE в случае успеха и FALSE при возникновении ошибки.

Функция SetWindowOrgEx устанавливает начало (xWinO, yWinO) ло­гической системы координат:

bool SetWlndowOrgEx(HDC hdc, int xWinO, int yWinO, LPPOINT IpPoint);

Значения xWinO и yWinO задают в логических единицах. В структуру, адрес которой передается через параметр IpPoint, записываются старые координаты начала системы координат. Функция возвращает TRUE в случае успеха и FALSE при возникновении ошибки.

Рекомендуется изменять только одно начало отсчета - либо физиче­ских, либо логических координат.

Пример. Создать систему координат с началом отсчета в левом ниж­нем углу окна. Ось х направить слева направо, а ось у - снизу вверх. Ло­гические значения высоты и ширины изменять цт 0 до 1000. Установить одинаковый масштаб по осям х и у.

Следующий фрагмент кода решает эту задачу:

SetMapMode(hdc, MMJSOTROPIC);

SetWindowExt(hdc, 1000,1000);

SelViewportExt(hdc, cxClient, -cyClient);

SetViewportOrg(hdc, 0, cyClient);