Основные инструменты графической подсистемы
В среде Windows за формирование изображения отвечают так называемые инструменты, а функции рисования лишь задают их поведение. Инструменты являются системными объектами, но прикладная программа может произвольно создавать их и управлять ими.
К основным инструментам относятся:
– перо (Pen) – отображение контурных примитивов («карандаш»);
– кисть (Brush) – заполнение внутренних областей примитивов;
– шрифт (Font) – отображение символов и строк;
– битовая карта (Bitmap) – «готовые» растровые изображения.
Инструмент идентифицируется его описателем и создается соответствующей функцией вида Create..., которая возвращает этот описатель (NULL – признак ошибки). Количество создаваемых инструментов искусственно не ограничивается, но в любом контексте одновременно может быть активным только один инструмент каждого типа. Выбор инструмента отменить нельзя, но можно повторять его сколько угодно раз с любыми другими инструментами того же типа. Инструменты различного типа между собой взаимно независимы. Перед удалением инструмент следует дезактивировать, выбрав активным другой инструмент того же типа, например, сохраненный предыдущий.
Инструмент Pen
Для отображения контурных примитивов используется перо, выбранное в контексте, определяющее цвет, ширину и стиль линии, который может быть сплошным (solid), точечным (dotted) или пунктирным (dashed).
По умолчанию устанавливается одно из трех стандартных перьев, рисующих сплошные линии толщиной в единицу, выбранного цвета: BLACK_PEN – черное перо, WHITE_PEN – белое перо и NULL_PEN – пустое перо, которое ничего не рисует.
Определив переменную, например, hPen типа HPEN (описатель пера –handle to a pen): HPEN hPen; получить описатель одного из стандартных перьев, например белого пера, можно, вызывая функцию
hPen = GetStockObject (WHITE_PEN);
сделаем это перо текущим, вызвав функцию
SelectObject (hdc, hPen);
После этого все линии будут использовать белое перо до тех пор, пока не выберем другое перо в контекст устройства или пока не освободим контекст устройства.
Все вышесказанное можно совместить в одной инструкции:
hPen = SelectObject (hdc, GetStockObject (WHITE_PEN));
Если это первый вызов, функция SelectObject возвращает описатель того пера, которое уже было выбрано в контексте устройства; текущим пером становится белое, а переменная hPen получает описатель предыдущего (по умолчанию – черного) пера, вернуться к которому можно, используя вызов
SelectObject (hdc, hPen);
Для создания пера используются функции CreatePen или CreatePenIndirect (ExtCreatePen).
Функция CreatePen:
hPen = CreatePen (iPenStyle, iWidth, rgbColor);
параметр iPenStyle определяет стиль линии и может принимать одно из семи значений (семь стилей пера): PS_SOLID – сплошное, PS_DASH, PS_DOT, PS_DASHDOT, PS_DASHDOTDOT – штриховое, пунктирное и штрихпунктирное, PS_NULL – нерисующее (пустое) перо, PS_INSIDEFRAME – внутренняя обводка, в замкнутом контуре автоматически отступает внутрь в соответствии с толщиной линии.
Для стилей PS_SOLID, PS_NULL и PS_INSIDEFRAME параметр iWidth задает ширину пера, при iWidth = 0 – перо шириной в один пиксел.
Параметр rgbColor – цвет пера; для перьев всех стилей, кроме PS_INSIDEFRAME, преобразуется в ближайший чистый цвет, стиль PS_INSIDEFRAME позволяет использовать полутона при ширине больше 1.
Можно создать перо, определив структуру LOGPEN logpen («логическое перо» – logical pen), содержащую поля:
lopnStyle (UINT) – стиль пера;
lopnWidth (POINT) – ширина пера в логических единицах измерения;
lopnColor (COLORREF) – цвет пера.
Затем создаем перо, передавая адрес структуры в функцию CreatePenIndirect:
hPen = CreatePenIndirect (&logpen);
Получить информацию об уже существующем пере можно, используя функцию
GetObject (hPen, sizeof(LOGPEN), &logpen);
Функции CreatePen и CreatePenIndirect не требуют описателя контекста устройства. Эти функции создают логические перья, которые никак не связаны с контекстом устройства до тех пор, пока не вызвать функцию SelectObject.
Рассмотрим метод создания, выбора и удаления перьев. Предположим, в программе используются два пера – красное шириной 3 и черное точечное. Определим переменные для хранения описателей этих перьев:
static HPEN hPen1, hPen2;
В процессе обработки сообщения WM_CREATE создадим перья:
hPen1 = CreatePen (PS_SOLID, 3, RGB (255, 0, 0));
hPen2 = CreatePen (PS_DOT, 0, 0);
В процессе обработки сообщения WM_PAINT или когда есть действительный контекст устройства, выберем одно из этих перьев в контекст устройства и можем рисовать, используя его:
SelectObject (hdc, hPen2);
[функции рисования линий]
SelectObject (hdc, hPen1);
[другие функции рисования линий]
В процессе обработки сообщения WM_DESTROY удалить их:
DeleteObject (hPen1);
DeleteObject (hPen2);
Можно создать перья в процессе обработки сообщения WM_PAINT и удалить их после вызова EndPaint.
Можно объединить вызовы функций CreatePen и SelectObject в одну инструкцию:
SelectObject (hdc, CreatePen (PS_DASH, 0, RGB (255, 0, 0)));
Удалить перо можно, выбрав стандартное перо BLACK_PEN в контекст устройства и удаления значения, возвращаемого функцией SelectObject:
DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN)));
Выбирая только что созданное перо в контекст устройства, сохраним описатель, возвращаемый функцией SelectObject:
hPen = SelectObject (hdc, CreatePen (PS_DASH, 0, RGB (255, 0, 0)));
Если это первый вызов, hPen – описатель стандартного черного пера, мы можем теперь выбрать его в контекст устройства и удалить созданное перо (описатель, возвращаемый вызовом функции SelectObject) в одной инструкции:
DeleteObject (SelectObject (hdc, hPen));
Инструмент Brush
Объект кисть – это битовый образ, свойства которого распространяются в горизонтальном и вертикальном направлениях при закрашивании области.
Имеется шесть стандартных (Stock) кистей: WHITE_BRUSH – белая, LTGRAY_ BRUSH – светло-серая, GRAY_ BRUSH – серая, DKGRAY_ BRUSH – темно-серая, BLACK_ BRUSH – черная и NULL_ BRUSH (HOLLOW) – пустая кисть.
Выбрать одну из стандартных кистей в контекст устройства можно аналогично выбору пера, определив переменную типа описателя кисти HBRUSH hBrush; получаем описатель кисти, например, GRAY_BRUSH:
hBrush = GetStockObject (GRAY_BRUSH);
Выберем эту кисть в контекст устройства:
SelectObject (hdc, hBrush);
Теперь внутренняя область рисуемых фигур будет закрашиваться серым.
Если необходимо нарисовать фигуру без рамки, выберем перо NULL_PEN:
SelectObject (hdc, GetStockObject (NULL_PEN));
А если только контур фигуры без закрашивания внутренней области, выберем кисть NULL_BRUSH:
SelectObject (hdc, GetStockObject (NULL_BRUSH));
Для создания сплошной (Solid) логической кисти:
hBrush = CreateSolidBrush (rgbColor);
Для создания штриховой (Hatch) кисти, состоящей из горизонтальных, вертикальных или диагональных линий:
hBrush = CreateHatchBrush (iHatchStyle, rgbColor);
параметр iHatchStyle – стиль штриховки: HS_HORIZONTAL, HS_VERTICAL, HS_BDIAGONAL – диагональная слева направо вверх; HS_FDIAGONAL – диагональная слева направо вниз; HS_CROSS – прямая сетка; HS_DIAGCROSS – диагональная сетка; в обеих функциях rgbColor – цвет штриховых линий.
Промежутки между штриховыми линиями закрашиваются в соответствии с режимом и цветом фона, если режим фона – OPAQUE, то цвет фона используется для закрашивания промежутков между штриховыми линиями, если режим фона – TRANSPARENT, то промежутки между штриховыми линиями не зарисовываются.
Можно создавать кисти, основанные на битовых шаблонах, используя функцию CreatePatternBrush:
hBrush = CreatePatternBrush (hBitmap);
Функция, включающая три рассмотренные ранее функции, строящие кисти:
hBrush = CreateBrushIndirect (&logbrush);
переменная logbrush – структура типа LOGBRUSH («логическая кисть» – logical brush), содержащая поля:
UINT lbStyle – стиль кисти: BS_SOLID – сплошная; BS_HOLLOW, BS_NULL – «пустая» (невидимая); BS_HATCHED – штрихованная; BS_PATTERN, BS_PATTERN8X8 – задаются битовой картой; BS_DIBPATTERN, BS_DIBPATTERN8X8, BS_DIBPATTERNPT – задаются битовой картой DIB (в Windows 95 размер шаблона ограничен 8´8 точек);
COLORREF lbColor – цвет кисти, для пустой или «шаблонной» кисти игнорируется, для кистей с DIB-шаблоном младшее слово определяет, следует ли интерпретировать его цвета как заданные цветовыми компонентами (DIB_RGB_COLORS) или как палитровые (DIB_PAL_COLORS).
Значение поля lbStyle определяет, как интерпретируются другие поля:
lbStyle | lbColor | lbHatch |
BS_SOLID | Цвет кисти | Игнорируется |
BS_HOLLOW | Игнорируется | Игнорируется |
BS_HATCHED | Цвет штриховых линий | Стиль штриховки |
BS_PATTERN | Игнорируется | Описатель битового шаблона |
Получить описатель логической кисти: SelectObject (hdc, hBrush);
Удалить созданную кисть: DeleteObject (hBrush);
Получить информацию о кисти:
GetObject (hBrush, sizeof (LOGBRUSH), &logbrush);
Инструмент Font
Более сложным инструментом является шрифт. Все символы в оконном интерфейсе формируются в соответствии с одним из зарегистрированных в системе шрифтов.
Физический шрифт – файл (образ в памяти) с описанием начертаний всех известных в данном шрифте символов. Логический шрифт – объект GDI, характеризуемый как физическим шрифтом, так и его конкретными характеристиками. Он же является и инструментом, отвечающим за формирование символов.
Для создания логического шрифта используется функция
HFONT CreateFont (int nHeight, int nWidth, int nEscapement,
int nOrientation, int fnWeight, DWORD fdwItalic, DWORD fdwUnderline,
DWORD fdwStrikeOut, DWORD fdwCharSet,
DWORD fdwOutputPrecision, DWORD fdwClipPrecision,
DWORD fdwQuality, DWORD fdwPitchAndFamily,
LPCTSTR lpszFace);
возвращающая описатель созданного инструмента (NULL – ошибка), параметры:
nHeight – основной размер (высота) шрифта в логических единицах: положительное значение определяет высоту знакоместа, отрицательное – высоту шрифта (после смены знака), нулевое – размер по умолчанию; при неточном соответствии требуемого размера выбирается наибольший, не превышающий требуемый;
nWidth – «приблизительная» ширина шрифта, если 0 – стандартная для выбранного основного размера;
nEscapement – направление вывода строки символов (угол между базовой линией и горизонтальной осью по часовой стрелке в десятых долях градуса);
nOrientation – ориентация отдельного символа (исчисление аналогично предыдущему параметру, в Windows 9x ориентация символов и направление вывода должны совпадать);
fnWeight – толщина символов в условных единицах от 0 до 1000, например: 0 (FW_DONTCARE) – стандартный (по умолчанию), 400 (FW_NORMAL, FW_REGULAR) – стандартная толщина, обычный шрифт, 700 (FW_BOLD) – жирный, выделенный, и т.д.;
fdwItalic, fdwUnderline, fdwStrikeOut – флаги, указывающие, является ли шрифт наклонным, подчеркнутым или перечеркнутым;
fdwCharSet – тип символьного набора: DEFAULT_CHARSET, ANSI_CHARSET, OEM_CHARSET и т.д. (национальные наборы символов);
fdwOutputPrecision – «точность вывода» символов, фактически предпочтение типа шрифта при наличии альтернативного выбора: OUT_DEFAULT_PRECIS, OUT_DEVICE_PRECIS и т.д.;
fdwClipPrecision – точность отсечения;
fdwQuality – качество вывода;
fdwPitchAndFamily – комбинация по «ИЛИ» двух групп параметров, действующих при неопределенном имени шрифта:
– питч (шаг символов) – 2 младших бита: DEFAULT_PITCH, FIXED_PITCH, VARIABLE_PITCH;
– «семейство» шрифта – 4 старших бита: FF_DONTCARE – по умолчанию, FF_MODERN – моноширинные шрифты, FF_ROMAN – «книжные» с засечками (переменный шаг), FF_SWISS – без засечек (переменный шаг), FF_SCRIPT – «рукописные» и курсивные;
lpszFace – имя шрифта, обычно совпадает с именем его дискового файла; если NULL – система подбирает шрифт, наиболее отвечающий заданным требованиям, иначе явно указанный шрифт перекрывает их.
Функция CreateFontIndirect (const LOGFONT* lplgFont); использует в качестве аргумента структуру с полями аналогичного назначения.
Параметры шрифта не включают цвет отображающего инструмента. Управление цветом выводимого текста осуществляется функциями
COLORREF SetTextColor (hdc, crColor);
COLORREF GetTextColor (hdc);
Базовой функцией вывода символа является
BOOL TextOut (hdc, nXStart, nYStart, lpString, cbString);
Позицией символа считается верхний левый угол его знакоместа.
Дата добавления: 2017-10-04; просмотров: 1172;