Чтобы изменить текущее перо или кисть, выбираем стандартное перо или кисть или создаём пользовательские, а затем выбираем их в объекте контекста устройства. Выбранные перо или кисть используются до следующего явного выбора других инструментов рисования.
3)Выбор стандартных инструментов рисования
Выбирается перо или кисть вызовом функции SelectStockObject класса cdc:
CGdiObject* SelectStockObject (int nIndex);
Параметр nIndex является кодом отдельного стандартного объекта, который передается в объект контекста устройства. Можно вызвать функцию SelectStockObject для выбора стандартного шрифта.
Например, следующие строки выбирают белое перо и серую кисть.
void CMyView:;OnDraw(CDC* pDC)
(
pDC->SelectStockObject (WHITE_PEN) ;
pDC->SelectStockObject (GRAY_BRUSH) ;
// Вызов других графических функций и рисование графики ... // (линии и границы будут белыми, внутренние области // фигур с замкнутыми контурами - серыми)
}
При выборе пера null_pen линии не рисуются. Значит, выбор не удачен. Аналогично при выборе NULL_BRUSH внутренняя часть фигуры не закрашивается. Этот инструмент удобен при рисовании фигур, состоящих только из границы (прямоугольник), если необходимо оставить неизменным существующее на экране графическое изображение внутри границы.
Примечание
Стандартное перо рисует сплошные линии шириной в один пиксель независимо от заданного режима отображения. Стандартная кисть закрашивает сплошным цветом, а не узорами.
4)Создание инструментов рисования
Можно создать перо или кисть, выполнив следующие действия.
1. Создаём экземпляр класса СРеn для пера или CBrush для кисти.
2. Вызываем соответствующую функцию класса СРеn или CBrush для инициализации пера или кисти.
3. Выбираем перо или кисть в объекте контекста устройства, сохраняя указатель на предыдущее перо или кисть.
4. Вызываем функции рисования для выполнения графического вывода.
5. Снова выбираем старое перо или кисть в объекте контекста устройства.
Для создания временного пера или кисти можно объявить экземпляр класса СРеn или CBrush как локальный объект внутри функции, генерирующей графический вывод. Этот метод продемонстрирован в примере фрагмента программы, приведенном в конце этого раздела. При многократном использовании в программе выбранного пера или кисти объект удобнее объявить как переменную класса представления или любого класса, управляющего окном вывода.
Для инициализации пера вызываем функцию CreatePen класса СРеn.
BOOL CreatePen (int nPenStyle, int nWidth, COLORREF crColor) ;
Параметр nPenStyle описывает стиль линии, нарисованной пером. Присваивание стиля ps_null создает перо, совпадающее со стандартным пером null_pen. Стиль ps_insideframe выбирает перо для рисования границы вокруг фигуры с замкнутым контуром, расположенной внутри ограничивающего прямоугольника. Ограничивающие прямоугольники и эффекты стиля ps_insideframe описаны далее. Стили ps_dash, ps_dot, ps_dashdot и PS dashdotdot используются, если ширина пера равна 1 пикселю. Если ширина пера превышает этот размер, то перечисленные стили генерируют сплошные линии.
Параметр nWidth описывает ширину линии в логических единицах, используемых в текущем режиме отображения. Если ширина пера — 0, то
ширина линии — 1 пиксель, независимо от текущего режима отображения. Такая ширина генерируется и стандартным пером, и заданным по умолчанию.
Параметр crColor задает цветовой код линии. Легче всего описать цвет, используя макрос Win32 rgb.
ColorRef RGB (bRed, bGreen, bBlue)
Параметры bRed, bGreen и bBlue показывают относительную интенсивность красного, зеленого и синего цветов. Каждому параметру можно присвоить значение в диапазоне от 0 до 255. В табл. 19.3 приведены значения, которые передаются в макрос RGB для описания 16 чистых цветов, доступных в стандартном графическом режиме VGA.
Обратим внимание: перу присваивается только чистый цвет. Чистый цвет - это цвет, генерируемый аппаратными средствами для видеоотображения, который не требуется имитировать смешиванием различных цветов (известным как имитация полутонов (dithering)). Если присвоить перу цветовой код, который не относится НИ к одному из чистых цветов, то линия будет нарисована с использованием ближайшего чистого цвета. Исключение из этого правила: если перо имеет стиль ps_insideframe и ширину более 1 пикселя, то Windows использует полутона (если присвоенный цвет не является чистым).
Примечание
Класс СPеn предоставляет более совершенную функцию инициализации пера, называемую ExtCreatePen. В среде Windows NT эта функция задает способ изменения и объединения широких перьев, что позволяет создавать перья с пользовательским стилем. Однако Windows 95 не поддерживает большинство из этих средств. Заметим также, что вместо вызова функции CPen: :CreatePen, объект пера можно инициализировать при его создании, передавая конструктору СPеn соответствующие параметры. Информация о
конструкторах СРеn и ExtCreatePen - в следующих разделах справочной системы: Visual C++ Documentation, Reference, Microsoft Foundation Class Library and Templates, Microsoft Foundation Class Library, Class Library Reference, СРеп.
Кисть можно инициализировать так, чтобы она окрашивала однородным цветом внутреннюю область фигур, вызывая функцию CreateSolidBrush класса CBrush с параметром crColor, описывающим цвет заливки. Можно задать любой цвет. Если присвоенный цвет не является чистым, то Windows генерирует псевдополутоновый цвет (полученный имитацией полутонов).
BOOL CreateSolidBrush (COLORREF crColor);
Кроме того, для заливки внутренней области фигур можно инициализировать кисть, вызвав функцию CreateHatchBrush класса Cbrush.
BOOL CreateHatchBrush (int nindex, COLORREF crColor);
Параметр nIndex задает узор. Параметр crColor описывает цвет линий штриховки.
Функция CreatePatternBrush класса CBrush вызывает кисть для заполнения фигуры заданным узором.
BOOL CreatePatternBrush (CBitmap* pBitmap);
Параметр pBitmap является указателем на объект растрового изображения. Если фигура рисуется с помощью кисти, то ее внутренняя область полностью заполняется копиями растрового изображения, размещаемыми одна возле другой. Объект растрового изображения создается и инициализируется. Задаём размер растрового изображения равным 8х8 пикселей.
Если растровое изображение монохромное, то Windows использует текущие цвета текста и фона.
Примечание
Объект кисть (как и перо) можно инициализировать при создании, передавая конструктору CBrush соответствующие параметры. Информация об этом - в следующих разделах справочной системы: Visual C++ Documentation, Reference, Microsoft Foundation Class Library and Templates, Microsoft Foundation Class Library, Class Library Reference, CBrush.
Как только перо или кисть инициализированы, их выбирают в объекте контекста устройства с помощью функции SelectObject класса cdc. Для выбора пера вызовите функцию SelectObject,
CPen* SelectObject (CPen* рРеn) ;
где рРеn — указатель на объект-перо. Функция SelectObject возвращает указатель на предыдущий объект-перо, выбранный в объекте контекста устройства. Если перо ранее не выбиралось, это будет временный объект пера, заданного по умолчанию. Для выбора кисти вызывается функция SelectObject.
CBrush* SelectObject (CBrush* pBrush);
где pBrush — указатель на объект-кисть. Функция SelectObject возвращает указатель на ранее выбранную кисть. Если она ранее не выбиралась, то это будет временный объект для заданной по умолчанию кисти.
При вызове функции SelectObject для выбора пера или кисти нужно сохранить возвращаемый указатель. После вызова графических функций для отображения выводимой информации с использованием пера или кисти (что описано далее в этой же главе) удалите перо или кисть из объекта контекста устройства и вызовите функцию SelectObject для выбора предыдущего объекта.
Перо или кисть необходимо удалить из объекта контекста устройства, чтобы объект контекста устройства не хранил некорректный дескриптор
после удаления объекта. При инициализации пера или кисти Windows добавляет дескриптор, сохраняемый внутри объекта. При выборе пера или кисти объект контекста устройства также сохраняет этот дескриптор. Когда объекты выходят за пределы области видимости или удаляются, деструктор объекта уничтожает дескриптор. Однако этот шаг не нужно выполнять, если объект контекста устройства удаляется до удаления объекта пера или кисти.
В моей программе будут рисоваться два эллипса, первый по формуле
x2 y2
{ --- --- =1 ;
a2 b2
а второй, по формуле
x=a cos t
{
y=b sin t
Вот функция, которая рисует оба эллипса:
void CEllipseView::OnDraw(CDC* pDC)
{
CEllipseDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
float x, y, t, PI = 3.1415926;
for (x = -pDoc->A; x < pDoc->A; x+=0.005)
{
y = sqrt(abs((1.0 - (x*x)/(pDoc->A*pDoc->A))*(pDoc->B*pDoc->B)));
pDC->SetPixel(x*5+pDoc->A*5+10,
y*5+pDoc->B*5+10, RGB(0xFF,0,0));
y = -sqrt(abs((1.0 - (x*x)/(pDoc->A*pDoc->A))*(pDoc->B*pDoc->B)));
pDC->SetPixel(x*5+pDoc->A*5+10,
y*5+pDoc->B*5+10, RGB(0xFF,0,0));
}
for (t = -PI; t < PI; t+=0.005)
{
x = pDoc->Ac * cos(t);
y = pDoc->Bc * sin(t);
pDC->SetPixel(x*5+MAX(pDoc->A,pDoc->Ac)*15+20,
y*5+MAX(pDoc->B,pDoc->Bc)*5+10, RGB(0,0x20,0x80));
}
Для передачи параметров в функцию рисования я создал два диалоговых окна, одно для первой формулы (первого эллипса), другое – для второй формулы (второго эллипса). При нажатии на иконки эллипсов появляются эти диалоговые окна и предлагается ввести соответствующие параметры формулы эллипса. Диалоговые окна вызываются в файле EllipseDoc.Cpp, вот функции вызова обоих диалоговых окон: