Основные графические объекты и CDIГрафические объекты - это объекты, с помощью которых осуществляется вывод на экран изображений. Их использование в приложениях для создания графических изображений возможно на различных уровнях - в этом раздели будет рассмотрена работа с объектами с использованием функций GDI. Графических объектов не так уж и много:
Получение изображения перерисовкой пикселейИзменить один контекста устройства дает возможность вызов функции SetPixel(): WINGDIAPI COLORREF WINAPI SetPixel(HDC hdc,int x,int y,COLORREF color); Первый аргумент хэндл контекста устройства (как и во всех последующих примерах - поэтому далее этот параметр не будет поясняться). x и y - координаты прорисовываемого пикселя. color - цвет пикселя, как совокупность трех цветов (red - красного, зеленого - green и синего - blue, или RGB -значение цвета ). Каждая из этих микроточек может иметь значение, соответствующее интенсивности свечения от 0 до 255 (максимальная яркость). Таким образом может быть определено почти 17 миллионов цветов. Число отображаемых цветов может быть меньше и зависит от видиокарты компьютера и установок Windows. Можно задать цвет как 16 ричное число: 0xx00bbggrr Макрос RGB, возвращающий цвет пикселя, определен как:
#define RGB(r, g, b) ((COLORREF) (((BYTE)(r)
| ((WORD) ((BYTE)(g)) <8 ))
| (((DWORD) (ВYTЕ) (P)) <16 )))
Пример использования функции SetPixel(). В примере точками рисуется зеленая линия длиной 100 пикселей. HDC hDc = GetDC(Handle); for(int i=0; i < 100;i++) SetPixel(hDc,100,100,RGB(0,255,0)): ReleaseDC(Handle,hDc); В принципе для рисования линий более подходят функции работы с перьями - о чем речь пойдет ниже. Перо и его использование для рисования графичиских примитивовПеро перед использованием создается с помощью функции CreatePen. Эта функция создает логическое перо, которое задает указанный стиль, ширину, и цвет пера. Перо перед использованием выбирается в контекст устройства. HPEN CreatePen ( int PenStyle, // стиль пера int nWidth, // ширина COLORREF crColor // цвет ); Стиль пера задают константы: PS_SOLID - сплошная линия. PS_DASH - штриховая линия. PS_DOT - пунктирная линия. PS_DASHDOT - штрих пунктирная линия. PS_DASHDOTDOT - чередующиеся черточки и двойные точки. PS_NULL - невидимое перо. PS_INSIDEFRAME - перо для линий, выводимых внутри рамки закрытых форм (например, Ellipse, Rectangle, RoundRect, Pie, и Chord функции). Перо может быть создано также функцией CreatePenIndirect(). HPEN CreatePenIndirect ( CONST LOGPEN *lplgpn // указатель на структуру LOGPEN ); Функция SelectObject выбирает объукт (в данном случае перо) в указанный контекст устройства. Новый объект заменяет предыдущий объект того же самого типа и возвращает HDC заменяемого объекта. HGDIOBJ SelectObject ( HDC hdc, // дескриптор контекста устройства HGDIOBJ hgdiobj // дескриптор объекта который вибирается ); Для рисования перьями используются функции:
Эти функции работают только в Windows NT:
Следующие примеры показывают использование некоторых описанных функций.
void __fastcall
TForm1::Button1Click(TObject *Sender)
{
HPEN hPen,hPenOld;
//Получаем контекст окна приложения
HDC hDc = GetDC(Handle);
//Создаем перо сплошное, толщиной 2,красное
hPen=CreatePen(PS_SOLID,2,RGB(255,0,0));
//Выбираем перо в контекст устройства и запоминаем старое
hPenOld = SelectObject(hDc,hPen);
//Рисуем линию
MoveToEx(hDc,0,0,NULL);
LineTo(hDc,Width,Height);
//Рисуем прямоугольник
Rectangle(hDc,50,50,100,100);
//Рисуем прямоугольник со скругленными углами
RoundRect(hDc,150,150,400,400,50,50);
//Рисуем элипс
Ellipse(hDc,100,100,300,300);
//Рисуем сектор элипса
Pie(hDc,0,0,200,200,0,0,0,100);
//Рисуем дугу
Arc(hDc,0,0,250,250,125,0,50,0);
//Рисуем сегмент, замкнутый дугой
AngleArc(hDc,100,150,50,0,180);
//Рисуем сегмент элипса
Chord(hDc,0,0,200,200,0,0,10,200);
//Рисуем ломаную линию
TPoint tPoint[3];
tPoint[0] = Point(100,500);
tPoint[1] = Point(150,400);
tPoint[2] = Point(100,300);
Polyline(hDc,tPoint,3);
//Рисуем кривые Блейзера
TPoint tPoints[7];
tPoints[0]=TPoint(0,0);
tPoints[1]=TPoint(800,30);
tPoints[2]=TPoint(0,40);
tPoints[3]=TPoint(550,400);
tPoints[4]=TPoint(350,200);
tPoints[5]=TPoint(550,400);
tPoints[6]=TPoint(0,500);
PolyBezier(hDc,tPoints,6);
//Возвращаем все на свои места
SelectObject(hDc,hPenOld);
DeleteObject(hPen);
DeleteObject(hPenOld);
ReleaseDC(Handle,hDc);
//Или
DeleteDC(hDc);
}
Для того, чтобы рисовать не в форме приложения,а на экране дисплея, достаточно в предыдущем примере получить контекст экрана монитора.
HDC hDc=CreateDC("DISPLAY",NULL,NULL,NULL);
Несмотря на то, что многие функции работают только в Windows NT, но в BorlandC++ Builder доступ к ним имеется через свойство Canvas компонентов. Кисти, их создание и применениеКисти используются в Windows в основном для заливки внутренних областей. Чтобы использовать кисть ее необходимо создать с помощью функций CreateSolidBrush, CreateDIBPatternBrush, CreateHatchBrush, CreatePatternBrush... и затем, как и для пера, выбрать их в контекст отображения, используя функцию SelectObject. После применения средств рисования их можно удалить с помощью функции DeleteObject. Основные функции для создания кисти, следующие: Функция CreateSolidBrush создает логическую кисть, которая имеет указанный цвет. HBRUSH CreateSolidBrush ( COLORREF crColor // цвет кисти ); Функция CreateHatchBrush создает логическую кисть, которая имеет указанный образец штриховки и цвет. HBRUSH CreateHatchBrush ( Int fnStyle, // стиль штриховки COLORREF clrref // цвет ); FnStyle определяет стиль штриховки кисти. Этот параметр может иметь одно из следующих значений: HS_BDIAGONAL штриховка 45 градусов слева направо; HS_CROSS горизонтальная и вертикальная штриховка(квадратиками); HS_DIAGCROSS Штриховка сеточкой 45 градусов; HS_FDIAGONAL С 45 градусами справа на лево; HS_HORIZONTAL горизонтальная штриховка; HS_VERTICAL вертикальная штриховка. Функция CreatePatternBrush создает логическую кисть с указанным растровым изображением. HBRUSH CreatePatternBrush ( HBITMAP hbmp // Хэндл изображения ); В Win9x кисти, созданные как точечные рисунки в формате растрового изображения больше чем 8x8 пикселы не поддерживаются. Если точечный рисунок больше, то используется только его часть. Цвет однобитных кистей при значении бита 1 соответствует цвету текста и фона контекста устройства, 0 текущему цвету контекста. Исполльзования кистейМы уже использовали кисти при рассмотрении фигур, созданных перьями. Это все функции, которые предназначены для рисования предопределенно замкнутых фигур ( Rectangle(), Ellipse(), RoundRect(), Pie(), Chord(), PolyGon(), PolyPolyGon()). Здесь используются совместно кисти и перья и если их параметры не переопределить, то используются атрибуты по умолчанию как для пера так и для кисти. Атрибуты контекста графических устройств
Примеры работы с кистямиИспользование одноцветной и штриховых кистей:
void __fastcall
TForm1::Button1Click(TObject *Sender)
{
HPEN hPen,hPenOld;
HBRUSH hBrush,hBrushOld;
//Если будем ртсовать в приложении
HDC hDc = GetDC(Handle);
//Если рисуем на экране монитора
HDC hDc=CreateDC("DISPLAY",NULL,NULL,NULL);
//Если использовать одноцветную кисть
hBrush=CreateSolidBrush(RGB(0,0,255));
//Если использовать штриховую кисть кисть
hBrush=CreateHatchBrush(HS_HORIZONTAL,RGB(0,0,255));
//Без этой функции штриховка будет по белому квадрату
//с этой функцией под штриховкой то, что было на экране
//монитора или в окне приложения
SetBkMode(hDc,TRANSPARENT);
//Как и в примерах выше создаем перо для контура
hPen=CreatePen(PS_SOLID,2,RGB(255,0,0));
//Выбираем созданные объекты в контекст устройства
hPenOld = SelectObject(hDc,hPen);
hBrushOld=SelectObject(hDc,hBrush);
//Рисуем прямоугольник
Rectangle(hDc,0,0,200,200);
//Освобождаем ресурсы
SelectObject(hDc,hPenOld);
DeleteObject(hPen);
DeleteObject(hPenOld);
DeleteObject(hBrush);
DeleteObject(hBrushOld);
ReleaseDC(Handle,hDc);
DeleteDC(hDc);
}
Использование кисти с созданным растровым изображением:
void __fastcall
TForm1::Button2Click(TObject *Sender)
{
HDC hDc;
HBRUSH hBrush,hBrushOld;
// Массив для пикеселей изображения 10*10 пикселей. При 24
//цветах на каждый пиксель требуется 3 байта или 1.5 unsigned
//short числа, для 10*10 пикселей требуется 15*15=225 чисел.
// Создание кистей из битовых образов размером более 8*8
//пикселей в Win 9x не поддерживается. Если указан битовый
//образ большего размера, используется его часть.
unsigned short usrgMassPix[225];
//Зная как в памяти располагаются биты, например для 24 цветовой
//палитры синий цвет ff0000, можем задать его как цвет кисти
if(GetDeviceCaps(CreateDC("DISPLAY",NULL,NULL,NULL),BITSPIXEL) == 24)
{
for(int i=0; i < 75; i++)
{
usrgMassPix[i*3]=255;
usrgMassPix[i*3+1]=0;
usrgMassPix[i*3+2]=0;
}
}
else //Здесь для других значений или если не знаем как
for(int i=0; i < 225; i++) usrgMassPix[i] =random(255);
//Создаем изображение кисти в памяти 10*10 пикселов и получаем его хэндл
//Функция CreateBitmap будет описана позже
HBITMAP
hBmp =
CreateBitmap(10,10,GetDeviceCaps(CreateDC("DISPLAY",
NULL,NULL,NULL),PLANES),
GetDeviceCaps(CreateDC("DISPLAY",NULL,NULL,NULL),BITSPIXEL),
&usrgMassPix[0]);
//Получаем хэндл устройства
hDc=GetDC(Handle);
//Создаем кисть
hBrush = CreatePatternBrush(hBmp);
//Выбираем кисть в контекст устройства
hBrushOld=SelectObject(hDc,hBrush);
//Здесь можно было выбрать перо для обводки фигуры как и
//в примере выше, но решили воспользоваться пером по умолчанию
//Рисуем кистью, например элипс
Ellipse(hDc,200,200,600,400);
//Возвращаем все в исходное состояние
SelectObject(hDc,hBrushOld);
DeleteObject(hBmp);
DeleteObject(hBrush);
DeleteObject(hBrushOld);
ReleaseDC(Handle,hDc);
DeleteDC(hDc);
}
В данном примере использованы не только перо и кисть, но и объект DC
- растровое изображение, о котором речь пойдет в следующем параграфе.
|