Рисование многоугольников


Для рисования многоугольников служит функция Polygon.

BOOL Polygon (

HDC hdc, II дескриптор контекста отображения

CONST POINT *lppt, II указатель на массив структурPOINT

int cPoinis II размер массива структурPOINT

};

Параметры функцииPolygon no своему смыслу аналогичны параметрам функцииPolyline.ФункцияPolygon не использует текущую позицию пера и не изменяет ее после завершения работы.

В массиве структурPOINT каждая вершина может быть указана только один раз. ФункцияPolygonавтоматически замыкает линию, образующую многоугольник.

 


5.7.3.4Выбор кисти

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

Для выбора встроенных кистей необходимо пользоваться макрокомандой GetStockBrush, определенной в файле windows.h следующим образом:

#define GetStockBrush(i) ((НBRUSH)GetStockObject(i) В качестве параметра для этой макрокоманды можно использовать следующие значения:

 

    Значение i   Oписание  
BLACK_BRUSH WHITE_BRUSH GRAY_BRUSH LTGRAY_BRUSH DKGRAY_BRUSH NULL_BRUSH HOLLOW_BRUS H   Кисть черного цвета Кисть белого цвета Серая кисть Светло-серая кисть Темно-серая кисть Бесцветная кисть, которая ничего не закрашивает Синоним для NULL BRUSH  

 

Прежде чем использовать полученную кисть, ее необходимо выбрать в контекст отображения. Это можно сделать, используя макрокомандуSelectBrush:

#define SelectBrush(hdc, hbr) ((HBRUSH)SelectObject((hdc), (HGDIOBJ)(HBRUSH)(hbr)))

Для создания цветной кисти необходимо воспользоваться функцией CreateSolidBrush:

HBRUSH CreateBrush (COLORREF cirref);

После использования кисти ее следует удалить, для освобождения памяти, не следует забывать, что перед удалением кисти, необходимо выбрать в контекст старую кисть. Для удаления кисти служит определенная в файле windows.h макрокоманда DeleteBrush.

#define DeleteBrush(hbr) DeleteObject((HGDIOBJ)(HBRUSH)(hbr))

Для штриховки внутренней области необходимо создать соответствующую кисть. HBRUSH CreateHatchBrush(int fnStyle, COLORREF clrref);

Параметр clrrеl определяет тип штриховки.

Стиль штриховки   Описание  
HS_BDIAGONAL HS_FDIAGONAL HS_DIAGCROSS HS_HORIZONTAL HS_VERTICAL HS_CROSS   Штриховка под углом а = 45* Штриховка под углом а = 135" Двойная штриховка под углом а = 45" и Р = 135* Штриховка горизонтальными линиями Штриховка вертикальными линиями Двойная штриховка горизонтальными и вертикальными линиями  

 

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

HBRUSH CreatePatternBrush (HBITMAP hBilmap);

Ниже представлено приложениеDraw, демонстрирующее некоторые графические возможности GDI.

 

Листинг

 

Файл RDraw.cpp

 

//======================================================================

// Приложение Rdaw

// Демонстрация использования функции рисования графических изображений

//=====================================================================

#define STRICT

#include <windows.h>

#include <windowsx.h>

 

// Прототипы функций

 

BOOL InitApp (HINSTANCE);

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

 

void DrawLines(HDC); // Рисование линий

void DrawPolyline(HDC); // Рисование полилиний

void DrawArc(HDC); // Рисование дуги эллипса

void DrawRectangles(HDC); // Рисование прямоугольников

void DrawPolygon(HDC); // Рисование полигонов

void DrawEllipse(HDC); // Рисование эллипса

void DrawCircle(HDC); // Рисование окружности

void DrawPie(HDC); // Рисование сектора эллипса

void DrawChord(HDC); // Рисование сегмента эллипса

 

// Имя класса окна

CCHAR szClassName[] ="DrawClass";

 

// Заголовок окна

CCHAR szWindowTitle[]="Приложение Rdraw";

 

// Размеры внутренней области окна

short cxClient, cyClient;

 

// Код выбранной строки меню "Draw"

int nFigures=0;

 

// Режим фона

int nBkMode=0;

 

// Код растровой операции

int nROP2 = R2_COPYPEN;

 

// ==================================================================

// Функция WinMain

//===================================================================

 

int WINAPI

WinMain(HINSTANCE hinstance,

HINSTANCE hPrevlnstance,

LPSTR IpszCmdLine,

int nCmdShow)

