Смекни!
smekni.com

Основы графического вывода (стр. 11 из 26)

Во–первых, по умолчанию нижняя и правая границы описывающего прямоугольника не включаются в рисуемый объект, однако в случае Win32 API и установленного расширенного режима границы описывающего прямоугольника полностью включаются в рисуемый объект (функция SetGraphicsMode, GM_ADVANCED, дополнительно см. раздел «Глобальные системы координат GDI (Win32 API)»).

Во–вторых, рисуемый объект может выходить за рамки описывающего прямоугольника, если для обведения контура используется перо, ширина которого превышает одну единицу устройства и это перо не стиля PS_INSIDEFRAME. Линия стиля PS_INSIDEFRAME всегда будет находиться внутри описывающего прямоугольника.

В–третьих, ориентация сторон описывающего прямоугольника всегда параллельна осям координат и, соответственно, предусмотренные функции не могут рисовать наклонных прямоугольников и эллипсов, что является существенным неудобством. Единственное возможность — при использовании Win32 API перейти в расширенный режим и наклонить сами оси координат (см. раздел «Глобальные системы координат GDI (Win32 API)»).

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

BOOL Rectangle (hDC, xLeft, yTop, xRight, yBottom);

BOOL Ellipse (hDC, xLeft, yTop, xRight, yBottom);

BOOL RoundRect (hDC, xLeft, yTop, xRight, yBottom, xRound, yRound);

Функция Rectangle рисует прямоугольник с прямыми углами, а функция RoundRect скругляет эти углы, проводя небольшие дуги. Эти функции используют описывающий прямоугольник, координаты которого задаются в качестве параметров, причем для функций Rectangle и RoundRect этот прямоугольник задает непосредственно рисуемый объект, а для функции Ellipse он задает описывающий прямоугольник. Функция RoundRect дополнительно требует задания величины эллипсов, которыми она будет скруглять углы. При этом надо учитывать, что задаются размеры описывающего скругляющий эллипс прямоугольника, а не его радиусы. То есть в каждом углу скругляющая дуга будет занимать только половину от указанных вами значений.

Рисунок 7. Задание величины скругляющих эллипсов для функции RoundRect.

Теперь осталось рассмотреть пару функция для рисования сектора (Pie), то есть дуги и области, ограниченной двумя радиусами и для рисования дуги, стянутой хордой (Chord).

Рисунок 8. Результат выполнения функций Pie (слева) и Chord (справа).

BOOL Pie (hDC, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);

BOOL Chord (hDC, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);

При использовании этих функций надо помнить о направлении рисования дуги (в WindowsAPI вы можете задавать это направление, а в Win32 API в расширенном графическом режиме оно всегда против часовой стрелки), о задании начальной и конечной точек дуги и об особенностях задания ограничивающего прямоугольника.

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

BOOL Polygon (hDC, lpPoints, nCount);

BOOL PolyPolygon (hDC, lpPoints, lpCounts, nPolyCount);

Функция Polygon рисует текущим карандашом ломаную линию, имеющую указанное параметром nCount число точек с координатами, заданными массивом структур типа POINT, который задается параметром lpPoints (аналогично функции PolyLine — см. раздел «Рисование линий»). В отличие от PolyLine, функция Polygon замыкает многоугольник и закрашивает его внутреннюю область текущей кистью. Так как многоугольник может быть достаточно сложным, и некоторые его области могут перекрываться, то GDI предусматривает два различных алгоритма вычисления внутренней, закрашиваемой области. Применяемый алгоритм определяется атрибутом контекста устройства, называемым режим заполнения многоугольников (polygon filling mode) — см. ниже.

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

Кисть

В Windows существует специальный объект GDI, используемый для закраски внутренних областей фигур; по аналогии с рисованием на бумаге этот объект получил название кисть (brush). Практически кисть представляет собой небольшую (8x8 пикселей) картинку, которая многократно воспроизводится для закраски указанной области.

Кисть является объектом GDI и, соответственно, при работе с ней надо придерживаться общих правил работы с объектами GDI.

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

HANDLE GetStockObject (nIndex);

HBRUSH GetStockBrush (nIndex); 2

где параметр nIndex может быть:

BLACK_BRUSH — кисть черного цвета
DKGRAY_BRUSH — темно-серая
GRAY_BRUSH — серая
LTGRAY_BRUSH — светло-серая
WHITE_BRUSH — белая
HOLLOW_BRUSH — прозрачная кисть
NULL_BRUSH — прозрачная кисть (синоним символа HOLLOW_BRUSH)

Белая кисть (WHITE_BRUSH) обычно используется для закраски фона окна (при описании класса окна поле WNDCLASS.hbrBackground задается обычно равным хендлу белой кисти).

В принципе, вы можете задать любую другую кисть для закраски внутренней области окна, либо изменив регистрацию класса окна, либо, уже после регистрации и создания окна (окон) этого класса, воспользовавшись функцией:

