Базовая точка (х0 у0) определяет положение объекта
Рисунок 3.16. Базовая точка (х0, у0) определяет положение объекта
Перед тем как нарисовать кораблик на новом месте, функция обработки события от таймера стирает кораблик, нарисованный в процессе обработки предыдущего события onTimer. Изображение кораблика стирается путем вывода прямоугольника, перекрывающего его.
Функции обработки события OnTimer, функция Ship и функция FormCreate, обеспечивающая настройку таймера, приведены в листинге 3.6
Битовые образы
Битовые образы
Для формирования сложных изображений используют битовые образы. Битовый образ — это, как правило, небольшая картинка, которая находится в памяти компьютера.
Сформировать битовый образ можно путем загрузки из bmp-файла или из ресурса, а также путем копирования фрагмента из другого битового образа, в том числе и с поверхности формы.
Картинку битового образа (иногда говорят просто "битовый образ") можно подготовить при помощи графического редактора или, если предполагается, что битовый образ будет загружен из ресурса программы, — при помощи редактора ресурсов (например, Borland Resource Workshop). В последнем случае надо создать файл ресурсов и поместить в него битовый образ. Файл ресурсов можно создать и при помощи утилиты Image Editor.
В программе битовый образ — это объект типа TBitmap. Некоторые свойства объекта TBitmap приведены в табл. 3.6.
Загрузку картинки из файла обеспечивает метод LoadFromFile, которому в качестве параметра передается имя bmp-файла. Например, следующий фрагмент кода обеспечивает создание и загрузку битового образа из файла.
Graphics: :TBitmap *Plane = new Graphics: :TBititiap() ; Plane->LoadFromFile("plane.bmp");
В результате выполнения приведенного выше фрагмента, битовый образ Plane представляет собой изображение самолета (предполагается, что в файле plane.bmp находится изображение самолета).
Чтобы создать файл ресурсов выберите
Рисунок 3.18. Чтобы создать файл ресурсов, выберите команду File | New | Resource File
Чтобы выбрать иллюстрацию щелкните
Рисунок 3.10. Чтобы выбрать иллюстрацию, щелкните в строке Picture на кнопке стремя точками, затем в окне Picture Editor — на кнопке Load
Диалоговое окно программы Просмотр иллюстраций
Рисунок 3.11. Диалоговое окно программы Просмотр иллюстраций
Следующая программа (вид ее окна приведен на Рисунок 3.11, а текст — в листинге 3.2) использует компонент image для отображения JPG-иллюстраций.
Кнопка Каталог, в результате щелчка на которой появляется стандартное диалоговое окно Выбор папки, позволяет пользователю выбрать каталог, в котором находятся иллюстрации. Кнопка Дальше обеспечивает отображение следующей иллюстрации.
Дуга
Дуга
Метод Arc рисует дугу — часть эллипса (окружности). Инструкция вызова метода в общем виде выглядит так:
Canvas->Arc(xl,yl,х2,у 2,х3,у3, х4,у4)
Параметры x1, y1, х2, у2 определяют эллипс (окружность), частью которого является дуга. Параметры х3 и у3 задают начальную, а х4 и у4 — конечную точку дуги. Начальная (конечная) точка дуги — это точка пересечения границы эллипса и прямой, проведенной из центра эллипса в точку с координатами х3 и у3(х4, у4). Метод Arc вычерчивает дугу против часовой стрелки от начальной точки к конечной (Рисунок 3.4).
Цвет, толщина и стиль линии, которой вычерчивается дуга, определяются значениями свойства Реn поверхности (canvas), на которую выполняется вывод.
Файл ресурсов images res содержит два битовых образа
Рисунок 3.22. Файл ресурсов images.res содержит два битовых образа
Если нужная картинка уже существует в виде отдельного файла, то ее можно через буфер обмена (Clipboard) поместить в битовый образ файла ресурсов. Делается это следующим образом.
1. Сначала надо запустить графический редактор, например Microsoft Paint, загрузить в него файл картинки и выделить всю картинку или ее часть. В процессе выделения следует обратить внимание на информацию о размере (в пикселах) выделенной области (Paint выводит размер выделяемой области в строке состояния). Затем, выбрав команду Копировать меню Правка, необходимо поместить копию выделенного фрагмента в буфер.
2. Далее нужно переключиться в Image Editor, выбрать ресурс, в который надо поместить находящуюся в буфере картинку, и установить значения характеристик ресурса в соответствии с характеристиками картинки, находящейся в буфере. Значения характеристик ресурса вводятся в поля диалогового окна Bitmap Properties, которое открывается выбором команды Image Properties меню Bitmap. После установки характеристик ресурса можно вставить картинку в ресурс, выбрав команду Past меню Edit.
После добавления всех нужных ресурсов файл ресурса следует сохранить в том каталоге, где находится программа, для которой этот файл создается. Сохраняется файл ресурса обычным образом, т. е. выбором команды Save меню File. Image Editor присваивает файлу ресурсов расширение res.
Файл ресурсов создан Теперь в
Рисунок 3.19. Файл ресурсов создан. Теперь в него надо поместить необходимые ресурсы
Для того чтобы в файл ресурсов добавить новый ресурс, надо в меню Resource выбрать команду New | Bitmap (Новый битовый образ). В результате выполнения этой команды открывается диалоговое окно Bitmap Properties (Характеристики битового образа), в котором нужно установить размер (в пикселах) битового образа и выбрать палитру (Рисунок 3.20). В результате нажатия кнопки ОК в списке Contents появится новый элемент Bitmap1, соответствующий новому ресурсу, добавленному в файл ресурсов (Рисунок 3.21).
Фоновый рисунок и битовый образплитка
Рисунок 3.13. Фоновый рисунок и битовый образ-плитка, из которого он составлен
Следующая программа показывает, как можно получить фоновый рисунок путем многократного вывода битового образа на поверхность формы. Формирование фонового рисунка, многократный вывод битового образа на поверхность формы выполняет функция Background. Ее объявление (прототип), а также объявление битового образа (объекта типа TBitmap) надо поместить в секцию private объявления класса формы (листинг 3.4), которая находится в заголовочном файле. Создание битового образа и загрузку картинки из файла выполняет функция обработки события onCreate. Функция обработки события OnPaint путем вызова функции Background обеспечивает вывод фонового рисунка на поверхность формы (листинг 3.5).
Форма программы "Полет над городом"
Рисунок 3.17. Форма программы "Полет над городом"
Графические примитивы
Графические примитивы
Любая картинка, чертеж или схема могут рассматриваться как совокупность графических примитивов: точек, линий, окружностей, дуг и др. Таким образом, для того чтобы на экране появилась нужная картинка, программа должна обеспечить вычерчивание (вывод) графических элементов — примитивов, составляющих эту картинку.
Вычерчивание графических примитивов на поверхности (формы или компонента image — области вывода иллюстрации) осуществляется применением соответствующих методов к свойству canvas этой поверхности.
График построенный по точкам
Рисунок 3.8. График, построенный по точкам
Вызов функции Grafik выполняют функции Обработки событий OnPaint и OnResize. Функция TForm1:: Formpaint обеспечивает вычерчивание графика после появления формы на экране в результате запуска программы, а также после появления формы во время работы программы — например, в результате удаления или перемещения других окон, полностью или частично перекрывающих окно программы. Функция TForm1: :FormResize обеспечивает вычерчивание графика после изменения размера формы.
Приведенная программа универсальна. Заменив инструкции в теле функции f (х), можно получить график другой функции. Причем независимо от вида функции ее график будет занимать всю область, предназначенную для вывода. Следует обратить внимание на то, что приведенная программа работает корректно, если функция, график которой надо построить, принимает как положительные, так и отрицательные значения. Если функция во всем диапазоне только положительная или только отрицательная, то в программу необходимо внести изменения. Какие — пусть это будет упражнением для читателя.
Холст
Холст
Программа может вывести графику на поверхность формы (или компонента image), которой соответствует свойство canvas (Canvas — холст для рисования). Для того чтобы на поверхности формы или компонента image появилась линия, окружность, прямоугольник или другой графический элемент (примитив), необходимо к свойству Canvas применить соответствующий метод (табл. 3.1).
Например, оператор Forml->Canvas->Rectangle(10,10,50, 50); рисует на поверхности формы прямоугольник.
Иллюстрации
Иллюстрации
Наиболее просто вывести иллюстрацию, которая находится в файле с расширением bmp, jpg или ico, можно при помощи компонента image, значок которого находится на вкладке Additional палитры компонентов (Рисунок 3.9). Основные свойства компонента приведены в табл. 3.5.
Использование битовых образов
Использование битовых образов
В последнем примере изображение формировалось из графических примитивов. Теперь рассмотрим, как можно реализовать перемещение заранее подготовленного при помощи графического редактора изображения.
Как и в предшествующей программе, эффект перемещения объекта (картинки) достигается за счет периодической перерисовки картинки с некоторым смещением относительно ее прежнего положения. Перед выводом картинки в новой точке предыдущее изображение должно быть удалено, а фоновый рисунок, который был перекрыт — восстановлен. Удалить (стереть) картинку и одновременно восстановить фон можно путем перерисовки всей фоновой картинки или только той ее части, которая была перекрыта объектом. В рассматриваемой программе используется второй подход. Изображение объекта выводится применением метода Draw к свойству canvas формы, а стирается путем копирования (метод CopyRect) нужной части фона из буфера в битовый образ, соответствующий поверхности формы.
Форма программы приведена на Рисунок 3.17, а текст — в листинге 3.6. Компонент Timer используется для организации цикла удаления и вывода изображения самолета.
Кадры баннера
Рисунок 3.23. Кадры баннера
Карандаш и кисть
Карандаш и кисть
Методы вычерчивания графических примитивов обеспечивают только вычерчивание. Вид графического элемента определяют свойства Реn(карандаш) и Brush (кисть) той поверхности (Canvas), на которой рисует метод.
Карандаш и кисть, являясь свойствами объекта Canvas, в свою очередь представляют собой объекты Реn и Brush. Свойства объекта Реп (табл. 3.2) задают цвет, толщину и тип линии или границы геометрической фигуры. Свойства объекта Brush (табл. 3.3) задают цвет и способ закраски области внутри прямоугольника, круга, сектора или замкнутого контура.
Координаты области вывода текста
Рисунок 3.6. Координаты области вывода текста
Шрифт, который используется для вывода текста, определяется значением свойства Font соответствующего объекта canvas. Свойство Font представляет собой объект типа TFont. В табл. 3.4 перечислены свойства объекта TFont, определяющие характеристики шрифта, используемого методом TextoutA для вывода текста.
Координаты точек поверхности формы (холста)
Рисунок 3.1. Координаты точек поверхности формы (холста)
Линия
Линия
Вычерчивание прямой линии выполняет метод LineTo. Метод рисует линию из той точки, в которой в данный момент находится карандаш (эта точка называется текущей позицией карандаша или просто "текущей"), в точку, координаты которой указаны в инструкции вызова метода. Например, оператор
Canvas->LineTo(100,200)
рисует линию в точку с координатами (100, 200), после чего текущей становится точка с координатами (100, 200).
Начальную точку линии можно задать, переместив карандаш в нужную точку графической поверхности. Сделать это можно при помощи метода MoveTo, указав в качестве параметров координаты точки начала линии. Например, операторы
Canvas->MoveTo(10,10); // установить карандаш в точку (10,10) Canvas->LineTo(50,10); // линия из точки (10,10)в точку (50,10)
рисуют горизонтальную линию из точки (10, 10) в точку (50, 10).
Используя свойство текущей точки, можно нарисовать ломаную линию. Например, операторы
Canvas->MoveTo(10,10) ; Canvas->LineTo(50,10) ; Canvas->LineTo(10,20) ; Canvas->LineTo(50,20) ;
рисуют линию, похожую на букву Z.
обработка события OnResize void __fastcall
Листинг 3.1.
График функции // обработка события OnPaint void__fastoall TForml::FormPaint(TObject *Sender) { Grafik();
} // обработка события OnResize void __fastcall TForml::FormResize(TObject *Sender) { TRect ret = Rect(0,0,Ciientwidth,CiientHeight);
Canvas->
FillRect(ret);
// стереть Grafik();
} #include "math.h" // для доступа к sin и exp // функция, график которой надо построить float f(float х) { return 2*sin(x)*exp(x/5);
} void TForml::Grafik() { float xl, x2; // границы изменения аргумента функции float yl, y2; // границы изменения значения функции float x; // аргумент функции float у; // значение функции в точке х float dx; // приращение аргумента int 1, Ь; // левый нижний угол области вывода графика int w, h; // ширина и высота области вывода графика float mx, my; // масштаб по осям X и Y int xO, уО; // начало координат // область вывода графика 1-10; // X - координата левого верхнего угла b = Forml->
ClientHeight-20; // Y — координата левого нижнего угла h = Forml->
ClientHeight-40; // высота w = Forml->
Wldth - 20; // ширина xl = 0; // нижняя граница диапазона аргумента х2 = 25; // верхняя граница диапазона аргумента dx = 0.01; //шаг аргумента // найдем максимальное и минимальное значение // функции на отрезке [xl,x2] x = xl; yl = f(х);
// минимум у2 = f(x);
// максимум do { у = f(х);
if ( у < yl) yl = у; if ( у >
у2) у2 = у; х += dx; } while (x <= х2);
// вычислим масштаб my = (float)h/abs(y2-yl);
// масштаб по оси Y mx = w/abs(x2-xl);
// масштаб по оси X // оси хО = 1+abs(xl*mx);
уО = b-abs(yl*my);
Canvas->
MoveTo(xO,b);
Canvas->
LineTo(xO,b-h);
Canvas->
MoveTo(l,yO);
Canvas->
LineTo(1+w,yO);
Canvas->
TextOutA(xO+5,b-h,FloatToStrF(y2,ffGeneral,6,3));
Canvas->
TextOutA(xO+5,b,FloatToStrF(yl,ffGeneral, 6,3));
// построение графика x = xl; do { У = f (x);
Canvas->
Pixels[xO+x*mx][yO-y*my] = clRed; x += dx; } while (x <= x2);
}
Основную работу выполняет функция Grafik (ее объявление надо поместить в раздел private объявления формы в заголовочном файле программы). Функция Grafik сначала вычисляет максимальное (у2) и минимальное (yi) значение функции на отрезке [x1, x2]. Затем, используя информацию о ширине и высоте области вывода графика, она вычисляет коэффициенты масштабирования по осям X и Y. После этого вычисляет координату Y горизонтальной оси, координату X вертикальной оси и вычерчивает координатные оси. Затем выполняется непосредственное построение графика (Рисунок 3.8).
к функции SelectDirectory AnsiString aPath;
Листинг 3.2.
Просмотр иллюстраций
#include <jpeg.hpp>
// обеспечивает работу с JPEG-иллюстрациями linclude <FileCtrl.hpp>
// для доступа к функции SelectDirectory AnsiString aPath; // каталог, в котором находится иллюстрация TSearchRec aSearchRec; // результат поиска файла void __fastcall TForml::FormCreate(TObject *Sender) { aPath = ""; // текущий каталог — каталог, из которого // запущена программа Imagel->
AutoSize = false; Imagel->
Proportional = true; Button2->
Enabled = false; FirstPicture();
// показать картинку, которая // есть в каталоге программы } // щелчок на кнопке Каталог void __fastcall TForml::ButtonlClick(TObject *Sender) { if (SelectDirectory( "Выберите каталог, в котором находятся иллюстрации", "",aPath) != 0) { // пользователь выбрал каталог и щелкнул на кнопке ОК aPath = aPath + "\\"; FirstPicture(}; // вывести иллюстрацию } } // найти и вывести первую картинку void TForml::FirstPicture() { Imagel->
Visible = false; // скрыть компонент Imagel Button2->
Enabled = false; // кнопка Дальше недоступна Labell->
Caption = ""; if ( FindFirst(aPath+ "*.jpg", faAnyFile, aSearchRec) == 0) { Imagel->
Picture->
LoadFromFile(aPath+aSearchRec.Name);
Imagel->
Visible = true; Labell->
Caption = aSearchRec.Name; if ( FindNext(aSearchRec) == 0) // найти след, иллюстрацию { // иллюстрация есть Button2->
Enabled = true; // теперь кнопка Дальше доступна } } } // щелчок на кнопке Дальше void __fastcall TForml::Button2Click(TObject *Sender) { Imagel->
Picture->
LoadFromFile(aPath+aSearchRec.Name);
Labell->
Caption = aSearchRec.Name; if ( FindNext(aSearchRec) != 0) // найти след, иллюстрацию { // иллюстраций больше нет Button2->
Enabled = false; // теперь кнопка Дальше недоступна } }
Загрузку и вывод первой и остальных иллюстраций выполняют соответственно функции FirstPicture и NextPicture. функция FirstPicture вызывает функцию FindFirst для того, чтобы получить имя файла первой иллюстрации. В качестве параметров функции FindFirst передаются:
имя каталога, в котором должны находиться иллюстрации; структура aSearchRec, поле Name которой, в случае успеха, будет содержать имя файла, удовлетворяющего критерию поиска; маска файла иллюстрации.
Если в указанном при вызове функции FindFirst каталоге есть хотя бы один файл с указанным расширением, то значение функции будет равно нулю. В этом случае метод LoadFromFiie загружает файл иллюстрации. После загрузки первой иллюстрации функция FirstPicture вызывает функцию FindNext для поиска следующего файла иллюстрации. Если файл будет найден, то кнопка Дальше будет сделана доступной.
Функция обработки события Onclick на кнопке Дальше загружает следующую иллюстрацию, имя файла которой было найдено функцией FindNext в процессе обработки предыдущего щелчка на кнопке Дальше, и снова вызывает функцию FindNext для поиска следующей иллюстрации. Если файл иллюстрации не будет найден, то кнопка Дальше станет недоступной. Необходимо обратить внимание на следующее. Для того чтобы иллюстрации отображались без искажения, свойству Autosize компонента image1 надо присвоить значение false, а свойству Proportional — значение true. Сделать это можно во время создания формы в среде разработки (установить значения свойств в окне Object Inspector) или возложить задачу настройки компонента на саму программу. В последнем случае в функцию обработки события OnCreate для формы (TForm1: : FormCreate) надо добавить следующие инструкции:
Image1->
AutoSize = false; Image1->
Proportional = true;
Кроме того, во время создания формы свойству Enabled кнопки Дальше (Button2) надо присвоить значение false. Это обеспечит корректную работу программы в том случае, если в каталоге, из которого запускается программа, нет иллюстраций. Настройку кнопки Buttona можно возложить на функцию TForml: : FormCreate. Для этого в функцию надо добавить оператор
Button2->
Enabled = false
и вывод битовых образов на
Листинг 3.3.
Загрузка и вывод битовых образов на поверхность формы
void __fastcall TForml::FormPaint(TObject *Sender) { // битовые образы: небо и самолет Graphics::TBitmap *sky = new Graphics::TBitmap();
Graphics::TBitmap *plane = new Graphics::TBitmap();
sky->
LoadFromFile("sky.bmp");
plane->
LoadFromFile("plane.bmp");
Canvas->
Draw(0,0,sky);
// фон - небо Canvas->
Draw(20,20,plane);
// левый самолет plane-XTransparent = true; /* теперь элементы рисунка, цвет которых совпадает с цветом левой нижней точки битового образа, не отображаются */ Canvas->
Draw(120,20,plane);
// правый самолет // уничтожить объекты sky->
Graphics::-TBitmap();
plane->
Graphics::-TBitmap();
}
Небольшие по размеру битовые образы часто используют при формировании фоновых рисунков по принципу кафельной плитки (Рисунок 3.13).
элемент фонового рисунка void __fastcall
Листинг 3.4.
Объявление битового образа и функции Background
class TForml : public TForm { _published: void__fasteal1 FormCreate(TObject *Sender);
void__fastcall FormPaint(TObject *Sender);
void__fastcall FormResize(TObject *Sender);
private: Graphics::TBitmap *back; // элемент фонового рисунка void __fastcall Background();
// формирует фоновый рисунок на // поверхности формы public: _fastcall TForml(TComponent* Owner);
};
обработка события OnCreate void __fastcall
Листинг 3.5.
Функции, обеспечивающие формирование и вывод фонового рисунка // обработка события OnCreate void __fastcall TForml::FormCreate(TObject *Sender) { back = new Graphics::TBitmap();
// создать объект — битовый образ // загрузить картинку try // в процессе загрузки картинки возможны ошибки { Forml->
back->
LoadFromFile("Legal.bmp");
} catch (EFOpenError &e) { return; } } // формирует фоновый рисунок void __fastcall TForml::Background() { int x=0,y=0; // координаты левого верхнего угла битового образа if ( back->
Empty) // битовый образ не был загружен return; do { do { Canvas->
Draw(x,y,back);
x += back->
Width; } while (x < ClientWidth);
x = 0; у4= back->
Height; } while (y < ClientHeight);
} // обработка события OnPaint void __fastcall TForml::FormPaint(TObject *Sender) { Background();
// обновить фоновый рисунок }
рисует на поверхности формы кораблик
Листинг 3.6.
Простая мультипликация
int х = -68, у = 50; // начальное положение базовой точки // рисует на поверхности формы кораблик void __fastcall TForml::Ship(int x, int y) { int dx=4,dy=4; // шаг сетки // корпус и надстройку будем рисовать // при помощи метода Polygon TPoint pi[7]; // координаты точек корпуса TPoint p2[8]; // координаты точек надстройки TColor pc,bc; // текущий цвет карандаша и кисти // сохраним текущий цвет карандаша и кисти рс = Canvas->
Pen->
Color; be = Canvas->
Brush->
Color; // установим нужный цвет карандаша и кисти Canvas->
Pen->
Color = clBlack; Canvas->
Brush->
Color = clWhite; // рисуем ... 11 корпус pl[0].x = x; pl[0].y = y; pl[l].x=x; pl[l].y = y-2*dy; pl[2].x = x+10*dx; pi[2].у = y-2*dy; pl[3].x = x+ll*dx; pl[3].y = y-3*dy; pl[4]-x = x+17*dx; pi[4].у =y-3*dy; pl[5].x = x+14*dx; pi[5].у =y; pl[6].x = x; pl[6].y =y; Canvas->
Polygon(pl,6);
// надстройка p2[0].x = x+3*dx; p2[0].y = y-2*dy; p2[l].x = x+4*dx; p2[l].y = y-3*dy; р2[2].х = x+4*dx; p2[2].y = y-4*dy; р2[3].х = x+13*dx; p2[3].y = y-4*dy; р2[4].х = x+13*dx; p2[4].y = y-3*dy; р2[5].х = x+ll*dx; p2[5].y = y-3*dy; р2[6].х = x+10*dx; p2[6].y = y-2*dy; р2[7].х = x+3*dx; p2[7].y = y-2*dy; Canvas->
Polygon(p2,7);
Canvas->
MoveTo(x+5*dx,y-3*dy);
Canvas->
LineTo(x+9*dx,y-3*dy);
// капитанский мостик Canvas->
Rectangle(x+8*dx,y-4*dy,x+ll*dx,y-5*dy);
// труба Canvas->
Rectangle(x+7*dx,y-4*dy,x+8*dx,y-7*dy);
// иллюминаторы Canvas->
Ellipse(x+ll*dx,y-2*dy,x+12*dx,y-l*dy);
Canvas->
Ellipse(x+13*dx,y-2*dy,x+14*dx,y-l*dy);
// мачта Canvas->
MoveTo(x+10*dx,y-5*dy);
Canvas->
LineTo(x+10*dx,y-10*dy);
// оснастка Canvas->
Pen->
Color = clWhite; Canvas->
MoveTo(x+17*dx,y-3*dy);
Canvas->
LineTo(x+10*dx, y-10*dy);
Canvas->
LineTo(x,y-2*dy);
// восстановим цвет карандаша и кисти Canvas->
Pen->
Color = рс; Canvas->
Brush->
Color = be; } // обработка события OnTimer void__fastcall TForml::TimerlTimer(TObject *Sender) { // стереть кораблик — закрасить цветом, совпадающим // с цветом фона (формы) Canvas->
Brush->
Color = Forml->
Color; Canvas->
FillRect(Rect(x-1,y+l,x+68,y-40));
// вычислить координаты базовой точки х+=3; if (x >
ClientWidth) { // кораблик "уплыл" за правую границу формы х= -70; // чтобы кораблик "выплывал" из-за левой границы формы y=random(Forml->
ClientHeight);
} // нарисовать кораблик на новом месте Ship(х, у) ; ) // обработка события OnCreate для формы void__fastcall TForml::FormCreate(TObject *Sender) { /* Таймер можно настроить во время разработки программы (в процессе создания формы) или во время работы программы. */ // настройка и запуск таймера Timerl->
Interval = 100; // период события OnTimer —0.1 сек. Timerl->
Enabled = true; // пуск таймера }
с размером фонового рисунка GlientWidth
Листинг 3.7.
Полет над городом
void _fastcall TForml::FormCreate(TObject *Sender) { // загрузить фоновый рисунок из bmp-файла back = new Graphics::TBitmap();
back->
LoadFromFile("factory.bmp");
// установить размер клиентской (рабочей) области формы // в соответствии с размером фонового рисунка GlientWidth = back->
Width; ClientHeight = back->
Height; // загрузить картинку sprite = new Graphics::TBitmap();
sprite->
LoadFromFile("aplane.bmp");
sprite->
Transparent = true; // исходное положение самолета x=-20; // чтобы самолет "вылетал" из-за левой границы окна У=20; } void _fastcall TForml::FormPaint(TObject *Sender) { Canvas->
Draw(0,0,back);
//фон Canvas->
Draw(x,у,sprite);
// рисунок } void__fastoall TForml::TimerlTimer(TObject *Sender) { TRect badRect; // положение и размер области фона, // которую надо восстановить badRect = Rect(x,y,x+sprite->
Width,y+sprite->
Height);
// стереть самолет (восстановить "испорченный" фон) Canvas->
CopyRect(badRect,back->
Canvas,badRect);
// вычислим новые координаты спрайта (картинки) х +=2; if (х >
ClientWidth) { // самолет улетел за правую границу формы // изменим высоту и скорость полета х = -20; у = random(ClientHeight —30);
// высота полета" // скорость полета определяется периодом возникновения // события On Timer, который, в свою очередь, зависит // от значения свойства Interval Timerl->
Interval = random(20) + 10; // скорость "полета" меняется // от 10 до 29 } Canvas->
Draw(х,у,sprite);
}
Для хранения битовых образов (картинок) фона и самолета используются два объекта типа TBitmap, которые создает функция TFormi:: Formcreate (объявления этих объектов надо поместить в заголовочный файл проекта). Эта же функция загружает из файлов картинки фона (factory.bmp) и самолета (aplane.bmp).
Восстановление фона выполняется при помощи метода copyRect, который позволяет выполнить копирование прямоугольного фрагмента одного битового образа в другой. Объект, к которому применяется метод copyRect, является приемником копии битового образа. В качестве параметров методу передаются: координаты и размер области, куда должно быть выполнено копирование; поверхность, с которой должно быть выполнено копирование; положение и размер копируемой области. Информация о положении и размере восстанавливаемой (копируемой на поверхность формы) области фона находится в структуре badRect типа TRect.
Следует обратить внимание на то, что начальное значение переменной х, которая определяет положение левой верхней точки битового образа (движущейся картинки) — отрицательное число, равное ширине битового образа картинки. Поэтому в начале работы программы самолет не виден и картинка отрисовывается за границей видимой области. С каждым событием OnTimer значение координаты х увеличивается и на экране появляется та часть битового образа, координаты которой больше нуля. Таким образом, у наблюдателя создается впечатление, что самолет вылетает из-за левой границы окна.
загрузить фоновый рисунок из ресурса
Листинг 3.8
. Загрузка битовых образов из ресурса // подключить файл ресурсов, в котором находятся // необходимые программе битовые образы #pragma resource "images.res" void__fastcall TForml::FormCreate(TObject *Sender) { // загрузить фоновый рисунок из ресурса back = new Graphics::TBitmap();
back->
LoadFromResourceName((int)HInstance,"FACTORY");
// установить размер клиентской (рабочей) области формы //в соответствии с размером фонового рисунка ClientWidth = back->
Width; ClientHeight = back->
Height; // загрузить изображение объекта из ресурса sprite = new Graphics::TBitmap();
sprite->
LoadFromResourceName((int)HInstance,"APLANE");
sprite->
Transparent = true; // исходное положение самолета x=-20; // чтобы самолет "вылетал" из-за левой границы окна у=20; }
Преимущества загрузки картинок из ресурса программы очевидны: при распространении программы не надо заботиться о том, чтобы во время работы программы были доступны файлы иллюстраций, т. к. все необходимые программе картинки находятся в исполняемом файле.
Теперь рассмотрим, как можно реализовать в диалоговом окне программы вывод баннера, представляющего собой последовательность сменяющих друг друга картинок (кадров). Кадры баннера обычно находятся в одном файле или в одном ресурсе. В начале работы программы они загружаются в буфер (объект типа TBitmap). Вывод кадров баннера обычно выполняет функция обработки сигнала от таймера (события onTimer), которая выделяет очередной кадр и выводит его на поверхность формы.
Вывести кадр баннера (фрагмент битового образа) на поверхность формы можно при помощи метода copyRect, который копирует прямоугольную область одной графической поверхности на другую.
Инструкция применения метода CopyRect в общем виде выглядит так:
Canvasl->
CopyRect(Область1, Canvas2, Область2)
где:
Canvas1 — поверхность, на которую выполняется копирование; Canvas2 — поверхность, с которой выполняется копирование; Область1 — структура типа TRect, которая задает положение и размер области, куда выполняется копирование (приемник);
Область2 — структура типа TRect, которая задает положение и размер области, откуда выполняется копирование (источник).
Определить прямоугольную область, заполнить поля структуры TRect можно при помощи функции Rect или Bounds. Функции Rect надо передать в качестве параметров координаты левого верхнего и правого нижнего углов области, функции Bounds — координаты левого верхнего угла и размер области. Например, если надо определить прямоугольную область, то это можно сделать так: ret = Rect(x1,y1,x2,y2) или так: ret = Bounds(x1,y1,w,h)
где x1, y1 — координаты левого верхнего угла области; х2, у2 — координаты правого нижнего угла области; w и h — ширина и высота области.
Следующая программа (ее текст приведен в листинге 3.9) выводит в диалоговое окно баннер — рекламное сообщение. На Рисунок 3.23 приведены кадры этого баннера (содержимое файла baner.bmp), а на Рисунок 3.24 — диалоговое окно. Форма программы содержит один-единственный компонент — таймер.
область воспроизведения баннера int w,
Листинг 3.9.
Баннер (baner.h, baner_.cpp)
// baner.h class TForml : public TForm { published: TTimer *Timerl; void__fastcall FormCreate(TObject *Sender);
void __fastcall TimerITimer(TObject *Sender);
private: Graphics::TBitmap *baner; // баннер TRect kadr; // кадр баннера TRect scr; // область воспроизведения баннера int w, h; // размер кадра int с; // номер воспроизводимого кадра public: _fastcall TForml(TComponent* Owner);
}; // baner_.cpp #define FBANER "borland.bmp" // баннер #define NKADR 4 // количество кадров в баннере void__fastcall TForml::FormCreate(TObject *Sender) { baner = new Graphics::TBitmap();
baner->
LoadFromFile(FBANER);
// загрузить баннер h = baner->
Height; w = baner->
Width / NKADR; scr = Rect(10,10,10+w,10+h);
// положение и размер области // воспроизведения баннера kadr = Rect(0,0,w,h);
// положение и размер первого кадра //в баннере } // обработка события OnTimer void__fastcall TForml:rTimerlTimer(TObject *Sender) { // вывести кадр баннера Canvas->
CopyRect(scr,baner->
Canvas,kadr);
// подготовиться к воспроизведению следующего кадра if (с < NKADR) { // воспроизводимый в данный момент // кадр — не последний с++; kadr.Left += w; kadr.Right += w; } else { с = 0; kadr.Left = 0; kadr.Right = w; } }
Программа состоит из двух функций. Функция TForm1:: Form-Create создает объект TBitmap и зафужает в него баннер — BMP-файл, в котором находятся кадры баннера. Затем, используя информацию о размере загруженного битового образа, функция устанавливает значения характеристик кадра: высоту и ширину.
Основную работу в программе выполняет функция обработки события onTimer, которая выделяет из битового образа Baner очередной кадр и выводит его на поверхность формы. Выделение кадра и его отрисовку путем копирования фрагмента картинки с одной поверхности на другую выполняет метод copyRect (Рисунок 3.25), которому в качестве параметров передаются координаты области, куда нужно копировать, поверхность и положение области, откуда нужно копировать. Положение фрагмента в фильме, т. е. координата х левого верхнего угла, определяется умножением ширины кадра на номер текущего кадра.
Ломаная линия
Ломаная линия
Метод Polyline вычерчивает ломаную линию. В качестве параметров методу передается массив типа TPoint, содержащий координаты узловых точек линии, и количество звеньев линии. Метод Polyline вычерчивает ломаную линию, последовательно соединяя точки, координаты которых находятся в массиве: первую со второй, вторую с третьей, третью с четвертой и т. д.
Например, приведенный ниже фрагмент кода рисует ломаную линию, состоящую из трех звеньев.
TPoint p[4]; // координаты начала, конца и точек перегиба
# задать координаты точек ломаной р[0].х = 100; р[0].у = 100; // начало р[1].х = 100; р[1].у = 150; // точка перегиба р[2].х = 150; р[2].у = 150; // точка перегиба р[3].х = 150; р[3].у = 100; // конец Canvas->Polyline(p,3}; // ломаная из трех звеньев
Метод Polyline можно использовать для вычерчивания замкнутых контуров. Для этого надо, чтобы первый и последний элементы массива содержали координаты одной и той же точки.
Метод базовой точки
Метод базовой точки
Следующая простая программа показывает, как можно заставить двигаться изображение, сформированное из графических примитивов. Окно и форма программы приведены на Рисунок 3.14.
Метод CopyRect копирует в область
Рисунок 3.25. Метод CopyRect копирует в область Rect1 поверхности Canvas1 область Rect2 с поверхности Canvas2
Метод RoundRec вычерчивает прямоугольник
Рисунок 3.2. Метод RoundRec вычерчивает прямоугольник со скругленными углами
Многоугольник
Многоугольник
Метод Polygon вычерчивает многоугольник. Инструкция вызова метода в общем виде выглядит так:
Canvas->Polygon(p,n)
где р — массив записей типа TPoint, который содержит координаты вершин многоугольника; n — количество вершин.
Метод Polygon чертит многоугольник, соединяя прямыми линиями точки, координаты которых находятся в массиве: первую со второй, вторую с третьей, третью с четвертой и т. д. Вид границы многоугольника определяют значения свойства Реп, а вид заливки области, ограниченной линией границы, — значения свойства Brush той поверхности, на которой метод рисует.
Ниже приведен фрагмент кода, который, используя метод Polygon, рисует ромб.
TPoint p[4]; // четыре вершины
// координаты вершин р[0].х = 50; р[0].у = 100; р[1].х = 150; р[1].у = 75; р[2].х = 250; р[2].у = 100; р[3].х = 150; р[3].у = 125;
Canvas->Brush->Color = clRed; Canvas->Polygon(p,3);
Мультипликация
Мультипликация
Под мультипликацией обычно понимается движущийся и меняющийся рисунок. В простейшем случае рисунок может только двигаться или только меняться.
Обеспечить перемещение рисунка довольно просто: надо сначала вывести рисунок на экран, затем через некоторое время стереть его и снова вывести этот же рисунок, но уже на некотором расстоянии от его первоначального положения. Подбором времени между выводом и удалением рисунка, а также расстояния между старым и новым положением рисунка (шага перемещения), можно добиться того, что у наблюдателя будет складываться впечатление, что рисунок равномерно движется по экрану.
Окно файла ресурсов после добавления ресурса Bitmap
Рисунок 3.21. Окно файла ресурсов после добавления ресурса Bitmap
Bitmap 1 — это автоматически созданное имя ресурса, которое можно изменить, выбрав команду Resource | Rename. После этого можно приступить к редактированию (созданию) битового образа. Для этого надо в меню Resource выбрать команду Edit. В результате этих действий будет активизирован режим редактирования битового образа.
Графический редактор Image Editor предоставляет программисту стандартный для подобных редакторов набор инструментов, используя которые можно нарисовать нужную картинку. Если во время работы надо изменить масштаб отображения картинки, то для увеличения масштаба следует выбрать команду View | Zoom In, а для уменьшения — команду View | Zoom Out. Увидеть картинку в реальном масштабе можно, выбрав команду View | Actual Size.
В качестве примера на Рисунок 3.22 приведен вид диалогового окна Image Editor, в котором находится файл ресурсов images.res для программы Flight. Файл содержит два битовых образа FACTORY и APLANE.
Окно и форма программы
Рисунок 3.14. Окно и форма программы
На поверхности формы находится один-единственный компонент Timer, который используется для генерации последовательности событий, функция обработки которых обеспечивает вывод и удаление рисунка. Значок компонента Timer находится на вкладке System (Рисунок 3.15). Следует обратить внимание, что компонент Timer является невизуальным. Это значит, что во время работы программы компонент в диалоговом окне не отображается. Поэтому компонент Timer можно поместить в любую точку формы. Свойства компонента Timer приведены в табл. 3.7.
Окружность и эллипс
Окружность и эллипс
Нарисовать эллипс или окружность (частный случай эллипса) можно при помощи метода Ellipse. Инструкция вызова метода в общем виде выглядит следующим образом:
Canvas->Ellipse(xl,yl,x2,у2)
Параметры x1, y1, x2, y2 определяют координаты прямоугольника, внутри которого вычерчивается эллипс или, если прямоугольник является квадратом, — окружность (Рисунок 3.3).
Подключение файла ресурсов
Подключение файла ресурсов
Для того чтобы ресурсы, находящиеся в файле ресурсов, были доступны программе, в текст программы надо поместить инструкцию (директиву), которая сообщит компилятору, что в исполняемый файл следует добавить содержимое файла ресурсов.
В общем виде эта директива выглядит следующим образом:
где ФайлРесурсов — имя файла ресурсов.
Например, для программы flight_l директива, обеспечивающая включение содержимого файла ресурсов в выполняемый файл, выглядит так: #pragma resource "images.res"
Загрузить битовый образ из ресурса можно при помощи метода LoadFromResourceName, который имеет два параметра: идентификатор программы и имя ресурса. В качестве идентификатора программы используется глобальная переменная Hinstance. Имя ресурса должно быть представлено в виде строковой константы.
Например, в программе flight_l инструкция загрузки фона из ресурса выглядит так: back->LoadFromResourceName((int)Hinstance,"FACTORY");
В качестве примера в листинге 3.8 приведен фрагмент программы flight_l — функция TForm1:: FormCreate, которая обеспечивает загрузку битовых образов из ресурсов.
Присвоив свойству Transparent значение true можно скрыть фон
Рисунок 3.12. Присвоив свойству Transparent значение true, можно скрыть фон
Прямоугольник
Прямоугольник
Метод Rectangle вычерчивает прямоугольник. В инструкции вызова метода надо указать координаты двух точек — углов прямоугольника. Например, оператор
Canvas->Rectangle(10,10,50,50)
рисует квадрат, левый верхний угол которого находится в точке (10, 10), а правый нижний в точке (50, 50).
Цвет, вид и ширину линии контура прямоугольника определяют значения свойства Реn, а цвет и стиль запивки области внутри прямоугольника — значения свойства Brush той поверхности, на которой метод рисует прямоугольник. Например, следующие операторы рисуют флаг Российской Федерации.
Canvas->Brush->Color = clWhite; // цвет кисти — белый Canvas->Rectangle(10,10,90,30); Canvas->Brush->Color = clBlue; // цвет кисти — синий Canvas->Rectangle(10,30,90,50); Canvas->Brush->Color = clRed; // цвет кисти — красный Canvas->Rectangle(10,50,90,70);
Вместо четырех параметров — координат двух диагональных углов прямоугольника — методу Rectangle можно передать один параметр — структуру типа TRect, поля которой определяют положение диагональных углов прямоугольной области. Следующий фрагмент кода демонстрирует использование структуры TRect В качестве параметра метода Rectangle.
TRect ret; // прямоугольная область ret.Top = 10; ret.Left = 10; ret.Bottom = 50; ret.Right = 50; Canvas->Rectangle(ret); // нарисовать прямоугольник
Есть еще два метода, которые вычерчивают прямоугольник. Метод FillRect вычерчивает закрашенный прямоугольник, используя в качестве инструмента только кисть (Brush), а метод FrameRect — только контур и использует только карандаш (Реп). У этих методов только один параметр — структура типа TRect. Поля структуры TRect содержат координаты прямоугольной области. Значения полей структуры TRect можно задать при помощи функции Rect.
Например:
TRect ret; // область, которую надо закрасить ret = Rect(10,10,30,50); // координаты области Canvas->Brush->Color = clRed; // цвет закраски Canvas->FillRect(ret) ;
Метод RoundRec вычерчивает прямоугольник со скругленными углами. Инструкция вызова метода RoundRec в общем виде выглядит так:
Canvas->RoundRec(xl,yl,x2,у2,хЗ,уЗ)
Параметры x1, y1, x2, y2 определяют положение углов прямоугольника, а параметры х3 и у3 — размер эллипса, одна четверть которого используется для вычерчивания скругленного угла (Рисунок 3.2).
Сектор
Сектор
Метод pie вычерчивает сектор эллипса или круга. Инструкция вызова метода в общем виде выглядит следующим образом:
Canvas->Pie(x1,y1,х2,у2,х3,у3,х4,у4)
Параметры x1, y1, x2, y2 определяют эллипс (круг), частью которого является сектор; х3, у3, х4 и у4 — прямые — границы сектора. Начальная точка границ совпадает с центром эллипса. Сектор вырезается против часовой стрелки от прямой, заданной точкой с координатами (х3, у3), к прямой, заданной точкой с координатами (х4, у4) (Рисунок 3.5).
Создание файла ресурсов
Создание файла ресурсов
Файл ресурсов можно создать при помощи утилиты Image Editor, которая поставляется вместе с C++ Builder. Запустить Image Editor можно из C++ Builder, выбрав в меню Tools команду Image Editor, или из Windows, выбрав команду Пуск | Программы | Borland C++Builder | Image Editor.
Для того чтобы создать файл ресурсов, надо в меню File выбрать команду New, а затем в появившемся подменю — команду Resource File (Рисунок 3.18). В результате выполнения команды будет создан файл ресурсов Untitledl.res (Рисунок 3.19), в который надо поместить необходимые ресурсы.
Методы вычерчивания графических примитивов
Таблица 3.1. Методы вычерчивания графических примитивов
Метод |
Действие |
LineTo(x,y) |
Рисует линию из текущей точки в точку с указанными координатами |
Rectangle (x1,y1,x2, y2) |
Рисует прямоугольник, x1, y1 и х2, у2 — координаты левого верхнего и правого нижнего углов прямоугольника. Цвет границы и внутренней области прямоугольника могут быть разными |
FillRect (x1,y1,x2,y2) |
Рисует закрашенный прямоугольник, x1, y1, х2, у2 — определяют координаты диагональных углов |
FrameRect(x1,y1,x2,y2) |
Рисует контур прямоугольника, x1, y1, х2, у2 — определяют координаты диагональных углов |
RounRect (x1,y1,x2,y2,x3,y3) |
Рисует прямоугольник со скругленными углами |
Ellipse (x1,y1,x2,y2) |
Рисует эллипс или окружность (круг), x1, y1, х2, у2 — координаты прямоугольника, внутри которого вычерчивается эллипс или, если прямоугольник является квадратом, окружность |
Polyline (points, n) |
Рисует ломаную линию, points— массив типа TPoint. Каждый элемент массива представляет собой запись, поля х и у которой содержат координаты точки перегиба ломаной; л — количество звеньев ломаной. Метод Polyline вычерчивает ломаную линию, последовательно соединяя прямыми отрезками точки, координаты которых находятся в массиве: первую со второй, вторую с третьей, третью с четвертой и т. д. |
Методы вывода графических примитивов рассматривают свойство canvas как некоторый абстрактный холст, на котором они могут рисовать (Canvas переводится как "поверхность", "холст для рисования"). Холст состоит из отдельных точек — пикселов. Положение пиксела на поверхности холста характеризуется горизонтальной (X) и вертикальной (Y) координатами. Координаты возрастают сверху вниз и слева направо (Рисунок 3.1). Левый верхний пиксел поверхности формы (клиентской области) имеет координаты (0, 0), правый нижний — (ciientwidth, clientHeight). Доступ к отдельному пикселу осуществляется через свойство Pixels, представляющее собой двумерный массив, элементы которого содержат информацию о цвете точек холста.
Следует обратить внимание на важный момент. Изображение, сформированное на поверхности формы, может быть испорчено, например, в результате полного или частичного перекрытия окна программы другим окном. Поэтому программист должен позаботиться о том, чтобы в момент появления окна программа перерисовала испорченное изображение. К счастью, операционная система Windows информирует программу о необходимости перерисовки окна, посылая ей соответствующее сообщение, в результате чего возникает событие OnPaint. Событие OnPaint возникает и в момент запуска программы, когда окно появляется на экране в первый раз. Таким образом, инструкции, обеспечивающие вывод графики на поверхность формы, надо поместить в функцию обработки события onPaint.
Свойства объекта Реn (карандаш)
Таблица 3.2. Свойства объекта Реn (карандаш)
Свойство |
Определяет |
Color |
Цвет линии |
Width |
Толщину линии (задается в пикселах) |
Style |
Вид линии (psSolid— сплошная; psDash— пунктирная, длинные штрихи; psDot — пунктирная, короткие штрихи; psDashDot — пунктирная, чередование длинного и короткого штрихов; psDashDotDot — пунктирная, чередование одного длинного и двух коротких штрихов; psClear — линия не отображается (используется, если не надо изображать границу области — например, прямоугольника) |
Свойства объекта Brush (кисть)
Таблица 3.3. Свойства объекта Brush (кисть)
Свойство |
Определяет |
Color |
Цвет закрашивания замкнутой области |
Style |
Стиль заполнения области (bsSolid — сплошная заливка. Штриховка: bsHorizontal — горизонтальная; bsVertical — вертикальная; bsFDiagonal — диагональная с наклоном линий вперед; bsBDiagonal — диагональная с наклоном линий назад; bsCross — в клетку; bsDiagCross — диагональная клетка |
Ниже приведена функция обработки события onPain, которая рисует на поверхности формы олимпийский флаг.
void__fastcall TForml::FormPaint(TObject *Sender) { // полотнище флага Canvas->Pen->Width = 1; Canvas->Pen->Color = clBlack; Canvas->Brush->Color = clCream; Canvas->Rectangle(30,30,150,150); Canvas->Pen->Width =2; // ширина колец Canvas->Brush->Style = bsClear; // чтобы круг, нарисованный // методом Ellipse, не был закрашен // рисуем кольца Canvas->Pen->Color = clBlue; Canvas->Ellipse(40,40,80,80) ; Canvas->Pen->Color = clBlack; Canvas->Ellipse(70,40,110,80); Canvas->Pen->Color = clRed; Canvas->Ellipse(100,40,140,80); Canvas->Pen->Color = clYellow; Canvas->Ellipse(55,65,95,105); Canvas->Pen->Color = clGreen; Canvas->Ellipse(85,65,125,105); }
Свойства объекта TFont
Таблица 3.4. Свойства объекта TFont
Свойство |
Определяет |
Name |
Используемый шрифт. В качестве значения следует использовать название шрифта (например, Arial) |
Size |
Размер шрифта в пунктах (points). Пункт— это единица измерения размера шрифта, используемая в полиграфии. Один пункт равен 1/72 дюйма |
Style |
Стиль начертания символов. Может быть: нормальным, полужирным, курсивным, подчеркнутым, перечеркнутым. Стиль задается при помощи следующих констант: fsBold (полужирный), fsltalic (курсив), fsUnderline (подчеркнутый), fsStrikeOut (перечеркнутый) Свойство style является множеством, что позволяет комбинировать необходимые стили. Например, инструкция, которая устанавливает стиль "полужирный курсив", выглядит так: Canvas->Font->Style = TFontStyles ( ) <<fsBold<<f sUnderline |
Color |
Цвет символов. В качестве значения можно использовать константу типа TColor |
При выводе текста весьма полезны методы Textwidth и TextHeight, значениями которых являются соответственно ширина и высота области вывода текста, которые, очевидно, зависят от характеристик используемого шрифта. Обоим этим методам в качестве параметра передается строка, которую предполагается вывести на поверхность методом TextoutA.
Следующий фрагмент кода демонстрирует использование методов, обеспечивающих вывод текста на поверхность формы. Приведенная функция обработки события OnPaint закрашивает верхнюю половину окна белым, нижнюю — голубым цветом, затем в центре окна, по границе закрашенных областей, выводит текст (Рисунок 3.7).
void _fastcall TForml::FormPaint(TObject *Sender) { AnsiString ms = "Borland C++Builder"; TRect aRect; int x,y; // точка, от которой будет выведен текст // верхнюю половину окна красим белым aRect = Rect(0,0,ClientWidth,ClientHeight/2); Canvas->Brush->Color = clWhite; Canvas->FillRect(aRect); // нижнюю половину окна красим голубым aRect = Rect(0,ClientHeight/2,ClientWidth,ClientHeight); Canvas->Brush->Color = clSkyBlue; Canvas->FillRect(aRect); Canvas->Font->Name = "Times New Roman"; Canvas->Font->Size = 24; // Canvas->Font->Style = TFontStyles ()« fsBold « fsItalic; // текст разместим в центре окна х = (ClientWidth - Canvas-XTextWidth(ms)) /2; у = ClientHeight/2 - Canvas-XTextHeight(ms) /2; Canvas->Brush->Style = bsClear; // область вывода текста // не закрашивать Canvas->Font->Color = clBlack; Canvas->TextOutA(x,y,ms); // вывести текст }
Свойства компонента image
Таблица 3.5. Свойства компонента image
Свойство |
Описание |
Picture |
Иллюстрация, которая отображается в поле компонента |
Width, Height |
Размер компонента. Если размер компонента меньше размера иллюстрации и значение свойств AutoSize, Strech и Proportional равно false, то отображается часть иллюстрации |
Proportional |
Признак автоматического масштабирования картинки без искажения. Чтобы масштабирование было выполнено, значение свойства AutoSize должно быть false |
Strech |
Признак автоматического масштабирования (сжатия или растяжения) иллюстрации в соответствии с реальным размером компонента. Если размер компонента не пропорционален размеру иллюстрации, то иллюстрация будет искажена |
AutoSize |
Признак автоматического изменения размера компонента в соответствии с реальным размером иллюстрации |
Center |
Признак определяет расположение картинки в поле компонента по горизонтали, если ширина картинки меньше ширины поля компонента. Если значение свойства равно false, то картинка прижата к правой границе компонента, если true — то картинка располагается по центру |
Visible |
Признак указывает, отображается ли компонент и, соответственно, иллюстрация на поверхности формы |
Canvas |
Поверхность, на которую можно вывести графику |
Иллюстрацию, которая будет выведена в поле компонента image, можно задать как во время разработки формы приложения, так и во время работы программы.
Во время разработки формы иллюстрация задается установкой значения свойства Picture путем выбора файла иллюстрации в стандартном диалоговом окне, которое становится доступным в результате щелчка на командной кнопке Load окна Picture Editor, которое, в свою очередь, появляется в результате щелчка на кнопке с тремя точками в строке свойства picture (Рисунок 3.10).
Если размер иллюстрации больше размера компонента, то свойству Proportional нужно присвоить значение true. Тогда будет выполнено масштабирование иллюстрации в соответствии с реальными размерами компонента.
Чтобы вывести иллюстрацию в поле компонента image во время работы программы, нужно применить метод LoadFromFile к свойству Picture, указав в качестве параметра метода файл иллюстрации. Например, инструкция
Imagel->Picture->LoadFromFile("e:\\temp\\bart.bmp")
загружает иллюстрацию из файла bart.bmp и выводит ее в поле компонента вывода иллюстрации (Image 1).
По умолчанию компонент image можно использовать для отображения иллюстраций форматов BMP, ICO и WMF. Чтобы использовать компонент для отображения иллюстраций в формате JPEG (файлы с расширением jpg), надо подключить соответствующую библиотеку (поместить в текст программы директиву #include <jpeg.hpp>). Обратите внимание, что если указанной директивы в тексте программы не будет, то компилятор не выведет сообщения об ошибке. Но во время работы программы при попытке загрузить jpg-файл при помощи метода LoadFromFile возникнет ошибка — исключение EInvalidGraphic.
Свойства объекта TBitmap
Таблица 3.6. Свойства объекта TBitmap
Свойство |
Описание |
Height, Width |
Размер (ширина, высота) битового образа. Значения свойств соответствуют размеру загруженной из файла (метод LoadFromFile) или ресурса (метод LoadFromResourcelD или LoadFromResourceName) картинки |
Empty |
Признак того, что картинка в битовый образ не загружена (true) |
Transparent |
Устанавливает (true) режим использования "прозрачного" цвета. При выводе битового образа методом Draw элементы картинки, цвет которых совпадает с цветом TransparentColor, не выводятся. По умолчанию значение TransparentColor определяет цвет левого нижнего пиксела |
TransparentColor |
Задает прозрачный цвет. Элементы картинки, окрашенные этим цветом, методом Draw не выводятся |
Canvas |
Поверхность битового образа, на которой можно рисовать точно так же, как на поверхности формы или компонента image |
После того как битовый образ сформирован (загружен из файла или из ресурса), его можно вывести, например, на поверхность формы или компонента image. Сделать это можно, применив метод Draw к свойству Canvas. В качестве параметров методу Draw надо передать координаты точки, от которой будет выведен битовый образ. Например, оператор
Canvas->Draw(10,20,Plane);
выводит на поверхность формы битовый образ plane — изображение самолета.
Если перед применением метода Draw свойству Transparent битового образа присвоить значение true, то фрагменты рисунка, цвет которых совпадает с цветом левой нижней точки рисунка, не будут выведены. Такой прием используется для создания эффекта прозрачного фона. "Прозрачный" цвет можно задать и принудительно, присвоив соответствующее значение свойству TransparentColor.
Следующая программа демонстрирует работу с битовыми образами. После запуска программы в ее окне появляется изображение неба и двух самолетов (Рисунок 3.12). И небо, и самолеты — это битовые образы, загруженные из файлов во время работы программы. Загрузку и вывод битовых образов на поверхность формы выполняет функция обработки события onPaint, текст которой приведен в листинге 3.3. Белое поле вокруг левого самолета показывает истинный размер битового образа Plane. Белого поля вокруг правого самолета нет, т. к. перед тем как вывести битовый образ второй раз, свойству Transparent было присвоено значение true.
Свойства компонента Timer
Таблица 3.7. Свойства компонента Timer
Свойство |
Определяет |
Name |
Имя компонента. Используется для доступа к свойствам компонента |
Interval |
Период возникновения события OnTimer, Задается в миллисекундах |
Enabled |
Разрешение работы. Разрешает (значение true) или запрещает (значение false) возникновение события OnTimer |
Компонент Timer генерирует событие OnTimer. Период возникновения события onTimer измеряется в миллисекундах и определяется значением свойства interval. Следует обратить внимание на свойство Enabled. Оно дает возможность программе "запустить" или "остановить" таймер. Если значение свойства Enabled равно false, то событие onTimer не возникает.
В рассматриваемой программе вывод изображения выполняет функция ship, которая рисует на поверхности формы кораблик. В качестве параметров функция ship получает координаты базовой точки. Базовая точка (X0, Y0) определяет положение графического объекта в целом; от нее отсчитываются координаты графических примитивов, образующих объект (Рисунок 3.16). Координаты графических примитивов можно отсчитывать от базовой точки не в пикселах, а в относительных единицах. Такой подход позволяет легко выполнить масштабирование изображения.
Текст
Текст
Вывод текста (строк типа Ansistring) на поверхность графического объекта обеспечивает метод TextOutA. Инструкция вызова метода TextoutA в общем виде выглядит следующим образом:
Canvas->TextOutA(x,y,TeKCT)
Параметр текст задает выводимый текст. Параметры х и у определяют координаты точки графической поверхности, от которой выполняется вывод текста (Рисунок 3.6).
Точка
Точка
Поверхности, на которую программа может осуществлять вывод графики, соответствует объект canvas. Свойство Pixels, представляющее собой двумерный массив типа TColor, содержит информацию о цвете каждой точки графической поверхности. Используя свойство pixels, можно задать цвет любой точки графической поверхности, т. е. "нарисовать" точку. Например, инструкция
Canvas->Pixels[10][10] = clRed
окрашивает точку поверхности формы в красный цвет.
Размерность массива pixels определяется реальным размером графической поверхности. Размер графической поверхности формы (рабочей области, которую также называют клиентской) определяют свойства clientwidth и clientHeight, а размер графической поверхности компонента image — свойства width и Height. Левой верхней точке рабочей области формы соответствует элемент pixels [0] [0], а правой нижней —
Следующая программа (листинг 3.1), используя свойство Pixels, строит график функции у = 2 sin(x) e*/5. Границы диапазона изменения аргумента функции являются исходными данными. Диапазон изменения значения функции вычисляется во время работы программы. На основании этих данных программа вычисляет масштаб, позволяющий построить график таким образом, чтобы он занимал всю область формы, предназначенную для вывода графика. Для построения графика используется вся доступная область формы, причем если во время работы программы пользователь изменит размер окна, то график будет выведен заново с учетом реальных размеров окна.
В диалоговом окне Bitmap Properties
Рисунок 3.20. В диалоговом окне Bitmap Properties надо задать характеристики создаваемого битового образа
Builder позволяет программисту разрабатывать программы,
В этой главе...
C++ Builder позволяет программисту разрабатывать программы, которые работают с графикой. В этой главе рассказывается, что надо сделать, чтобы на поверхности формы появилась картинка, сформированная из графических примитивов, или иллюстрация, созданная в графическом редакторе или полученная в результате сканирования фотографии.
Воспроизведение баннера в окне программы
Рисунок 3.24. Воспроизведение баннера в окне программы
Вывод текста
Рисунок 3.7. Вывод текста
Иногда требуется вывести какой-либо текст после сообщения, длина которого во время разработки программы неизвестна. В этом случае необходимо знать координаты правой границы области выведенного текста. Координаты правой границы текста, выведенного методом TextOutA, можно получить, обратившись к свойству penPos.
Следующий фрагмент кода демонстрирует возможность вывода строки текста при помощи двух инструкций TextOutA:
Canvas->TextOutA(10,10,"Borland "); Canvas->TextOutA(Canvas->PenPos.x, Canvas->PenPos.y, "C++Builder");
Загрузка битового образа из ресурса программы
Загрузка битового образа из ресурса программы
В программе "Полет над городом" (листинг 3.7) картинки (битовые образы) фона и объекта (самолета) загружаются из файлов. Такой подход не всегда удобен. C++ Builder позволяет поместить нужные битовые образы в исполняемый файл программы и по мере необходимости загружать их непосредственно оттуда.
Битовый образ, находящийся в выполняемом файле программы, называется ресурсом, а операция загрузки битового образа из выполняемого файла — загрузкой битового образа из ресурса.
Для того чтобы воспользоваться возможностью загрузки картинки из ресурса, сначала надо создать файл ресурсов и поместить в него нужные картинки.
Значения параметров метода Arc
Рисунок 3.4. Значения параметров метода Arc определяют дугу как часть эллипса (окружности)
Значения параметров метода Ellipse
Рисунок 3.3. Значения параметров метода Ellipse определяют вид геометрической фигуры
Вместо четырех параметров — координат диагональных углов прямоугольника — методу Ellipse можно передать один — объект типа TRect. Следующий фрагмент кода демонстрирует использование объекта TRect в качестве параметра метода Ellipse.
TRect rec = Rect(10,10,50,50); Canvas->Ellipse(rec);
Как и в случае вычерчивания других примитивов, вид контура эллипса (цвет, толщину и стиль линии) определяют значения свойства Реn, а цвет и стиль заливки области внутри эллипса — значения свойства Brush той поверхности (canvas), на которой метод чертит.
Значения параметров метода Pie
Рисунок 3.5. Значения параметров метода Pie определяют сектор как часть эллипса (окружности)
Значок компонента Image
Рисунок 3.9. Значок компонента Image
Значок компонента Timer
Рисунок 3.15. Значок компонента Timer