{

 

MSG msg; // Структура для работы с сообщениями

HWND hwnd; // Идентификатор главного окна приложения

// Определяем наличие загруженной копии приложения

if (FindWindow(szClassName, szWindowTitle))

return FALSE;

// Инициализируем приложение

if(!InitApp(hinstance))

return FALSE;

// Создаем главное окно приложения

hwnd = CreateWindow(

szClassName, // имя класса окна

szWindowTitle, // заголовок окна

WS_OVERLAPPEDWINDOW, //стиль окна

CW_USEDEFAULT, // задаем размеры и расположение

CW_USEDEFAULT, // окна, принятые по умолчанию

CW_USEDEFAULT,

CW_USEDEFAULT,

0, 0, hinstance, NULL);

 

if (!hwnd) return FALSE;

 

// Рисуем главное окно максимального размера

ShowWindow(hwnd, SW_MAXIMIZE);

UpdateWindow(hwnd);

// Запускаем цикл обработки сообщений

while(GetMessage(&msg, 0, 0, 0))

{

DispatchMessage(&msg);

}

return msg.wParam;

}

 

//===================================================================

// Функция InitApp // Выполняет регистрацию класса окна

//===================================================================

BOOL InitApp(HINSTANCE hinstance)

{

 

ATOM aWndClass; // атом для кода возврата

WNDCLASS wc; // структура для регистрации класса окна

// Записываем во все поля структуры нулевые значения

memset(&wc, 0, sizeof(wc));

// Подключение меню

wc.lpszMenuName = NULL;

wc.style = CS_HREDRAW | CS_VREDRAW;

wc.lpfnWndProc = (WNDPROC) WndProc;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = hinstance;

wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);

wc.lpszClassName = (LPSTR)szClassName;

aWndClass = RegisterClass(&wc);

// Регистрация класса

return (aWndClass !=0);

}

 

 

//=================================================================

// Функция WndProc

//=================================================================

 

LRESULT CALLBACK

WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM IParam)

{

HDC hdc;

PAINTSTRUCT ps;

 

switch (msg) {

// При изменении размеров окна сохраняем новые значения ширины и высоты

case WM_SIZE:

// Размер клиентской части окна по горизонтали

cxClient = LOWORD(IParam),

// Размер клиентской части окна по верикали

cyClient = HIWORD(IParam);

return 0;

 

// Рисование в окне

case WM_PAINT:

hdc = BeginPaint(hwnd, &ps);

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

// с началом координат в левом нижнем углу окна.

SetMapMode(hdc, MM_LOMETRIC);

SetViewportOrgEx(hdc, 0, cyClient, NULL );

// Устанавливаем режим отображения.

SetBkMode(hdc, nBkMode);

// Устанавливаем растровую операцию.

SetROP2(hdc, nROP2);

 

DrawLines(hdc); // прямые линии

/*

DrawArc(hdc); // дуга окружности

DrawRectangles(hdc); // прямоугольники

DrawPolygon(hdc); // полигон

DrawEllipse(hdc); // эллипс

DrawCircle(hdc); // окружность

DrawPie(hdc); // сектор эллипса

DrawChord(hdc); // сегмент эллипса

DrawPolyline(hdc); // полилиния

*/

 

// освобождаем контекст отображения

EndPaint(hwnd, &ps);

return 0;

case WM_DESTROY:

PostQuitMessage(0);

return 0;

default:

break;

}

return DefWindowProc(hwnd, msg, wParam, IParam);

}

Файл RDrawfn.cpp

 

//===================================================================

// Файл Rdrawfn.cpp

//===================================================================

 

//-----------------------------

// Функции для приложения Rdraw:

//------------------------------

 

# define STRICT

# include <windows.h>

# include <windowsx.h>

 

// Размеры внутренней области окна

extern short cxClient, cyClient;

 

 

//-------------------------------------------------

// DrawLines

// Рисование линий различной толщины и стиля

//--------------------------------------------------

 

void DrawLines(HDC hdc)

