gogox
Постоялец
- Регистрация
- 11 Окт 2011
- Сообщения
- 90
- Реакции
- 41
- Автор темы
- #11
Лабораторная работа №11
Тема: «Графика в Borland C++ Builder»Цель работы: познакомиться с графическими возможностями C++ Builder.
Порядок работы: в Windows используется термин контекст устройства (device context) — это что-то вроде грифельной доски, на которой могут рисовать программы (иначе холст — Canvas). Контекст устройства может использоваться для рисования на различных поверхностях:
• на рабочей области или рамке окна;
• на рабочем столе;
• в памяти;
• на принтере или других устройствах вывода. C++Builder предоставляет нам класс TCanvas, чтобы облегчить работу с контекстами устройств. Класс TСanvasимеет много свойств и методов (см. табл.6 и табл.7). Рассмотрим некоторые из них по мере работы над материалом сегодняшнего дня.
Таблица 6
Основные свойства TCanvas
Эти свойства и методы представляют лишь малую часть функциональных возможностей контекста устройства Windows. Тем не менее, они используются в 80 процентах задач, которые возникают при работе с графикой.
Следующий код написанный для компонента Image1 прочертит диагональную линию из верхнего левого в правый нижний угол, рисует эллипс и закрашивает его синим цветом.
Image1 → Canvas → Pen → Color = clRed;
Image1 → Canvas → Brush → Color = clBlue;
Imagel → Canvas → Ellipse(20,20,200,100);
Imagel → Canvas → MoveTo(0,0);
Imagel → Canvas → LineTo(ClientRect.Right, ClientRect.Bottom);
Перед тем, как более подробно рассматривать класс TCanvas, поговорим о графических объектах, используемых в программировании для Windows.
Интерфейс графических устройств (GDI) Windows содержит много типов объектов, определяющих функционирование холста. Наиболее широко используемыми объектами являются перья, кисти и шрифты.
Перо представляет объект, который используется для рисования линий. Линия может быть как отдельной (от одной точки до другой), так и контуром прямоугольника, эллипса или многоугольника. Перо доступно через свойство Penкласса TCanvas. В табл.8 перечислены свойства ТРеn.
Таблица 7
Свойства ТРеn
В большинстве случаев эти свойства используются так, как можно ожидать. В следующем примере рисуется красная пунктирная линия:
Image1 → Canvas → Pen → Color = clRed;
Image1 → Canvas → Pen → Style = psDash;
Image1 → Canvas → MoveTo(20, 20);
Image1 → Canvas → LineTo(120, 200);
Пунктирные линии, как штриховые (dashed), так и точечные (dotted), могут рисоваться только пером с толщиной 1. Стиль psClearиспользуется в том случае, когда контур объекта (прямоугольника, эллипса и закрашенного многоугольника) должен быть невидимым.
Кисть представляет закрашенную область графической фигуры. При изображении замкнутой области (эллипс, прямоугольник или многоугольник) она будет закрашена текущей кистью. Обычно под кистью подразумевается сплошной цвет, хотя это не всегда так. Кисть может включать шаблон или растр. Класс
TCanvasимеет свойство с названием Brush, которое может быть использовано для управления кистью. Свойства TBrushперечислены в табл.9.
Таблица 8
Свойства ТBrush
По умолчанию для свойства Styleустановлено значение bsSolid. Если использовать структурную заливку, то установите для свойства Styleодин из стилей шаблонов (bsHorizontal, bsVertical, bsFDiagonal, bsBDiagonal, bsCross или bsDiagCross).
В следующем примере рисуется круг, заштрихованный под углом 45 градусов. Canvas → Brush → Color = clBlue; Canvas → Brush → Style = bsDiagCross; Canvas →Ellipse(20, 20, 220, 220);
При использовании шаблонов свойство Colorопределяет цвет линий, которые составляют шаблон. При этом автоматически устанавливается прозрачный фон. Это означает, что цвет фона кисти будет таким же, как и у окна, содержащего нарисованную фигуру. Чтобы задать цвет фона, придется обойти VCL и обратиться напрямую к API. Вот как будет выглядеть код, если захотите заштриховать эллипс, вписанный в компонент Image1 (красная штриховку на белом фоне
TCanvas *pCanvas = Image1 → Canvas; pCanvas → Brush → Color = clRed; pCanvas → Brush → Style = bsDiagCross; pCanvas → Ellipse(0, 0, Imagel → Width, Imagel →Height); Теперь цвет фона кисти будет белым.
Другое интересное свойство кистей — возможность использования растровых изображений в качестве фона.
Imagel → Canvas → Brush → Bitmap = newGraphics :: TBitmap; Imagel → Canvas → Brush → Bitmap → LoadFromFile("abort.bmp"); Imagel → Canvas → Ellipse(20, 20, 220, 220); delete Imagel → Canvas → Brush → Bitmap;
В первой строке этого фрагмента кода создается объект TBitmap, который затем присваивается свойству Bitmapкисти. Свойство Bitmapне устанавливается по умолчанию, поэтому нужно специально создать объект TBitmapи присвоить его свойству Bitmap. Во второй строке из файла загружается растр, который должен иметь размер 8х8 пикселов. Можно использовать изображения большего размера, но они будут усечены до размера 8х8. В третьей строке рисуется круг. После того, как круг нарисован, свойство Brushстирается. Очистка свойства Brushтребуется потому, что Builder в данном случае не будет делать это автоматически. Если не очистить свойство Brush, программа вызовет утечку памяти.
Иногда потребуется пустая кисть. Через пустую (или прозрачную) кисть виден фон. Чтобы создать пустую кисть, установите для свойства Styleзначение bsClear.Давайте вернемся к предыдущему примеру и нарисуем второй круг внутри первого, используя, пустую кисть.
Canvas → Pen → Width = 1;
Canvas → Brush → Bitmap = new Graphics :: TBitmap;
Canvas → Brush → Bitmap → LoadFromFile("about.bmp");
Canvas → Ellipse (20, 20, 220, 220);
Canvas → Brush → Style = bsClear;
Canvas → Pen → Width = 5;
Canvas → Ellipse (70, 70, 170, 170);
delete Canvas → Brush → Bitmap;
Растровые изображения и палитры в большинстве случаев используются совместно. Растровые объекты в С++Builder инкапсулированы в классе TBitmap. С его помощью загрузка и вывод изображений выполняются очень просто.
Палитры — это один из тех аспектов программирования в Windows, которые вызывают наибольшую путаницу. Чаще всего управление палитрой берет на себя объект TBitmap.
Начните новое приложение и введите следующий код для обработчика
события OnPaint. Обратите внимание на правильность введенного пути к файлу HANDSHAK.BMP(ондолженнаходитьсявкаталоге
Common Files/Borland Shared/Images/Splash/256Color).
Graphics :: TBitmap* bitmap = new Graphics :: TBitmap;
//bitmap → IgnorePalette = true;
bitmap → LoadFromFile("handshak.bmp");
Canvas → Draw(0, 0, bitmap);
delete bitmap;
Данный фрагмент кода выводит в форму растровое изображение, находящиеся в файле handshak.bmp. Если включить в программу закомментированную строку, которая содержит указание игнорировать информацию о палитре при выводе изображения, то все цвета на рисунке станут неправильными. Это потому, что палитра не применялась. Использование палитры гарантирует, что все цвета изображения будут корректно отображены на системную палитру.
Класс TCanvasимеет несколько методов для отображения растров. Из них наиболее часто используется метод Draw(), который был рассмотрен ранее. Он просто выводит растровое изображение на холст в указанной позиции.
Метод StretchDraw() используется при необходимости изменения размера изображения. Укажите прямоугольник для размещения изображения и графический файл. Если прямоугольник больше, чем исходный размер изображения, оно будет растянуто. Если прямоугольник меньше, изображение будет сжато.
StretchDraw() не принимает никаких попыток сохранить пропорции изображения. Обеспечение исходного отношения ширины к высоте полностью зависит от вас.
Graphics :: TBitmap *bitmap = new Graphics :: TBitmap;
bitmap → LoadFromFile("handshak.bmp");
TRect rect = Rect(0, 0, 100, 100
Canvas → StretchDraw(rect, bitmap);
delete bitmap;
Ограничивающие области — это участки экрана, которые используются для указания фрагментов холста, на которых будет выполняться рисование. КлассTCanvasимеет свойство ClipRect, но оно доступно только для чтения. Для изменения ограничивающей области необходимо использовать API Windows. Давайте возьмем предыдущий пример и немного изменим его, чтобы проиллюстрировать работу ограничивающих областей.
Graphics :: TBitmap *bitmap = new Graphics :: TBitmap;
bitmap → LoadFromFile("handshak.bmp");
HRGN hRgn = CreateRectRgn(50, 50, 250, 250);
SelectClipRgn (Imagel → Canvas → Handle, hRgn);
Imagel → Canvas → Draw(0, 0, bitmap);
delete bitmap;
На этот раз при запуске программы видно, что отображается только часть картинки. Функция SelectClipRgn() устанавливает в качестве ограничивающей области прямоугольник с координатами 50, 50, 250, 250. Растровое изображение выводится в том же месте, что и раньше, но теперь видна только его часть. Все, что находится вне ограничивающей области, игнорируется.
Шрифты не являются для нас чем-то новым. Шрифты, используемые классом TCanvas, не отличаются от шрифтов, используемых формами или другими компонентами. Свойство Fontкласса TCanvasаналогично свойству Fontлюбого другого компонента. Чтобы изменить шрифт для холста, достаточно сделать следующее:
Canvas →Font → Name = "Courier New";
Canvas → Font → Size = 14;
Canvas → Font → Style = Canvas → Font → Style << fsBold;
Imagel → Canvas → TextOut(20. 20, "Testing");
Для вывода текста на холст используют два метода TextOut() и TextRet(). TextOut() является основным способом. Методу передаются координаты Х и Y, а также текст, который должен быть отображен.
Canvas → TextOut(20. 20; "1234567");
Указанная строка выводится в позиции 20, 20. Координаты Х и Yуказывают верхний левый угол текста, а не базовую линию. Метод TextOut() используйте при отображении текста, для которого не требуется точное позиционирование.
Метод TextRet() позволяет в дополнение к самому тексту указать ограничивающий прямоугольник. Этот метод следует использовать, если текст должен выводится внутри некоторой области. Текст, который выходит за границу указанной области, будет отсечен.
Следующий фрагмент кода гарантирует отображение не более 100 пикселов текста:
Imagel → Canvas → TextRect( Rect(20, 50, 120, 70),
20, 50,"This is a very long line that might get clipped.");
Как TеxtOut(), так и TextRect() могут отображать только одну строку текста. Никакого заворачивания не выполняется.
Фон текста определяется текущей кистью (белой по умолчанию). Чтобы убрать этот нежелательный эффект, нужно сделать одно из двух: либо изменить цвет кисти холста, либо сделать фон текста прозрачным. Какой цвет использовать для этого?
В данном случае цвет фона может совпадать с цветом формы, поэтому сделаем следующее:
Imagel → Canvas → Brush → Color = Color;
Это годится для большинства ситуаций, но иногда нужен больший контроль. Было бы проще сделать фон текста прозрачным.
TBrushStyle oldStyle:
oldStyle = Canvas → Brush → Style;
Canvas → Brush → Style = bsClear;
Canvas → TextOut(20. 20, "This is a test.");
Canvas → Brush → Style = oldStyle;
Сначала сохраняем текущий стиль кисти. После этого устанавливаем прозрачную кисть (bsClear). Закончив вывод текста, возвращаем кисти тот стиль, который она имела раньше.
Использование прозрачного фона имеет и другое преимущество. Допустим, нужно отобразить некоторый текст поверх растрового фона.
Контрольные вопросы и задание к лабораторной работе №11
1. Какое свойство TCanvasопределяет цвет закрашивания холста?
2. Какое свойство TCanvasопределяет цвет и вид линий, нарисованных на холсте?
3. Что делает ограничивающая область?
4. Могут ли ограничивающие области иметь произвольную форму, или они обязательно должны быть прямоугольными?
5. Как сохранить скрытое изображение в файле?
6. Создайте приложение, которое помещает на форму растровое изображение. На него выведите несколько строк текста, изменяя варианты шрифтов, фона,цвета, и нарисуйте различные геометрические фигуры, изменяя их цвет и заливку.
7. Для ранее сформулированного задания измените программу так, чтобы она сохраняла изображение из памяти на диске.
ПРИЛОЖЕНИЯ
Приложение 1
Таблица 9
Свойства форм
Приложение 2
Таблица 10
Методы форм
Приложение 2
Таблица 11
События форм
События
Описание
к 11 лабе конец таблицы