UINT SetClassWord (hWnd, GCW_HBRBACKGROUND, hbrNewBrush); // Windows 3.x

DWORD SetClassLong (hWnd, GCL_HBRBACKGROUND, hbrNewBrush); // Win32 API

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

Кисти HOLLOW_BRUSH и NULL_BRUSH представляют один и тот же объект — прозрачную кисть. Вы можете использовать данную кисть для закраски фона замкнутых фигур, если они должны быть представлены только контуром, без заполнения внутренней области.

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

HBRUSH CreateSolidBrush (crColor);

HBRUSH CreateHatchBrush (nStyle, crColor);

HBRUSH CreatePatternBrush (hBitmap);

HBRUSH CreateDIBPatternBrush (hGlobDIB, nColorSpec);

HBRUSH CreateBrushIndirect (lpLogBrush);

ФункцияCreateSolidBrushпозволяетсоздатьоднотоннуюкисть. В качестве параметра указывается цвет создаваемой кисти. В том случае, если система не может воспроизвести указанный цвет чистым, то GDI будет использовать смешивание разноцветных пикселей для получения наиболее точного приближения к заданному цвету.

Так, например, в 16ти цветном режиме стандартные кисти LTGRAY_BRUSH, GRAY_BRUSH и BLACK_BRUSH могут быть представлены оттенками серого цвета, а кисть DKGRAY_BRUSH будет представлена смесью точек серого и черного цветов.

Функция CreateHatchBrush создает штрихованную кисть. Вы указываете два параметра — тип штриховки (nStyle) и цвет штриха (crColor), для закраски фона между штрихами в качестве фона используются атрибуты контекста устройства текущий цвет фона и режим заполнения фона.

Рисунок 9. Стили штрихованных кистей

Параметр crColor задает цвет штриховки. GDI будет применять ближайший чистый цвет для рисования линий штриховки. Для задания цвета фона надо воспользоваться функциями

COLORREF SetBkColor (hDC, crColor);

intSetBkMode (hDC, nMode);

С помощью функций CreatePatternBrush и CreateDIBPatternBrush вы можете описать кисть, определяемую образцом (pattern) — рисунком размером 8x8 пикселей. Для этого надо предварительно получить битмап размером 8x8 пикселей (или больше) и передать его соответствующей функции. Кисть будет создана исходя по изображению размером 8x8 пикселей, находящемуся в верхнем–левом углу битмапа. Подробнее о получении битмапов — смотри в разделе “Растровые изображения”. Все время, пока существует кисть, вы должны сохранять исходный битмап, по которому эта кисть построена. Один битмап может применяться для создания многих кистей.

Разница между двумя функциями создания кисти по образцу связана с применением разных видов битмапов — зависимых от устройства (DDB — device depended bitmap) и независимых от устройства (DIB — device independed bitmap). Независимый от устройства битмап содержит как данные об изображении, так и данные о применяемых цветах (палитре). При создании кисти на основе DIB требуется два параметра, один из которых указывает образец (независимый от устройства битмап), а другой указывает правила интерпретации логических цветов данного битмапа.

К этим двум функциям создания кисти по образцу надо сделать еще одно замечание: если битмап является монохромным, то тогда GDI будет представлять его не в виде черно–белого изображения, а использовать текущий цвет текста вместо цвета (1) и текущий цвет фона вместо цвета (0). Таким образом картинка оказывается как–бы негативной — точки, кодированные 1, по умолчанию представляются черными (цвет текста), а 0 — белыми (цвет фона).

Функция CreateBrushIndirect является объединением всех рассмотренных функций: в качестве параметра ей передается указатель на структуру типа LOGBRUSH, которая описывает кисть любого типа.

typedef struct tagLOGBRUSH {

UINT lbStyle;

COLORREF lbColor;

int lbHatch;

} LOGBRUSH;

Поле lbStyle определяет стиль кисти. Оно может принимать одно из следующих значений: BS_SOLID, BS_HATCHED, BS_HOLLOW, BS_NULL, BS_PATTERN и BS_DIBPATTERN (что в какой-то мере соответствует функции, применяемой для создания кисти). Использование других полей структуры LOGBRUSHзависит от стиля кисти:

Стиль Эквивалентная функция, применяемая для создания кисти Использование параметра lbColor Использование параметра lbHatch
BS_HOLLOW, BS_NULL не используется не используется
BS_SOLID CreateSolidBrush цвет кисти не используется
BS_HATCHED CreateHatchBrush цвет штриховки стиль штриховки
BS_PATTERN CreatePatternBrush не используется хендл DDB битмапа (HBITMAP)
BS_DIBPATTERN CreateDIBPatternBrush способ интерпретации логических цветов хендл блока памяти с DIB битмапом (HGLOBAL)

Структура LOGBRUSH может использоваться также для выяснения свойств кисти с помощью функции GetObject.