{

HPEN hpenW10, hpenW50;

HPEN hpenDot, hpenDash, hpenDashDot, hpenOldPen;

 

// 1. Создание перьев

// 1.1. перо толщиной 1 мм.

hpenW10 = CreatePen(PS_SOLID, 10, RGB(0,0,0));

// 1.2. перо толщиной 5 мм.

hpenW50 = CreatePen(PS_SOLID, 50, RGB(0,0,0));

// 1.3. пунктирное перо.

hpenDot = CreatePen(PS_DOT, 0, RGB(0,0,0));

// 1.4. штриховое перо.

hpenDash = CreatePen(PS_DASH, 0, RGB(0,0,0));

// 1.5. штрихпунктирное перо

hpenDashDot = CreatePen(PS_DASHDOT, 0, RGB(0,0,0));

// 2. Рисуем две линии различной толщины пером, находящиеся

// в контексте отображения.

// 2.1. помещаем перо в начальныю позицию

MoveToEx(hdc, 100, 100, NULL);

// 2.2. рисуем линию

LineTo(hdc, 600,100);

// 2.3. выводим поясняющий текст

TextOut(hdc, 700,100,

"PS_SOLID. Сплошная, толщиной 1 пиксел.", 38);

 

// 3. Перед рисованием различными перьями, запоминаем перо

// находившееся в контексте отображения и одновременно

// выбираем перо толщиной 1 мм.

hpenOldPen = SelectPen(hdc, hpenW10);

MoveToEx(hdc, 100, 200, NULL);

LineTo(hdc, 600, 200);

TextOut(hdc, 700, 200, "PS_SOLID. Сплошная, толщиной 1 мм.", 34);

 

// 4. Перебираем созданные нами перья

SelectPen(hdc, hpenW50);

MoveToEx(hdc, 100, 300, NULL);

LineTo(hdc, 600, 300);

TextOut(hdc, 700, 300, "PS_SOLID. Сплошная, толщиной 5 мм.", 34);

 

SelectPen(hdc, hpenDot);

MoveToEx(hdc, 100, 400, NULL);

LineTo(hdc, 600, 400);

TextOut(hdc, 700, 400, "PS_DOT. Пунктирная толщиной 1 пиксел.", 40);

 

SelectPen(hdc, hpenDash);

MoveToEx(hdc, 100, 500, NULL);

LineTo(hdc, 600, 500);

TextOut(hdc, 700, 500, "PS_DASH. Штриховая толщиной 1 пиксел.", 36);

 

SelectPen(hdc, hpenDashDot);

MoveToEx(hdc, 100, 600, NULL);

LineTo(hdc, 600, 600);

TextOut(hdc, 700, 600, "PS_DASHDOT. Штрихпунктирная толщиной 1 пиксел.", 46);

 

TextOut(hdc, 700, 800, "Для тренировки, попытайтесь использовать цвет.", 46);

// 5. Выбираем старое перо в контекст отображения

SelectPen(hdc, hpenOldPen);

 

// 6. Удаляем созданные нами перья

DeletePen(hpenW10);

DeletePen(hpenW50);

DeletePen(hpenDot);

DeletePen(hpenDash);

DeletePen(hpenDashDot);

}

 

 

//----------------------

// DrawPolyLine

// Рисование полилинии

//----------------------

 

void DrawPolyline(HDC hdc)

{

// Массив координат точек излома полилинии

POINT ptPoints[]=

{

{10, 10}, {100,310},

{40, 300}, {300, 15},

{135,340}, {113, 125},

{250, 137}, {300, 300},

};

 

// Рисуем ломаную линию

Polyline(hdc, ptPoints, sizeof ptPoints / sizeof ptPoints[0]);

}

 

 

//------------------------------

// DrawArc

// Рисование дуги эллипса

//------------------------------

 

void DrawArc(HDC hdc)

{

HPEN hpenW10, hpenOldPen;

 

// Создаем перо 1 мм

hpenW10 = CreatePen(PS_SOLID, 10, RGB(0,0,0));

// Выбираем созданное перо в контекст отображения и

// запоминаем перо установленное в контексте отображения

// по умолчанию.

hpenOldPen = SelectPen(hdc, hpenW10);

// Рисуем дугу

Arc(hdc,

1200, 600, // верхний левый угол прямоугольника

1900, 100, // нижний правый угол прямоугольника

1750, 650, //начало

1850, 0); //конец

// Выбираем старое перо в контекст отображения

SelectPen(hdc, hpenOldPen);

// Удаляем созданное перо DeletePen(hpenW10);

}

 

 

//---------------------------

// DrawRectangles

// Рисование прямоугольников

//----------------------------

 

void DrawRectangles(HDC hdc)

{

HPEN hpenW10, hpenOldPen;

HBRUSH hbrush, hbrushOldBrush;

POINT pPoint[2];

RECT rect={350, 500, 400};

 

// Рисуем прямоугольник вокруг внутренней области окна.

// Так как установлен метрический режим отображения, а

// размеры окна, передаваемые вместе с сообщением WM_SIZE,

// выражены в пикселах, выполняем преобразование физических

// координат в логические

 

pPoint[0].x = 0;

pPoint[0].y = cyClient;

pPoint[1].x = cxClient;

pPoint[1].y = 0;

DPtoLP(hdc, pPoint, 2);

 

// Создаем перо толщиной 1 мм и выбираем его в контекст отображения

hpenW10 = CreatePen(PS_SOLID, 10, RGB(0,0,0));

hpenOldPen = SelectPen(hdc, hpenW10);

 

// Рисуем прямоугольник

Rectangle(hdc, pPoint[0].x, pPoint[0].y, pPoint[1].x, pPoint[2].y);

 

// Выбираем серую кисть

hbrush = GetStockBrush(GRAY_BRUSH);

hbrushOldBrush = SelectBrush(hdc, hbrush);

 

// Рисуем прямоугольник закрашенный серым цветом

Rectangle(hdc, 100, 500, 300, 50);

// Создаем и выбираем кисть для штриховки

hbrush = CreateHatchBrush(HS_DIAGCROSS, RGB(0,0,0));

SelectBrush(hdc, hbrush);

// Рисуем заштрихованный прямоугольник

Rectangle(hdc, 50, 300, 500,100);

// Выбираем старое перо и кисть

SelectPen(hdc, hpenOldPen);

SelectBrush(hdc, hbrushOldBrush);

// Заштриховываем прямоугольную область кистью

// brush, которая НЕ ВЫБРАНА в контексте

FillRect(hdc, &rect, hbrush);

// Рисуем прямоугольник со скругленными углами

RoundRect(hdc, 550, 200, 800, 100, 50, 50);

// Удаляем созданные нами перо и кисть

DeletePen(hpenW10);

DeleteBrush(hbrush);

}

 

//---------------------------

// DrawPolygon

// Рисование прямоугольника

//------------------------------

 

void DrawPolygon(HDC hdc)

{

HBRUSH hbrush, hbrushOldBrush;

int nOldPolyFillMode;

// Координаты вершин первого многоугольника

POINT ptPoints1[]=

{

{10, 10}, {100, 310}, {40, 300},

{300, 15}, {135, 340}, {113,125},

{250, 137}, {300, 300}

};

 

POINT ptPoints2[] =

{

{310, 10}, {400 ,310}, {340, 300},

{600, 15}, {435, 340}, {413, 125},

{550,137}, {600, 300}

};

 

// Выбираем встроенную серую кисть

hbrush = GetStockBrush(GRAY_BRUSH);

hbrushOldBrush = SelectBrush(hdc, hbrush);

// Рисуем первый многоугольник в режиме заполнения

//ALTERNATE, установленном по умолчанию

Polygon(hdc, ptPoints1,

sizeof ptPoints1/sizeof ptPoints1[0]);

// Устанавливаем режим заполнения WINDING

nOldPolyFillMode = SetPolyFillMode(hdc, WINDING);

 

// Рисуем второй многоугольник

Polygon(hdc, ptPoints2,

sizeof ptPoints2/sizeof ptPoints2[0]);

// Восстанавливаем старый режим заполнения

SetPolyFillMode(hdc,nOldPolyFillMode);

SelectBrush(hdc, hbrushOldBrush);

}

 

//----------------------------

// DrawEllipse

// Рисование эллипса

//-----------------------------

 

void DrawEllipse(HDC hdc)

{

POINT pPoint[2];

// Эллипс будет вписан во внутреннюю область окна,

// поэтому определяем координаты углов в текущей

// (метрической) системе координат после выполнения

// преобразований.

 

pPoint[0].x = 0;

pPoint[0].y = cyClient;

pPoint[1].x = cxClient;

pPoint[1].y = 0;

DPtoLP(hdc, pPoint, 2);

// Рисуем эллипс

Ellipse(hdc, pPoint[0].x, pPoint[0].y, pPoint[1].x, pPoint[1].y );

}

 

//------------------------------

// DrawCircle

// Рисование сектора круга

//-------------------------------

 

void DrawCircle(HDC hdc)

{

// Рисуем эллипс вписанный в квадрат

Ellipse (hdc, 100, 600, 600, 100);

}

 

 

//------------------------------

// DrawPie

// Рисование сектора круга

//-----------------------------

void DrawPie(HDC hdc)

{

HPEN hpenW10, hpenOldPen;

 

// Создаем перо и выбираем его

hpenW10 = CreatePen(PS_SOLID, 10, RGB(0,0,0));

hpenOldPen = SelectPen(hdc, hpenW10);

// Рисуем сектор круга

Pie(hdc, 100, 600, 800, 100, 650, 650,750, 0);

// Выбираем старое перо и удаляем созданное

SelectPen(hdc, hpenOldPen);

DeletePen(hpenW10);

}

 

//-----------------------------

// DrawChord

// Рисование сегмента круга

//-----------------------------

 

void DrawChord(HDC hdc)

{

HPEN hpenW10, hpenOldPen;

 

hpenW10 =CreatePen(PS_SOLID, 10, RGB(0,0,0));

hpenOldPen = SelectPen(hdc, hpenW10);

 

// Рисуем сегмент круга

Chord(hdc,100,600, 800, 100, 650, 650, 750, 0);

SelectPen(hdc, hpenOldPen);

DeletePen(hpenW10);

}

 



Дата добавления: 2017-01-26; просмотров: 1524;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.09 сек.