Анимация копирования файла
Вы можете посмотреть воспроизводимое изображение по кадрам. Для этого щелкните на компоненте правой кнопкой мыши и из всплывшего меню выберите разделы Next Frame (следующий кадр) или Previous Frame (предыдущий кадр). Это позволит вам выбрать фрагмент клипа, если вы не хотите воспроизводить клип полностью. Воспроизвести фрагмент клипа можно, установив соответствующие значения свойств StartFrame — начальный кадр воспроизведения, и StopFrame — последний кадр воспроизведения.
Воспроизводить фрагмент клипа можно и методом Play, который определен следующим образом: procedure Play(FromFrame, ToFrame: Word; Count: Integer);
Метод воспроизводит заданную последовательность кадров клипа от FromFrame до ToFrame включительно и воспроизведение повторяется Count раз. Если FromFrame = 1, то воспроизведение начинается с первого кадра. Значение ToFrame должно быть не меньше FromFrame и не больше значения, определяемого свойством FrameCount (свойство только для чтения), указывающим полное число кадров в клипе. Если Count = 0, то воспроизведение повторяется до тех пор, пока не будет выполнен метод Stop.
Выполнение Play идентично заданию StartFrame равным FromFrame, StopFrame равным ToFrame, Repetitions равным Count и последующей установке Active в true.
В компоненте Animate предусмотрены события OnClose, OnOpen, OnStart и OnStop, генерируемые соответственно в моменты закрытия и открытия компонента, начала и окончания воспроизведения.
Давайте теперь построим тестовое приложение, показывающее возможности компонента Animate. Установите в том приложении, которое вы уже начали, свойство Visible компонента Animate в false. Это надо для того, чтобы изображение возникало только тогда, когда произойдет соответствующее событие: копирование файлов, поиск файлов и т.п. В тестовом приложении мы будем имитировать начало и окончание события, которое должно сопровождаться мультипликацией, нажатиями кнопок запуска и останова воспроизведения. Поэтому верните значение свойства Repetitions в 0, чтобы воспроизведение длилось до окончания события. Свойство Active установите в false. Полезно также установить свойство AutoSize в false, а свойство Center в true, чтобы изображение всегда появлялось в центре экрана.
А теперь добавьте в приложение 3 кнопки (Рисунок 4.22). Первая из них (назовите ее ВWind) будет начинать процесс воспроизведения поочередно всех стандартных клипов Windows. Вторая кнопка (назовите ее BStop) пусть завершает воспроизведение очередного клипа. А третью кнопку (назовите ее BFile) введем для того, чтобы показать, что компонент может воспроизводить изображения из заданного файла .avi. Чтобы пользователь мог выбрать файл изображения, добавьте на форму компонент OpenDialog (см. ) и задайте его фильтр (свойство Filter) равным видео *.avi *.avi
Теперь все приготовления закончены и осталось только написать обработчики событий. Код обработчиков может иметь вид:
Демонстрация возможностей компонента Animate
Обработчик события OnClick кнопки BWind задает начальное значение свойства CommonAVI, сбрасывает счетчик на 1, делает компонент Animate1 видимым и активизирует его.
Обработчик события OnClick кнопки BStop останавливает воспроизведение методом Stop.
Обработчик события OnStop компонента Animate1 увеличивает счетчик на 1, в зависимости от значения счетчика загружает в компонент соответствующий клип Windows и активизирует компонент. Если все клипы уже воспроизведены, то компонент делается невидимым.
Обработчик события OnClick кнопки BFile загружает в компонент видео файл, выбранный пользователем.
Выполните приложение и проверьте его в работе. В качестве видео файла можете использовать файл ...\Demos\Coolstuf\Cool.avi, поставляемый с примерами Delphi (на Рисунок 4.22 изображен момент воспроизведения именно этого файла).
Форма приложения Рисунок 4.8 с занесенными в нее условными данными
Вы можете, если хотите, добавить на этот компонент Chart еще одну тождественную серию, нажав на закладке Series страницы Chart кнопку Clone, а затем для этой новой серии нажать кнопку Change (изменить) и выбрать другой тип диаграммы, например, Bar. Конечно, два разных типа диаграммы на одном рисунке будут выглядеть плохо. Но вы можете выключить индикатор этой новой серии на закладке Series, а потом предоставить пользователю выбрать тот или иной вид отображения диаграммы (ниже будет показано, как это делается).
Выйдите из Редактора Диаграмм, выделите в вашем приложении нижний компонент Chart и повторите для него задание свойств с помощью Редактора Диаграмм. В данном случае вам надо будет задать две серии, если хотите отображать на графике две кривые, и выбрать тип диаграммы Line. Поскольку речь идет о графиках, вы можете воспользоваться закладками Axis и Walls для задания координатных характеристик осей и трехмерных граней графика.
На этом проектирование внешнего вида приложения завершается. Осталось написать код, задающий данные, которые вы хотите отображать. Для тестового приложения давайте зададим в круговой диаграмме просто некоторые константные данные, а в графиках — функции синус и косинус.
Для задания отображаемых значений надо использовать методы серий Series. Остановимся только на трех основных методах.
Метод Clear очищает серию от занесенных ранее данных.
Метод Add: Add(Const AValue: Double; Const ALabel: String; AColor: TColor) позволяет добавить в диаграмму новую точку. Параметр AValue соответствует добавляемому значению, параметр ALabel — название, которое будет отображаться на диаграмме и в легенде, AColor — цвет. Параметр ALabel — не обязательный, его можно задать пустым: ''.
Метод AddXY: AddXY(Const AXValue, AYValue: Double; Const ALabel: String; AColor: TColor) позволяет добавить новую точку в график функции. Параметры AXValue и AYValue соответствуют аргументу и функции. Параметры ALabel и AColor те же, что и в методе Add.
Таким образом, процедура, обеспечивающая загрузку данных в нашем примере, может иметь вид: const A1=155; A2=251; A3=203; A4=404; var i: word; begin With Series1 do begin Clear; Add(A1, 'Цех 1', clYellow); Add(A2, 'Цех 2', clBlue); Add(A3, 'Цех 3', clRed); Add(A4, 'Цех 4', clPurple); end; Series2.Clear; Series3.Clear; for i:=0 to 100 do begin Series2.AddXY(0.02*Pi*i, sin(0.02*Pi*i), '', clRed); Series3.AddXY(0.02*Pi*i, cos(0.02*Pi*i), '', clBlue); end; end;
Эту процедуру можно включить в обработку щелчка какой-нибудь кнопки, в команду меню или просто в событие OnCreate формы. Операторы Clear нужны, если в процессе работы приложения вы собираетесь обновлять данные. Без этих операторов повторное выполнение методов Add и AddXY только добавит новые точки, не удалив прежние.
Если вы предусмотрели, например, для данных, отображаемых в диаграмме, две серии Series1 и Series4 разных видов — Pie и Bar, то можете ввести процедуру, изменяющую по требованию пользователя тип диаграммы. Эту процедуру можно ввести в событие OnClick какой-нибудь кнопки, в команду меню или, например, просто в обработку щелчка на компоненте Chart. Для того, чтобы загрузить данные в Series4 и сделать эту диаграмму в первый момент невидимой, можно вставить в конце приведенной ранее процедуры операторы Series4.Assign(Series1); Series4.Active:=false;
Первый из этих операторов переписывает данные, помещенные в Series1, в серию Series4. А второй оператор делает невидимой серию Series4. Смена типа диаграммы осуществляет процедура Series1.Active := not Series1.Active; Series4.Active := not Series4.Active;
На Рисунок 4.8 б вы можете видеть результат переключения пользователя на другой вид диаграммы.
График синусоиды, построенный по пикселям (а) и линиями (б)
Канва — объект класса TCanvas имеет множество методов, которые позволяют рисовать графики, линии, фигуры с помощью свойства Pen — перо. Это свойство является объектом, в свою очередь имеющим ряд свойств. Одно из них уже известное вам свойство Color — цвет, которым наносится рисунок. Второе свойство — Width (ширина линии). Ширина задается в пикселях. По умолчанию ширина равна 1.
Свойство Style определяет вид линии. Это свойство может принимать следующие значения:
У канвы имеется свойство PenPos типа TPoint (.). Это свойство определяет в координатах канвы текущую позицию пера. Перемещение пера без прорисовки линии, т.е. изменение PenPos, производится методом канвы MoveTo(X,Y). Здесь (X, Y) — координаты точки, в которую перемещается перо. Эта текущая точка становится исходной, от которой методом LineTo(X,Y) можно провести линию в точку с координатами (X,Y). При этом текущая точка перемещается в конечную точку линии и новый вызов LineTo будет проводить точку из этой новой текущей точки.
Давайте попробуем нарисовать пером график синуса из предыдущего примера. В данном случае обработчик события формы OnPaint может иметь вид: procedure TForm1.FormPaint(Sender: TObject); var X,Y: real; // координаты функции PX,PY: longint; // координаты пикселей begin Color:=clWhite; Canvas.MoveTo(0,ClientHeight div 2); for PX:=0 to ClientWidth do begin {X - аргумент графика, соответствующий пикселю с координатой РХ} X := PX*4*Pi/ClientWidth; Y := Sin(X); {PY — координата пикселя, соответствующая координате Y} PY := trunc(ClientHeight - (Y+1)*ClientHeight/2); {Проводится линия на графике} Canvas.LineTo(PX,PY); end; end;
Результат работы приложения в этом варианте вы можете видеть на Рисунок 4.1 б. Как видите, качество графика существенно улучшилось.
Перо может рисовать не только прямые линии, но и фигуры. Полный список методов канвы, использующих перо, см. во встроенной справке Delphi. А пока в качестве примера приведем только один из них — Ellipse, который рисует эллипс или окружность. Он объявлен как procedure Ellipse(X1, Y1, Х2, Y2: Integer); где параметры X1, Х2, Y1, Y2 определяют координаты прямоугольника, описывающего эллипс или окружность. Например, оператор Canvas.Ellipse(10, 40, 20, 50); нарисует окружность с диаметром 10 и с координатами центра (15, 45).
Фигуры в общем случае рисуются не пустыми, а закрашенными с помощью свойства канвы Brush — кисть. Свойство Brush является объектом, имеющим в свою очередь ряд свойств. Свойство Color определяет цвет заполнения. Свойство Style определяет шаблон заполнения (штриховку). По умолчанию значение Style равно bsSolid, что означает сплошное закрашивание цветом Color.
У пера Pen имеется еще одно свойство, которое мы пока не рассматривали. Это свойство — Mode (режим). По умолчанию значение Mode = pmCopy. Это означает, что линии проводятся цветом, заданным в свойстве Color. Но возможны и другие режимы, в которых учитывается не только цвет Color, но и цвет соответствующих пикселей фона. Наиболее интересным из этих режимов является режим pmNotXor — сложение с фоном по инверсному исключающему ИЛИ. Если задан этот режим, то повторное рисование той же фигуры на том же месте канвы убирает ранее нарисованное изображение и восстанавливает цвета пикселей, которые были до первого изображения фигуры.
Эту особенность режима pmNotXor можно использовать для создания простенькой анимации. Достаточно нарисовать нечто, затем стереть нарисованное, перерисовать немного измененным — и рисунок будет представляться ожившим.
Попробуйте сделать сами простенькую мультипликацию — движущуюся окружность. Начните новое приложение и в раздел implementation вставьте объявление var X,Y: integer;
Тем самым вы введете глобальные переменные X и Y — текущие координаты изображения.
В событие формы OnPaint вставьте операторы Canvas.Brush.Color := clWhite; Color := clWhite; Canvas.Pen.Mode := pmNotXor;
Первый из этих операторов задает белый цвет кисти Brush. Значит ваша окружность будет закрашена внутри белым цветом. Второй оператор задает белый цвет фона поверхности формы. Третий оператор устанавливает режим пера pmNotXor, который позволит вам стирать прежнее изображение прежде, чем нарисовать новое.
Даже самая простая мультипликация нуждается в синхронизации. Иначе скорость движения будет определяться быстродействием компьютера. Поэтому перенесите на форму компонент Timer — таймер со страницы System. Этот компонент описан в . Можете посмотреть там его подробное описание. А пока задайте его свойство Interval равным, например, 30 (это время выдержки в миллисекундах, но реальное время выдержки будет больше — см. раздел 5.7) и установите свойство Enabled равным false (это означает, что таймер не будет запускаться автоматически в момент запуска приложения).
В обработчик события этого компонента OnTimer вставьте операторы // Стирание прежнего изображения Canvas.Ellipse(Х-5, Y, X+5, Y-1Q); Inc(X); // Рисование нового изображения Canvas.Ellipse(Х-5, Y, X+5, Y-10); // Останов при достижении конца формы if (X >= ClientWidth-20) then Timer1.Enabled := false;
Первый из этих операторов рисует окружность в том месте, где она была нарисована ранее, т.е. стирает прежнее изображение. Далее увеличивается на единицу функцией Inc текущая координата X и изображение окружности рисуется в новой позиции. Последний оператор останавливает изображение у края формы.
Теперь перенесите на форму кнопку Button и в обработчик щелчка на ней поместите операторы Х:=10; Y:=100; Canvas.Ellipse(X-5, Y, X+5, Y-10); Timer1.Enabled:=true;
Первые два оператора задают начальные координаты окружности. Третий оператор рисует окружность в ее начальном положении, а четвертый — запускает таймер.
Оттранслируйте приложение, запустите его на выполнение, щелкните на кнопке. Вы увидите изображение окружности, перемещающееся по форме слева направо. А дальше уж подключите вашу фантазию и преобразуйте это не слишком интересное приложение во что-нибудь более увлекательное.
На канве можно отображать не только программно создаваемые изображения, но и изображения, хранящиеся в графических файлах. Только сама канва не имеет метода загрузки изображения из файла. Поэтому загружать файл надо в какой-нибудь другой графический объект, способный воспринимать информацию графических файлов. А затем переписывать изображение из этого объекта на канву с помощью метода канвы Draw. Его описание: procedure Draw(X, Y: Integer; Graphic: TGraphic);
Здесь параметры Х и Y определяют координаты левого верхнего угла размещения изображения на канве, a Graphic — объект, хранящий информацию. В качестве такого объекта может выступать, например, объект типа TBitMap, предназначенный для хранения битовых матриц. Давайте посмотрим, как все это выглядит на практике.
Откройте новое приложение, перенесите на форму компонент OpenPictureDialog со страницы Dialogs (это компонент диалога открытия графических файлов — см. ) и кнопку Button. Разместите OpenPictureDialog в любом месте формы, так как этот компонент невизуальный, а кнопку разместите внизу формы. В обработчик щелчка на кнопке занесите код: procedure TForm1.Button1Click(Sender: TObject); var BitMap:TBitMap; begin // Выбор пользователем графического файла if OpenPictureDialog1.Execute then begin // Создание объекта BitMap типа TBitMap BitMap:=TBitMap.Create; // Загрузка в BitMap выбранного графического файла BitMap.LoadFromFile(OpenPictureDialog1.FileName); // Перенос изображения на канву формы Canvas.Draw(10, 10, BitMap); // Уничтожение объекта BitMap BitMap.Free; end; end;
Этот код создает временный объект типа TBitMap с именем BitMap. Затем вызывается диалог открытия графического файла OpenPictureDialog1 и, если пользователь выбрал файл, то он загружается в BitMap методом LoadFromFile. Затем методом Draw загруженное изображение копируется на канву в область, с координатами левого верхнего угла (10, 10). После этого временный объект BitMap уничтожается.
Запустите ваше приложение и щелкните на его кнопке. Вы увидите, что можете загрузить любой графический файл типа .bmp и он отобразится на канве формы (см. Рисунок 4.2 а). Графические файлы вы можете найти в каталоге Images. В Delphi 5 и 4 он обычно расположен в каталоге ...\program files\Common Files\Borland Shared. В Delphi 3 он расположен в каталоге ...\program files\Borland\Delphi 3, а в Delphi 1 — в каталоге Delphi 16. В каталоге Images имеется, в частности, подкаталог \Images\Splash\16Color\, в котором хранится файл, загруженный в примере Рисунок 4.2.
Изображение на канве графического файла (а) и его стирание (б) при перекрытии другим окном
а) |
б) | Вы создали неплохое приложение для просмотра графических файлов. Но теперь давайте попробуем увидеть его крупный недостаток. Не закрывая своего приложения, перейдите в какую-нибудь другую программу, например, вернитесь в Delphi. Затем, ничего там не делая, опять перейдите в свое выполняющееся приложение. Если окно программы, в которую вы уходили, целиком перекрыло окно вашего приложения, то вернувшись в него вы увидите, что картинка в окне исчезла. Если же окно вашего приложения перекрывалось только частично, то вернувшись в свое приложение вы, возможно, увидите результат, подобный представленному на Рисунок 4.2 б. Вы видите, что если окно какого-то другого приложения перекрывает на время окно вашего приложения, то изображение, нарисованное на канве формы, портится. Посмотрим, как можно устранить этот недостаток. Если окно было перекрыто и изображение испортилось, операционная система сообщает приложению, что в окружении что-то изменилось и что приложение должно предпринять соответствующие действия. Как только требуется обновление окна, для него генерируется событие OnPaint. В обработчике этого события (в нашем случае события формы) нужно перерисовать изображение. Перерисовка может производиться разными способами в зависимости от приложения. В нашем примере можно было бы вынести объявление переменной BitMap (оператор var BitMap: TBitMap) за пределы приведенной выше процедуры, т.е. сделать эту переменную глобальной, разместив непосредственно в разделе implementation. Оператор BitMap.Free можно было бы перенести в обработчик события формы OnDestroy, происходящего в момент закрытия приложения. Тогда в течение всего времени выполнения вашего приложения вы будете иметь копию картинки в компоненте BitMap и вам достаточно ввести в обработчик события OnPaint формы всего один оператор: Canvas.Draw(10, 10, BitMap); Сделайте это, и увидите, что изображение на форме не портится при любых перекрытиях окон. Помимо рассмотренного метода Draw канва имеет еще метод копирования CopyRect: procedure CopyRect(Dest: TRect; Canvas: TCanvas; Source: TRect); Метод копирует указанную параметром Source область изображения в канве источника изображения Canvas в указанную параметром Dest область данной канвы. Тип TRect, характеризующий прямоугольные области Source и Dest, уже описывался в . Например, оператор Canvas.CopyRect(MyRect2, Bitmap.Canvas, MyRect1); копирует на канву формы в область MyRect2 изображение из области MyRect1 канвы компонента Bitmap. Копирование методом CopyRect производится в режиме, установленном свойством CopyMode. По умолчанию это свойство имеет значение cmSrcCopy, что означает просто замену изображения, содержащегося ранее в области Dest, на копируемое изображение. Другие возможные значения CopyMode позволяют комбинировать изображения, но их рассмотрение выходит за рамки данной книги. Этими основными сведениями о выводе графической информации на канву мы ограничимся. В были сообщены сведения о выводе на канву текста. В целом же канва — сложный объект, обладающий еще многими свойствами и методами. Но это требует развернутого обсуждения, выходящего за рамки данной книги. В следующей книге серии «Все о Delphi» эти вопросы будут рассмотрены подробнее. |
Изображение в компоненте Image битовой матрицы (а) и пиктограммы (6)
а) | б) | В этом приложении метод LoadFromFile применен к Image1.Picture. Если будут открываться только файлы битовых матриц, то оператор загрузки файла можно заменить на Image1.Picture.Bitmap.LoadFromFile( OpenPictureDialog1.FileName); Для пиктограмм можно было бы использовать оператор Image1.Picture.Icon.LoadFromFile( OpenPictureDialog1.FileName); а для метафайлов — оператор Image1.Picture.Metafile.LoadFromFile( OpenPictureDialog1.FileName); или Image1.Picture.Graphic.LoadFromFile( OpenPictureDialog1.FileName) ; Но во всех этих случаях, если формат файла не совпадет с предполагаемым, возникнет ошибка. Аналогично работает и метод SaveToFile с тем отличием, что примененный к Picture или к Picture.Graphic он сохраняет в файле изображение любого формата. Например, если вы дополните свое приложение диалогом SavePictureDialog (см. ), введете в меню раздел Сохранить как и в его обработчик поместите оператор if SavePictureDialog1.Execute then Image1.Picture.SaveToFile(SavePictureDialog1.FileName); то пользователь получит возможность сохранить изображение любого формата в файле с новым именем. Только при этом, чтобы не возникало в дальнейшем путаницы, расширение сохраняемого файла все-таки должно соответствовать формату сохраняемого изображения. Абсолютно идентично для изображений любого формата будет работать программа, если оператор сохранения вы замените на Image1.Picture.Graphic.SaveToFile( SavePictrureDialog1.FileName); использующий свойство Picture.Graphic. А если вам известен формат хранимого в компоненте Image изображения, то вы можете применить метод SaveToFile к свойствам Picture.Bitmap, Picture.Icon и Picture.Metafile. Для всех рассмотренных объектов Picture, Picture.Bitmap, Picture.Icon и Picture.Metafile определены методы присваивания значений объектов: procedure Assign(Source: TPersistent); Однако, для BitMap, Icon и Metafile присваивать можно только значения однородных объектов: соответственно битовых матриц, пиктограмм, метафайлов. При попытке присвоить значения разнородных объектов генерируется исключение ЕConvertError. Объект Picture — универсальный, ему можно присваивать значения объектов любых из остальных трех классов. А значение Picture можно присваивать только тому объекту, тип которого совпадает с типом объекта, хранящегося в нем. Метод Assign можно использовать и для обмена изображениями с буфером Clipboard. Например, оператор Clipboard.Assign(Image1.Picture) ; занесет в буфер обмена изображение, хранящееся в Image1. Аналогично оператор Image1.Picture.Assign(Clipboard) ; прочитает в Image1 изображение, находящееся в буфере обмена. Причем это может быть любое изображение и даже текст. Надо только не забыть при работе с буфером обмена вставить в оператор uses вашего модуля ссылку на модуль Clipbrd. Автоматически Delphi эту ссылку не вставляет. Возвращаясь к свойствам компонента Image, можно отметить один недостаток, присущий нашему тестовому приложению, приведенному на Рисунок 4.5. При загрузке разных изображений размер окна приложения может оказаться или слишком маленьким, и тогда вы увидите только часть изображения, или слишком большим, и тогда изображение будет некрасиво размещено в левом верхнем углу формы, оставляя много пустого пространства. Этот недостаток можно устранить, если воспользоваться свойствами Height (высота) и Width (ширина) компонента Image. При свойстве AutoSize установленном в true размеры Image автоматически устанавливаются равными размерам загруженного изображения. И этими размерами можно воспользоваться для соответствующего изменения размеров формы. Например, приведенный ранее код загрузки изображения из файла можно заменить на следующий: if OpenPictureDialog1.Execute then begin Image1.Picture.LoadFromFile( OpenPictureDialog1.FileName); Form1.ClientHeight := Image1.Height+10; Image1.Top := Form1.ClientRect.Top + (Form1.ClientHeight - Image1.Height) div 2; Form1.ClientWidth := Image1.Width+10; Image1.Left := Form1.ClientRect.Left + (Form1.ClientWidth - Image1.Width) div 2; end; В этом коде размеры клиентской области формы устанавливаются несколько больше размеров компонента Image1, которые в свою очередь адаптируются к размеру картинки благодаря свойству AutoSize. Внесите эти исправления в свое приложение, выполните его и увидите, что форма стала автоматически адаптироваться к размерам загруженного изображения. |
Компонент Chart
Теперь рассмотрим компонент Chart. Этот компонент позволяет строить различные диаграммы и графики, которые выглядят очень эффектно (Рисунок 4.8). Компонент Chart имеет множество свойств, методов, событий, так что если все их рассматривать, то этому пришлось бы посвятить целую главу. Поэтому ограничимся рассмотрением только основных характеристик Chart. А с остальными вы можете ознакомиться во встроенной справке Delphi или просто опробовать их, экспериментируя с диаграммами.
Компонент Shape
Компонент Shape только условно может быть отнесен к средствам отображения графической информации, поскольку просто представляет собой различные геометрические фигуры, соответствующим образом заштрихованные. Основное свойство этого компонента — Shape (форма), которое может принимать значения:
stRectangle | прямоугольник |
stRoundRect | прямоугольник со скругленными углами |
stEllipse | эллипс |
stSquare | квадрат |
stRoundSquare | квадрат со скругленными углами |
stCircle | круг |
Компоненты Image и PaintBox
Компоненты Image и PaintBox представляют собой некоторую ограниченную поверхность с канвой, на которую можно заносить изображения, как это описано в . При этом компонент PaintBox, собственно говоря, не дает ничего нового по сравнению с рисованием на канве формы. Рисование на PaintBox вместо формы не имеет никаких преимуществ, кроме, может быть, некоторого облегчения в расположении одного или нескольких рисунков в площади окна.
Компонент Image много богаче по своим возможностям и удобнее, чем PaintBox. Даже при использовании описанных в приемов рисования на канве компонент Image имеет существенное преимущество: в нем не приходится думать о перерисовке изображения, испорченного из-за перекрытия данного окна другими. Все, связанное с обработкой событий OnPaint, рассмотренных в разделе 4.2, в Image осуществляется автоматически. Кроме того с помощью Image проще, чем при непосредственном рисовании на канве формы, расположить в окне приложения несколько изображений и управлять ими. При этом отпадает необходимость сложных и нудных расчетов координат канвы формы, обеспечивающих требуемое взаимное расположение изображений, т.е. в полной мере проявляются преимущества визуального программирования. Так что, вероятно, во всех случаях лучше работать с канвой Image, чем с канвой формы.
Но помимо этих возможностей у компонента Image имеются свойства, позволяющие работать с различными типами графических файлов.
Delphi поддерживает три типа файлов — битовые матрицы, пиктограммы и метафайлы. Все три типа файлов хранят изображения; различие заключается лишь в способе их хранения внутри файлов и в средствах доступа к ним. Битовая матрица (файл с расширением .bmp) отображает цвет каждого пикселя в изображении. При этом информация хранится таким образом, что любой компьютер может отобразить изображение с разрешающей способностью и количеством цветов, соответствующими его конфигурации.
Пиктограммы (файлы с расширением .ico) — это маленькие битовые матрицы. Они повсеместно используются для обозначения значков приложений, в быстрых кнопках, в пунктах меню, в различных списках. Способ хранения изображений в пиктограммах схож с хранением информации в битовых матрицах, но имеются и различия. В частности, пиктограмму невозможно масштабировать, она сохраняет тот размер, в котором была создана.
Метафайлы (Metafiles) хранят не последовательность битов, из которых состоит изображение, а информацию о способе создания картинки. Они хранят последовательности команд рисования, которые и могут быть повторены при воссоздании изображения. Это делает такие файлы, как правило, более компактными, чем битовые матрицы.
Компонент Image позволяет отображать информацию, содержащуюся в графических файлах всех указанных типов. Для этого служит его свойство Picture — объект типа TPicture.
Компоненты страницы ActiveX — F1Book, Chartfx, Graph
К компонентам, отображающим графическую информацию, может быть отнесен рассмотренный в компонент F1Book со страницы библиотеки ActiveX. На приводившемся в этом разделе Рисунок 3.14 показано, как можно использовать этот компонент для отображения диаграмм и графиков данных, занесенных в таблицу.
Еще одним интересным компонентом, отображающим графическую информацию, является Chartfx со страницы библиотеки ActiveX. Он представляет собой законченный редактор диаграмм со встроенной инструментальной панелью (Рисунок 4.12). Нажимая кнопки инструментальной панели пользователь может задавать новые данные (вторая кнопка справа на Рисунок 4.12 и выбор опции Data Editor), изменять тип диаграммы, сохранять диаграмму в файле с расширением .chf или загружать ее из аналогичного файла, копировать диаграмму в буфер обмена Clipboard и таким образом включать ее в другие документы (например, в документы Word) и т.п.
Методы компонентов, обеспечивающие печать
Ряд компонентов, описанных в предыдущих разделах, имеют методы, обеспечивающие печать хранящихся в них данных. Например, компонент RichEdit (см. ) имеет метод Print, позволяющий печатать хранящийся в нем текст. В этот метод передается единственный параметр типа строки, назначение которого заключается только в том, что при просмотре в Windows очереди печатаемых заданий принтера эта строка появляется как имя задания. Например, оператор RichEdit1.Print('Печать RichEdit1'); обеспечивает печать текста компонента RichEdit1, причем задание на печать получает имя «Печать RichEdit1».
Печать воспроизводит все заданные особенности форматирования. Перенос строк и разбиение текста на страницы производится автоматически. Длина строк никак не связана с размерами компонента RichEdit, содержащего этот текст.
Компонент Chart (см. ) также имеет метод Print, обеспечивающий печать отображаемого в компоненте графика или диаграммы. Предварительно может быть выполнен метод PrintPortrait, задающий книжную (вертикальную) ориентацию бумаги, или метод PrintLandscape, задающий альбомную (горизонтальную) ориентацию. Масштабировать размер печатаемого графика можно, вызвав предварительно метод PrintRect: procedure PrintRect(const R: TRect); в котором параметр R определяет размер области принтера, в которой осуществляется печать.
Компонент Chartfx (см. ) имеет быструю кнопку печати (пятая слева в инструментальной панели Рисунок 4.12), с помощью которой пользователь в любой момент может напечатать текущий график или диаграмму.
Не только многие компоненты, но и сами формы имеют метод Print, который печатает клиентскую область формы. При этом полоса заголовка формы и полоса главного меню не печатается. Таким образом, можно включить в приложение форму, в которой пользователь во время выполнения размещает необходимые для печати результаты. Если имя этой формы Form2, то ее печать может выполняться оператором Form2.Print;
Свойство формы PrintScale определяет опции масштабирования изображения при печати. Возможные значения PrintScale:
poNone | Масштабирование не используется. Размер изображения может изменяться в зависимости от используемого принтера. |
poPrintToFit | Делается попытка напечатать изображение формы того же размера, который виден на экране. |
poProportional | Увеличивает или уменьшает размер изображения, подгоняя его под размер страницы, заданный при установке принтера. Это значение принято по умолчанию. |
Окна ввода выражений компонента
Вы можете просто написать приведенную выше функцию COPY с соответствующими аргументами в свойстве Expression. Но если вы хотите воспользоваться окном ввода выражений, то вам надо выполнить следующее. Нажмите кнопку Function. Перед вами откроется окно выбора функции, представленное на Рисунок 4.17 б. В левом списке вы видите категории функций, а в правом — доступные функции. В нашем примере вам надо выбрать в правом списке функцию COPY. При этом под списками вы видите пояснение функции и ее синтаксис. Нажмите кнопку Continue (продолжить). Вы попадете в окно ввода параметров, представленное на Рисунок 4.17 в. Может в его окнах непосредственно писать значения аргументов. Но если в качестве аргумента выступает другая функция (в нашем примере первый аргумент — функция DATE), то можете нажать кнопку с многоточием около окна соответствующего аргумента. Вы опять попадете в окно 4.17 а, можете в нем опять нажать Function и выбрать в появившемся окне Рисунок 4.17 б функцию DATE. После этого вы вернетесь в окно Рисунок 4.17 в, но в качестве аргумента в нем уже будет занесена функция. Таким образом просто вводить выражения, содержащие вложенные функции.
Когда вы ввели все аргументы, щелкните на ОК и вернетесь в основное окно Рисунок 4.17 а, в котором будет сформировано требуемое выражение. Щелкните в нем на OK и сформированное выражение занесется в свойство Expression.
Компонент QRSysData позволяет отображать в отчете системные данные. Его основное свойство Data, которое может принимать следующие значения:
Свойство Text компонента QRSysData определяет текст, предшествующий отображаемой величине.
Давайте в качестве примера использования всех этих компонентов рассмотрим создание простого отчета вида, представленного на Рисунок 4.16. Он содержит некоторый текст и рисунки, имеет нижние колонтитулы, в которых печатается название отчета и номер страницы. Кроме того, мы хотим, чтобы на первой странице над нижним колонтитулом было написано «МОСКВА» и дата создания отчета. Начните новый проект. Перенесите на форму компонент QuickRep и в его свойстве Bands установите в true подсвойство HasDetail — основная полоса, в которой вы будете писать текст, и подсвойство HasPageFooter — полоса нижних колонтитулов.
Свойство HasTitle можно устанавливать в true, а можно не устанавливать, поскольку различие между заголовком отчета и его полосой детализации проявляться в нашем случае не будет. Дело в том, что при работе с базами данных полоса детализации может печататься многократно и тогда надо отдельно выделить полосу заголовка, которая должна печататься только один раз. А в нашем случае полоса детализации будет печататься один раз, так что она не отличается от заголовка.
Если вы установили в true свойства HasDetail и HasPageFooter, то на поле компонента QuickRep появятся слабо видимые полосы с надписями «Detail» и «Page Footer». Перенесите в верхнюю часть полосы детализации компонент QRImage. Щелкните на кнопке с многоточием около его свойства Picture и загрузите в него какую-нибудь картинку так же, как в обычный компонент Image (см. ). Перенесите в полосу детализации компонент QRLabel, расположите его под рисунком и задайте заголовок отчета в свойстве Caption. Установите свойство Alignment в taCenter и AlignToBand в true. Это обеспечит размещение заголовка в центре страницы по горизонтали. Назовите эту метку QRLTitle. В дальнейшем нам надо будет на нее ссылаться. Разместите примерно в центре страницы компонент QRRichText, в котором будет писаться основной текст. Напишите какой-нибудь текст в свойстве Lines.
Теперь на страницу надо добавить строку с текстом «МОСКВА» и датой создания отчета. Но если мы разместим ее под компонентом QRRichText, то в отчете она окажется непосредственно под текстом. А мы хотим разместить ее внизу страницы. Поэтому нам надо ввести в отчет еще одну полосу. Перенесите на форму компонент QRSubDetail. Установите его свойство AlignToBottom в true. Это обеспечит размещение полосы внизу страницы. Разместите на полосе SubDetail компонент QRLabel, написав в его свойстве Caption текст «МОСКВА». Разместите правее метки компонент QRSysData. В его свойстве Data установите значение qrsDate. Этот компонент будет отображать дату создания отчета.
Это не лучший вариант, так как при этом будет отображаться день, месяц и год. Если хотите, чтобы отображались только месяц и год, используйте вместо QRSysData компонент QRExpr, в котором можно, как показано выше, задать отображение даты без указания дня.
Осталось внести информацию в нижний колонтитул страницы. Перенесите на полосу «Page Footer» компонент QRLabel, задайте в его свойстве Caption текст (например, «Отчет по изучению Delphi»). Установите свойство Alignment в taLeftJustify и AlignToBand в true. Это обеспечит выравнивание метки по левому краю страницы. Установите в свойстве Frame подсвойство DrawTop в true. Это обеспечит появление линии, отделяющей колонтитул от текста. Перенесите на полосу «Page Footer» компонент QRSysData. В его свойстве Data установите значение qrsPageNumber. Этот компонент будет отображать номер страницы. Установите свойство Alignment в taRightJustify и AlignToBand в true. Это обеспечит выравнивание номера по правому краю страницы,
Проектирование отчета завершено. Щелкните правой кнопкой мыши на компоненте QuickRep и из всплывшего меню выберите команду Preview. Перед вами откроется окно предварительного просмотра, в котором вы увидите свой отчет. Подберите размещение компонентов и размеры шрифтов в них так, чтобы все выглядело прилично.
Конечно, подобный отчет совсем не интересен, так как он весь создан в процессе проектирования. К тому же вы никак не использовали возможностей форматирования текста в компоненте QRRichText. Поэтому текст выглядит некрасиво. Давайте теперь создадим форму (Рисунок 4.18), которая управляла бы построением, просмотром и печатью этого отчета. Дайте имя FRep вашей форме (свойство Name). По этому имени вы потом сможете ссылаться на ее компоненты. Проверьте, что свойство Visible этой формы установлено в false. Это необходимо сделать, так как форма в дальнейшем должна быть невидимой.
Окно диалога открытия графического файла
Когда вы в процессе проектирования загрузили изображение из файла в компонент Image, он не просто отображает его, но и сохраняет в приложении. Это дает вам возможность поставлять ваше приложение без отдельного графического файла. Впрочем, как мы увидим позднее, в Image можно загружать и внешние графические файлы в процессе выполнения приложения.
Вернемся к рассмотрению свойств компонента Image.
Если установить свойство AutoSize в true, то размер компонента Image будет автоматически подгоняться под размер помещенной в него картинки. Если же свойство AutoSize установлено в false, то изображение может не поместиться в компонент или, наоборот, площадь компонента может оказаться много больше площади изображения.
Другое свойство — Stretch позволяет подгонять не компонент под размер рисунка, а рисунок под размер компонента. Установите AutoSize в false, растяните или сожмите размер компонента Image и установите Stretch в true. Вы увидите, что рисунок займет всю площадь компонента, но поскольку вряд ли реально установить размеры Image точно пропорциональными размеру рисунка, то изображение исказится. Устанавливать Stretch в true может иметь смысл только для каких-то узоров, но не для картинок. Свойство Stretch не действует на изображения пиктограмм, которые не могут изменять своих размеров.
Свойство — Center, установленное в true, центрирует изображение на площади Image, если размер компонента больше размера рисунка.
Рассмотрим еще одно свойство — Transparent (прозрачность). Если Transparent равно true, то изображение в Image становится прозрачным. Это можно использовать для наложения изображений друг на друга. Поместите на форму второй компонент Image и загрузите в него другую картинку. Только постарайтесь взять какую-нибудь мало заполненную, контурную картинку. Можете, например, взять картинку из числа помещаемых обычно на кнопки, например, стрелку (файл ...\program files\common files\borland shared\images\buttons\arrow1l.bmp). Передвиньте ваши Image так, чтобы они перекрывали друг друга, и в верхнем компоненте установите Transparent равным true. Вы увидите, что верхняя картинка перестала заслонять нижнюю. Одно из возможных применений этого свойства — наложение на картинку надписей, выполненных в виде битовой матрицы. Эти надписи можно сделать с помощью встроенной в Delphi программы Image Editor.
Учтите, что свойство Transparent действует только на битовые матрицы. При этом прозрачным (т.е. заменяемым на цвет расположенного под ним изображения) делается по умолчанию цвет левого нижнего пикселя битовой матрицы.
Мы рассмотрели загрузку изображения из файла в процессе проектирования. Но свойство Picture позволяет также легко организовать обмен с графическими файлами любых типов в процессе выполнения приложения. Чтоб пояснить технику такого обмена, надо сначала подробнее рассмотреть свойство Picture.
Это свойство является объектом, который имеет в свою очередь подсвойства, указывающие на хранящийся графический объект. Если в Picture хранится битовая матрица, на нее указывает свойство Picture.Bitmap. Если хранится пиктограмма, на нее указывает свойство Picture.Icon. На хранящийся метафайл указывает свойство Picture.Metafile. Наконец, на графический объект произвольного типа указывает свойство Picture.Graphic.
Объект Picture и его свойства Bitmap, Icon, Metafile и Graphic имеют методы файлового чтения и записи LoadFromFile и SaveToFile: procedure LoadFromFile(const FileName: string); procedure SaveToFile(const FileName: string);
Для свойств Picture.Bitmap, Picture.Icon и Picture.Metafile формат файла должен соответствовать классу объекта: битовой матрице, пиктограмме, метафайлу. При чтении файла в свойство Picture.Graphiс файл должен иметь формат метафайла. А для самого объекта Picture методы чтения и записи автоматически подстраиваются под тип файла. Поясним это на примере.
Давайте построим приложение, аналогичное рассмотренному в разделе 4.2 примеру просмотра графических файлов. Для разнообразия можно организовать управление им не кнопкой Button, а меню. Поместите на форму компонент Image. Растяните его или задайте его свойство Align равным alClient, чтобы он занял всю клиентскую область формы. Перенесите на форму компонент диалога открытия графического файла OpenPictureDialog (см. ). Поместите также на форму компонент главного меню MainMenu (см. ) и задайте в нем один раздел — Файл. В обработчике этого раздела напишите оператор if(OpenPictureDialog1.Execute) then Image1.Picture.LoadFromFile( OpenPictureDialog1.FileName);
Этот оператор вызовет диалог открытия графического файла (см. Рисунок 4.4) и загрузит в компонент Image1 изображение из выбранного пользователем файла (см. Рисунок 4.5). Причем файл может быть любого типа: битовая матрица, пиктограмма или метафайл.
Окно формы, управляющей подготовкой отчета
Теперь осталось связать друг с другом две формы и написать небольшие команды управления. Перейдите в модуль формы отчета URep и в его разделе implementation напишите оператор uses URep1; Этот оператор позволит ссылаться из модуля отчета на компоненты главной формы. Перейдите в модуль главной формы URep1 и в его разделе implementation напишите оператор uses URep; Этот оператор позволит ссылаться из модуля главной формы на компоненты модуля отчета. В компоненте QRRichText формы URep раскройте выпадающий список в свойстве ParentRichEdit. В этом списке должна появится ссылка на компонент RichEdit формы Form1. Установите это свойство, чтобы связать окна редактирования друг с другом. В обработчик события OnClick кнопки на форме Form1 внесите оператор FRep.QRLTitle.Caption := Edit1.Text; Он обеспечит пересылку в метку заголовка отчета QRLTitle текста, который пользователь ввел в окно Edit1. В обработку команды меню Шрифт вставьте операторы if FontDialog1.Execute then RichEdit1.SelAttributes.Assign(FontDialog1.Font); RichEdit1.SetFocus; Эти операторы, обеспечивающие форматирование в окне RichEdit1, уже рассматривались в . В обработку команды меню Просмотр вставьте оператор FRep.QuickRep1.Preview;
Приложение закончено. Запустите его на выполнение. Отформатируйте текст в окне (см. пример на Рисунок 4.18). Выполните команду Просмотр. Вы увидите окно предварительного просмотpa, показанное на Рисунок 4.19.
Окно Picture Editor
Чтобы познакомиться с этим свойством откройте новое приложение и перенесите на форму компонент Image. Растяните его или задайте его свойство Align равным alClient, чтобы он занял всю клиентскую область формы. Нажмите на кнопку с многоточием около свойства Picture в окне Инспектора Объектов или просто сделайте двойной щелчок на Image. Перед вами откроется окно Picture Editor (Рисунок 4.3), позволяющее загрузить в свойство Picture какой-нибудь графический файл (кнопка Load), а также сохранить открытый файл под новым именем или в новом каталоге. Щелкните на Load, чтобы загрузить графический файл. Перед вами откроется окно открытия графического файла, представленное на Рисунок 4.4. По мере перемещения курсора в списке по графическим файлам в правом окне отображаются содержащиеся в них картинки, а над ними — цифры, характеризующие размер картинки. Вы можете выбрать требуемый вам графический файл любого типа. Напомним, что поставляемые с Delphi графические файлы вы можете найти в каталоге Images. В Delphi 5 и 4 он обычно расположен в каталоге ...\program files\Common Files\Borland Shared. В Delphi 3 он расположен в каталоге ...\program files\Borland\Delphi 3, а в Delphi 1 — в каталоге Delphi 16. После загрузки файла щелкните на OK в окне Picture Editor и в вашем компоненте Image отобразится выбранная вами картинка. Можете запустить ваше приложение и полюбоваться ею. Впрочем, вы и так видите картинку, даже не выполняя приложение.
Окно задания свойств компонента Chartfx: страницы Data Values (а) и Шрифты (б)
а) |
б) | Теперь давайте коротко рассмотрим некоторые кнопки инструментальной панели компонента во время выполнения приложения (см. Рисунок 4.12). Первая и вторая слева быстрые кнопки обеспечивают соответственно чтение и сохранение диаграммы. Диаграмма сохраняется в файле с расширением .chf и может быть прочитана в последующих сеансах работы. Третья кнопка слева заносит диаграмму в буфер обмена Clipboard, откуда ее можно взять в каком-то другом приложении (например, в Word) и вставить в документ. Кнопки в центральной части панели позволяют изменять тип диаграммы или графика. Поэкспериментируйте с ними и вы легко поймете, что они означают. Вторая справа группа кнопок позволяет вводить на диаграмме или графике координатную сетку. Правая группа кнопок обеспечивает задание надписей на изображении, выбор шрифта надписей и т.п. Главной из этих кнопок является вторая справа. Она вызывает выпадающее меню, содержащее, в частности, раздел Data Editor. Если вы выберете этот раздел, вместо диаграммы вы увидите окно редактора данных, отображаемых на графике или в диаграмме (см. Рисунок 4.14). Сделав двойной щелчок на том или ином числе, вы можете изменить его. После того, как вы отредактировали данные, опять щелкните на второй справа кнопке инструментальной панели и снимите выделение с раздела Data Editor. Вы опять увидите диаграмму, отображающую введенные вами данные. |
Отображение графики на канве Canvas
Канва Canvas не является компонентом, так что, строго говоря, она не должна бы рассматриваться в рамках данной книги. Но поскольку многие компоненты, в частности, формы, имеют канву и канва предоставляет возможность выводить различную графическую информацию, то некоторые начальные сведения о канве все-таки целесообразно дать.
Канва представляет собой область компонента, на которой можно рисовать или отображать готовые изображения. Она содержит свойства и методы, существенно упрощающие графику Delphi. Все сложные взаимодействия с системой спрятаны для пользователя, так что рисовать в Delphi может человек, совершенно не искушенный в машинной графике.
Каждая точка канвы имеет координаты X и Y. Система координат канвы, как и везде в Delphi, имеет началом левый верхний угол канвы. Координата X возрастает при перемещении слева направо, а координата Y — при перемещении сверху вниз. Координаты измеряются в пикселях. Пиксель — это наименьший элемент поверхности рисунка, с которым можно манипулировать. Важнейшее свойство пикселя — его цвет.
Канва имеет свойство Pixels. Это свойство представляет собой двумерный массив, который отвечает за цвета канвы. Например, Canvas.Pixels[10,20] соответствует цвету пикселя, 10-го слева и 20-го сверху. С массивом пикселей можно обращаться как с любым свойством: изменять цвет, задавая пикселю новое значение, или определять его цвет по хранящемуся в нем значению. Например, Canvas.Pixels[10,20] := 0 или Canvas.Pixels[10,20] := clBlack — это задание пикселю черного цвета.
Свойство Pixels можно использовать для рисования на канве. Давайте попробуем нарисовать по пикселям график синусоиды на канве формы. Для этого в обработчик события формы OnPaint (прорисовка) можно вставить следующий код: procedure TForm1.FormPaint(Sender: TObject); var X,Y: real; // координаты функции PX,PY: longint; // координаты пикселей begin Color := clWhite; for PX := 0 to ClientWidth do begin {X — аргумент графика, соответствующий пикселю с координатой РХ} X := PX*4*Pi/ClientWidth; Y:=Sin(X); {PY — координата пикселя, соответствующая координате Y} PY:=trunc(ClientHeight - (Y+1)*ClientHeight/2); {Устанавливается черный цвет выбранного пикселя (О яркости)} Canvas.Pixels [PX, PY] := 0; end; end;
Выполните это тестовое приложение и вы увидите результат, представленный на Рисунок 4.1 а. График синусоиды получился, хотя и не очень хороший, т.к. разбивается на отдельные точки — пиксели.
Отображение хода выполнения длительных операций — компоненты ProgressBar и Gauge
Рассмотрим компоненты ProgressBar со страницы библиотеки Win32 и Gauge со страницы Samples, предназначенные для отображения в стиле Windows 95/98 хода процессов, занимающих заметное время, например, копирования больших файлов, настройку приложения, установку приложения на компьютере и т.п. Пример возможных вариантов отображения хода процесса компонентами ProgressBar и Gauge приведен на Рисунок 4.20.
Панель компонента MediaPlayer
Назначение кнопок (перечисляются слева направо):
Каждой кнопке медиа-плеера соответствует метод, осуществляющий по умолчанию требуемую операцию: Play, Pause, Stop, Next, Previous, Step, Back, StartRecording, Eject.
Тип устройства мультимедиа, с которым работает медиа-плеер, определяется его свойством DeviceType. Если устройство мультимедиа хранит объект воспроизведения в файле, то имя файла задается свойством FileName. По умолчанию свойство DeviceType имеет значение dtAutoSelect. Это означает, что медиа-плеер пытается определить тип устройства исходя из расширения имени файла FileName.
Еще одно свойство MediaPlayer — AutoOpen. Если оно установлено в true, то медиа-плеер пытается открыть устройство, указанное свойством DeviceType, автоматически во время своего создания в процессе выполнения приложения.
Воспроизведение видео информации по умолчанию производится в окно, которое создает само открытое устройство мультимедиа. Однако это можно изменить, если в свойстве Display указать оконный элемент, в котором должно отображаться изображение. Это может быть, например, форма или панель. Можно также задать в свойстве DisplayRect типа TRect (свойство только времени выполнения) прямоугольную область этого окна, в которую должно выводиться изображение. Для задания свойства DisplayRect можно использовать функцию Rect. Однако, в данном свойстве использование типа TRect не совсем обычно. Первые две координаты, как и обычно, задают положение левого верхнего угла изображения. А два следующих числа задают ширину и высоту изображения, а не координаты правого нижнего угла. Например, оператор MediaPlayer1.DisplayRect := Rect(10, 10, 200, 200); задает для вывода область с координатами левого верхнего угла (10, 10), длиной и шириной, равными 200.
В компоненте MediaPlayer определены события OnClick и OnNotify. Первое из них происходит при выборе пользователем одной из кнопок медиа-плеера и определено как type TMPBtnType=(btPlay, btPause, btStop, btNext, btPrev, btStep, btBack, btRecord, btEject); procedure(Sender: TObject; Button:TMPBtnType; var DoDefault: Boolean);
Параметр Button указывает выбранную кнопку. Параметр DoDefault, передаваемый как var, определяет выполнение (при значении true по умолчанию) или отказ от выполнения стандартного метода, соответствующего выбранной кнопке.
Событие OnNotify происходит после возвращения очередного метода, если свойство медиа-плеера Notify было установлено в true. Способ возврата любого метода медиа-плеера определяется свойством Wait. Если установить Wait равным false, то возвращение управления в приложение происходит сразу после вызова метода, не дожидаясь завершения его выполнения. Таким образом, задав Notify равным true и Wait равным false, можно обеспечить немедленный возврат в приложение и отображение пользователю текущего состояния объекта мультимедиа.
Свойства Notify и Wait действуют только на один очередной метод. Поэтому их значения надо каждый раз восстанавливать в обработчиках событий OnClick или OnNotify.
В обработчиках событий можно читать свойство Mode, характеризующее текущее состояние устройства мультимедиа. Можно также читать и устанавливать ряд свойств, характеризующих размер воспроизводимого файла и текущую позицию в нем.
Вот, собственно, в конспективном виде основная информация о компоненте MediaPlayer. А теперь попробуйте все это на практике. Простое и в то же время мощное приложение можно сделать очень легко. Начните новый проект и перенесите на форму компоненты MediaPlayer, MainMenu и OpenDialog. В фильтре компонента OpenDialog можно, например, задать:
В меню достаточно задать одну команду: Файл | Открыть. Обработчик события OnClick этой команды может содержать оператор if OpenDialog1.Execute then with MediaPlayer1 do begin FileName := OpenDialog1.FileName; Open; end; который открывает устройство мультимедиа, соответствующее выбранному пользователем файлу. При этом надо проследить, чтобы в компоненте MediaPlayer свойство DeviceType равнялось dtAutoSelect. Это обеспечит автоматический выбор соответствующего устройства мультимедиа исходя из расширения выбранного файла.
В компоненте MediaPlayer при желании можно указать имя файла FileName, открываемого в момент начала выполнения приложения. Тогда надо установить свойство AutoOpen в true. Впрочем, это, конечно, не обязательно.
Вот и все. Можете выполнять свое приложение и наслаждаться музыкой или фильмами (если, конечно, все вопросы, связанные с настройкой мультимедиа на вашем компьютере решены).
Чтобы все-таки использовать какие-то события компонента MediaPlayer, давайте немного усложним приложение. Введем в него три метки (Рисунок 4.24), в которых будем отображать имя воспроизводимого файла, состояние открытого устройства мультимедиа и последнюю вызванную операцию.
Печать с помощью объекта Printer
В Delphi имеется класс печатающих объектов TPrinter, который обеспечивает печать текстов, изображений и других объектов, расположенных на его канве — Canvas (см. разделы и ). На канве объекта типа TPrinter могут размещаться и тексты, и изображения.
Модуль Delphi, именуемый Printers, содержит переменную Printer, являющуюся объектом типа TPrinter. Эта переменная эквивалентна невизуальному компоненту, только отсутствующему в палитре библиотеки. Чтобы использовать Printer, надо добавить модуль Printers в оператор uses вашей программы. Автоматически он не добавляется.
Рассмотрим некоторые свойства и методы объекта типа TPrinter.
Свойство, метод | Описание |
Canvas | Канва Canvas — место в памяти, в котором формируется страница или документ перед печатью. Canvas обладает рядом свойств, включая Pen (перо) и Brush (кисть), которые позволяют вам делать рисунки и помещать на них текст. Подробное описание канвы и методов работы с ней вы найдете в . |
TextOut | Метод канвы, который позволяет посылать в нее текст (см. ). |
BeginDoc | Используется для начала задания печати. |
EndDoc | Используется для окончания задания печати. Фактическая печать происходит только при вызове EndDoc. |
PageHeight | Возвращает высоту страницы в пикселях. |
NewPage | Принудительно начинает новую страницу на принтере. |
PageNumber | Возвращает текущий номер печатаемой страницы. |
Предположим, вы хотите напечатать текст, используя печатающий объект. Вы можете написать код вида: Printer.BeginDoc; Printer.Canvas.ТехtOut(10, 10, 'Я печатаю через объект Printer'); Printer.EndDoc;
Этот код вызывает печать на канве принтера текста «Я печaтаю через объект Printer», начиная с десятого пикселя слева и десятого сверху. BeginDoc запускает задание на печать. Текст посылается на канву с помощью метода TextOut объекта Canvas. Метод EndDoc вызывает печать текста и останавливает задание на печать.
Если вы хотите напечатать изображение, хранящееся в компоненте Image1 (см. ), это можно сделать операторами: Printer.BeginDoc; with Image1.Picture.BitMap do Printer.Canvas.CopyRect(Rect(0, 0, Height, Width), Canvas, Rect(0, 0, Height, Width)); Printer.EndDoc;
При печати текста объект Printer не производит автоматического переноса строк и разбиения текста на страницы. Поэтому печать длинных текстов с помощью объекта Printer требует достаточно сложного программирования. Проще это делать, например, загрузкой текста в компонент RichEdit (см. ) и выполнением его метода Print (см. ). Другой возможный вариант — использование описанной в следующем разделе системы QuickReport.
Перечень компонентов отображения графической информации
Для отображения графической информации в библиотеке Delphi предусмотрены компоненты, список которых дан в таблице 4.1.
Пикто- грамма | Компонент | Страница | Описание |
Image (изображение) | Additional | Используется для отображения графики: пиктограмм, битовых матриц и метафайлов. | |
PaintBox (окно для рисования) | System | Используется для создания на форме некоторой области, в которой можно рисовать. | |
DrawGrid (таблица рисунков) | Additional | Используется для отображения в строках и столбцах нетекстовых данных. | |
Chart (диаграммы и графики) | Additional | Компонент принадлежит к семейству компонентов TChart, которые используются для создания диаграмм и графиков. |
Кроме того, отображать и вводить графическую информацию можно на поверхности любого оконного компонента, имеющего свойство Canvas — канва.
Подготовка и печать отчетов с
На странице QReport палитры компонентов Delphi имеется множество элементов (см. таблицу 4.2), предназначенных для подготовки и печати отчетов с помощью системы QuickReport.
Пикто- грамма | Компонент | Описание |
QuickRep (отчет) | Используется для введения в приложение средств печати отчетов QuickReport | |
QRSubDetail (детали) | Используется для компоновки в отчет дополнительных данных | |
QRStringsBand (полоса текста) | Используется для компоновки в отчет дополнительных текстов | |
QRBand (полоса) | Используется для построения отчетов путем размещения на нем печатаемых компонентов | |
QRChildBand (дочерняя полоса) | Используется для создания дочерних полос, которые могут содержать другие компоненты QuickRep и полосы | |
QRGroup (группировка) | Используется для группировки данных | |
QRLabel (метка) | Используется для размещения текста в отчете | |
QRDBText (текст из базы данных) | Представляет собой ориентированный на данные компонент для размещения текста в отчете | |
QRExpr (математические выражения) | Позволяет вам строить и отображать выражения над полями данных и системными величинами (такими, как время и дата). Свойство Expression компонента включает диалоговое окно Построителя Выражений (Expression Builder), дающее возможность графического построения выражений | |
QRSysData (системные данные) | Используется для отображения системных данных | |
QRMemo (многострочный текст) | Используется для размещения в отчете многострочных текстов | |
QRExprMemo (тексты с математическими выражениями) | Используется для размещения в отчете текстов с математическими выражениями | |
QRRichText (многострочный текст RTF) | Используется для размещения в отчете текста в обогащенном формате | |
QRDBRichText (многострочный текст RTF базы данных) | Используется для размещения в отчете текста из базы данных в обогащенном формате | |
QRShape (форма) | Используется для рисования в отчете графических форм | |
QRImage (изображение) | Используется для печати изображений в отчете | |
QRDBImage (изображение из базы данных) | Используется для печати изображений из баз данных в отчете | |
QRCompositeReport (составной отчет) | Используется для построения составных отчетов | |
QRPreview (предварительный просмотр) | Используется для предварительного просмотра на экране подготовленного к печати отчета | |
QRTextFilter (фильтр текста) | Используется для установки фильтра текста | |
QRCSVFilter (разделитель) | Используется для установки разделителя текста | |
QRHTMLFilter (фильтр HTML) | Используется для установки фильтра HTML | |
QRChart (диаграммы, графики) | Используется для печати в отчете диаграмм, построенных на основе баз данных |
В данном разделе мы коротко рассмотрим принципы создания отчетов с помощью QuickReport. Конечно, рассмотреть в деталях все компоненты QuickReport невозможно — это потребовало бы отвести под эту тему целую главу, а, возможно, и несколько. К тому же отчеты обычно строятся для того, чтобы распечатывать информацию из баз данных. А рассмотрение компонентов, связанных с данными, выходит за рамки данной книги. Поэтому ограничимся только самыми общими принципами построения отчетов, не связанных с базами данных.
QuickReport — это система, позволяющая визуально проектировать отчеты и связывать их с кодом приложения. QuickReport генерирует отчеты, представляемые в виде полос различных типов. Именно для размещения в отчете полос предназначены такие компоненты, как QRSubDetail, QRStringsBand, QRBand, QRChildBand, QRGroup. Однако, понятие полосы тесно связано с отображением информации из баз данных. С этим же связаны такие компоненты, как QRDBTest, QRDBRichText, QRDBImage. Все они в совокупности позволяют строить отчеты, в которых автоматически просматриваются базы данных и отображается их текущее состояние. Но в данном разделе мы сосредоточимся на основном компоненте QuickRep и на компонентах, не связанных с данными. При этом можно строить только простые отчеты, содержащие тексты и рисунки, как показано на Рисунок 4.16.
Предварительный просмотр отчета
В этом окне вы можете просматривать отчет, изменяя размер изображения, переходить со страницы на страницу (ваш отчет имеет всего одну страницу, так что переходы в нем невозможны), сохранять отчет в файле, проводить установку принтера, печатать отчет, сохранять его в файле, чтобы в каких-то будущих сеансах можно было загрузить его опять из файла. Словом, возможностей много. Опробуйте их все.
Приложение на основе компонента Chartfx
Как и в других компонентах ActiveX, доступ к свойствам Chartfx во время проектирования может осуществляться с помощью Инспектора Объектов или щелчком правой кнопки мыши и выбором из всплывшего меню команды Properties (Свойства). При выборе этой команды вы попадете в многостраничное диалоговое окно (см. Рисунок 4.13), позволяющее задать свойства компонента. Остановимся только на нескольких из них, которые вы можете задавать в этом диалоге, в Инспекторе Объектов или программно.
Свойство Series на странице Data Values (Рисунок 4.13 а) диалога (в Инспекторе Объектов это свойство названо NSeries) обозначает число серий данных (на Рисунок 4.12 равно 2). Свойство Points на той же странице диалога (в Инспекторе Объектов оно названо NValues) обозначает число значений по оси аргументов (на Рисунок 4.12 равно 4). Страница диалога Elements позволяет задать какие-то характерные уровни (опции Value — Text, на Рисунок 4.12 отмечен уровень 40 с текстом «Минимально допустимый запас»), выделить цветом какие-то полосы уровней (опции From — То — Color, на Рисунок 4.12 выделены полосы 0 — 20 и 20 — 40), задать текст в строке состояния (опции ID — Width — Text). Прочие свойства позволяют задать тексты вверху диаграммы, внизу, слева, справа, задать координатные сетки и многое другое. Следует обратить внимание на выбор шрифтов на странице Шрифты (Рисунок 4.13 б). Шрифты, естественно, надо выбрать такие, которые содержат символы кириллицы. При выборе шрифтов надо сначала в выпадающем списке Свойство выбрать надпись, для которой указывается шрифт (например, TopFont — шрифт надписи над диаграммой), а затем в окнах Шрифт, Начертание, Размер установить атрибуты шрифта. Подобную процедуру надо повторить для всех надписей.
Приложение на основе компонента Graph
Во время выполнения приложения задать новые данные, отредактировать их, настроить график или диаграмму можно методом BrowseProperties. Например, оператор Graph1.BrowseProperties; вызовет то же многостраничное окно свойств, которое вы видите во время проектирования, выполняя команду Properties из всплывающего меню компонента. В этом окне можно задать или отредактировать всю отображаемую компонентом информацию. Изменять во время выполнения данные и способ их отображения можно также задавая значения свойствам компонента, большинство из которых вы можете видеть в процессе проектирования в окне Инспектора Объектов.
* В Delphi 5 компонент Graph отсутствует. По-видимому, автор писал большую часть книги для Delphi 4 а затем автоматически перенес текст под 5-ю версию. - Примечание разработчика электронной версии.
Приложение универсального проигрывателя при воспроизведении звукового файла
Код, обеспечивающий подобную обратную связь в приложении, может быть следующим. const ModeStr: array[TMPModes] of string = (' He готово', 'Остановлено', 'Воспроизведение', 'Запись', 'Поиск', 'Пауза', 'Открыто'); ButtonStr: array[TMPBtnType] of string = ('Воспроизведение', 'Пауза', 'Стоп', 'Следующий', 'Предыдущий', 'Вперед', 'Назад', 'Запись', 'Конец'); procedure TForm1.OpenClick(Sender: TObject); begin if OpenDialog1.Execute then with MediaPlayer1 do begin FileName := OpenDialog1.FileName; Label1.Caption := 'Файл: ' + FileName; Open; Notify:=true; end; end; procedure TForm1.MediaPlayer1Notifу(Sender: TObject); begin with MediaPlayer1 do begin Label2.Caption := 'Состояние: ' + ModeStr[Mode]; {Переустановка Notify, чтобы событие произошло в следующий раз} Notify := true; end; end; procedure TForm1.FormCreate (Sender: TObject); begin with MediaPlayer1 do begin Label1.Caption := 'Файл: ' + FileName; Label2.Caption := 'Состояние: ' + ModeStr[Mode]; Notify:=true; end; end; procedure TForm1.MediaPlayer1Click(Sender: TObject; Button: TMPBtnType; var DoDefault: Boolean); begin Label3.Caption := 'Операция: ' + ButtonStr[Button]; {Переустановка Notify, чтобы произошло событие OnNotify} MediaPlayer1.Notify := true; end;
Приложение универсального проигрывателя при воспроизведении видео файла
Запустите приложение и проверьте его в работе. На Рисунок 4.24 показана приложение в момент воспроизведения звукового файла. А на Рисунок 4.25 то же приложение воспроизводит видео файл. Причем, поскольку мы не определили окно и область вывода изображения, то проигрыватель сам создает соответствующее окно.
Пример отчета
Основным компонентом, на котором строится весь отчет, является QuickRep. Он предоставляет ряд возможностей по управлению создаваемым отчетом, включая формирование заголовка, полос, шрифтов, установок принтера и др. Этот компонент является визуальным и после его соединения с базой данных может использоваться как контейнер полос, составляющих отчет.
Компонент QuickRep имеет ряд свойств, определяющих характеристики печати отчета:
Перенесите на форму компонент QuickRep и посмотрите перечисленные и иные его свойства в Инспекторе Объектов. Одно из основных свойств — Bands. Оно имеет ряд подсвойств. Отметим из них следующие: HasTitle — имеется полоса заголовка отчета, HasDetail — имеется полоса детализации, HasPageHeader — имеется верхний колонтитул (заголовок) на каждой странице отчета, HasPageFooter — имеется нижний колонтитул на каждой странице отчета. Для дальнейшего рассмотрения компонентов установите в true свойство HasDetail. На компоненте QuickRep появится слабо видимая полоса с надписью «Detail». На этой полосе, увеличив при необходимости ее размеры, можно размещать компоненты, которые отображают ту или иную информацию: QRLabel, QRExpr, QRSysData, QRMemo, QRRichText, QRShape, QRImage.
Компонент QuickRep имеет два основных метода: Preview — предварительный просмотр, и Print — печать. Предварительный просмотр и даже печать отчета можно осуществлять и в процессе проектирования. Для этого надо щелкнуть правой кнопкой мыши на компоненте QuickRep и из всплывшего меню выбрать команду Preview. Перед вами откроется окно предварительного просмотра, в котором, в частности, имеется кнопка печати.
Компоненты QRLabel, QRMemo, QRRichText, QRShape, QRImage, размещаемые на полосах отчета, являются аналогами обычных компонентов — Label, Memo, RichEdit, Shape, Image, которые уже рассматривались ранее. Основной особенностью соответствующих компонентов QuickReport является их способность печататься в тех полосах отчета, в которых они размещены. Компоненты имеют два свойства, отсутствующих в обычных компонентах: Frame и Size.
Свойство Frame имеет ряд подсвойств, определяющих рамку вокруг компонента: Color — цвет, Style — стиль, Width — ширина, DrawBottom, DrawLeft, DrawRight, DrawTop — определяют наличие рамки соответственно внизу, слева, справа и вверху компонента.
Свойство Size имеет подсвойства, определяющие размер и место размещения компонента при печати. Все определяется в единицах измерения, заданных свойством Units компонента QuickRep.
Некоторые компоненты имеют свойство AlignToBand — выравнивание в полосе. Если это свойство установить в true, то компонент будет выровнен по краю полосы, заданному свойством Alignment: taLeftJustify — влево, taCenter — по центру, taRightJustify — вправо.
Остановимся теперь на свойствах отдельных компонентов. Интересное свойство имеет компонент QRRichText — ParentRichEdit. Это свойство указывает на обычный компонент RichEdit, текст из которого автоматически передается в компонент QRRichText. Вы можете, например, ввести в свое приложение компонент RichEdit и предоставить пользователю возможность вводить в него нужный текст, форматируя соответствующим образом слова и абзацы. Этот текст будет автоматически переноситься в отчет — в размещенный в нем компонент QRRichText. Впрочем, и в другие компоненты QuickReport можно программно заносить тексты и изображения, задаваемые пользователем. Например, вы можете ввести в свое приложение компонент Edit и предоставить пользователю возможность вводить в него нужный текст. А перед предварительным просмотром или печатью отчета вы можете перенести этот текст, например, в метку QRLabel, оператором QRLabel1.Caption:=Edit1.Text;
Компонент QRExpr позволяет отображать в отчете результаты каких-то вычислений. Основное свойство этого компонента — Expression. Нажав на кнопку с многоточием около этого свойства в Инспекторе Объектов, вы попадете в окно, представленное на Рисунок 4.17 а. В этом окне вы можете ввести выражение, результаты которого должны отображаться в отчете на месте расположения компонента QRExpr. Элементами выражения могут быть поля базы данных (Database field), такие переменные (Variable), как текущее время, дата, номер страницы и др., функции (Function). Кнопка Validate позволяет вам проверить синтаксическую правильность введенного выражения и посмотреть результат вычисления. Поэкспериментируйте с этим компонентом и вы легко поймете принципы работы с ним.
Пусть, например, вы хотите отобразить текущую дату, включая месяц и год, но не включая числа. Обычно дата отображается в формате «дд.мм.гг». Значит вам надо убрать из этого формата первые три символа, отображающие день. Это можно сделать с помощью функции копирования фрагмента строки COPY(DATE, 4, 5), в которой первый аргумент указывает строку, второй — индекс первого копируемого символа, третий — число копируемых символов. В приведенном примере DATE — функция, возвращающая текущую дату в виде строки.
Пример отображения хода процесса компонентами ProgressВar и Gauge
Основные свойства этих компонентов очень схожи, различаясь только именами:
Отображение хода процесса можно осуществлять, задавая значение позиции — Position в ProgressBar или Progress в Gauge. Например, если полная длительность процесса характеризуется значением целой переменной Count (объем всех копируемых файлов, число настроек, количество циклов какого-то процесса), а выполненная часть — целой переменной Current, то задавать позицию диаграммы в случае, если используются значения минимальной и максимальной позиции по умолчанию (т.е. 0 и 100), можно операторами ProgressBar1.Position := 100 * Current div Count; или Gauge1.Progress := 100 * Current div Count; соответственно для ProgressBar и Gauge.
Можно поступать иначе: задать сначала значение максимальной величины равным Count, а затем в ходе процесса задавать позицию равной Current. Например: Gauge1.MaxValue := Count; Gauge1.Progress := Current;
Компонент ProgressBar имеет два метода, которыми тоже можно воспользоваться для отображения процесса: StepBy(Delta: Integer) — увеличение позиции на заданную величину Delta и StepIt — увеличение позиции на один шаг, величина которого задается свойством Step.
Пример приложения с диаграммами
Компонент Chart является контейнером объектов Series типа TChartSeries — серий данных, характеризующихся различными стилями отображения. Каждый компонент может включать несколько серий. Если вы хотите отображать график, то каждая серия будет соответствовать одной кривой на графике. Если вы хотите отображать диаграммы, то для некоторых видов диаграмм можно наложить друг на друга несколько различных серий, для других (например, для круговых диаграмм) это, вероятно, будет выглядеть некрасиво. Однако, и в этом случае вы можете задать для одного компонента Chart несколько серий одинаковых данных с разным типом диаграммы. Тогда, делая в каждый момент времени активной одну из них, вы можете предоставить пользователю выбор типа диаграммы, отображающей интересующие его данные.
Разместите один или два (если захотите воспроизвести Рисунок 4.8) компонента Chart на форме и посмотрите открывшиеся в Инспекторе Объектов свойства. Приведем пояснения некоторых из них.
Рядом со многими из перечисленных свойств в Инспекторе Объектов расположены кнопки с многоточием, которые позволяют вызвать ту или иную страницу Редактора Диаграмм — многостраничного окна, позволяющего установить все свойства диаграмм. Вызов Редактора Диаграмм возможен также двойным щелчком на компоненте Chart или щелчком на нем правой кнопкой мыши и выбором команды Edit Chart во всплывшем меню.
Если вы хотите попробовать воспроизвести приложение, показанное на Рисунок 4.8, сделайте двойной щелчок на верхнем компоненте Chart. Вы попадете в окно Редактора Диаграмм (Рисунок 4.9) на страницу Chart, которая имеет несколько закладок. Прежде всего вас будет интересовать на ней закладка Series. Щелкните на кнопке Add — добавить серию. Вы попадете в окно (Рисунок 4.10), в котором вы можете выбрать тип диаграммы или графика. В данном случае выберите Pie — круговую диаграмму. Воспользовавшись закладкой Titles вы можете задать заголовок диаграммы, закладка Legend позволяет задать параметры отображения легенды диаграммы (списка обозначений) или вообще убрать ее с экрана, закладка Panel определяет вид панели, на которой отображается диаграмма, закладка 3D дает вам возможность изменить внешний вид вашей диаграммы: наклон, сдвиг, толщину и т.д.
Когда вы работаете с Редактором Диаграмм и выбрали тип диаграммы, в компонентах Chart на вашей форме отображается ее вид с занесенными в нее условными данными (см. Рисунок 4.11).
Пример таблицы DrawGrid
Рассмотрим свойства компонентов DrawGrid и StringGrid, относящиеся к изображениям, поскольку свойства StringGrid, относящиеся к тексту, уже рассматривались в разделе 3.3.6.
Компоненты DrawGrid и StringGrid имеют канву Canvas, на которой можно размещать изображения методами, изложенными в . Имеется метод CellRect, который возвращает область канвы, отведенную под заданную ячейку. Этот метод определен как function CellRect (ACol, ARow: Longint): TRect; где ACol и ARow — индексы столбца и строка, начинающиеся с 0, на пересечении которых расположена ячейка. Возвращаемая этой функцией область является областью канвы, в которой можно рисовать необходимое изображение. Например, оператор DrawGrid1.Canvas.CopyRect(DrawGrid1.CellRect(1, 1), BitMap.Canvas, Rect(0, 0, BitMap.Height, BitMap.Width)); копирует методом CopyRect (см. ) в ячейку (1, 1) таблицы DrawGrid1 изображение из компонента BitMap. Эта ячейка является второй слева и второй сверху в таблице, поскольку индексы начинаются с 0. Учтите, что если размеры ячейки меньше, чем размер копируемого изображения, то в ячейке появится только левая верхняя часть картинки.
Изображение на канве компонентов DrawGrid и StringGrid, как и на канве любого компонента, подвержено стиранию при перекрытии окна приложения другими окнами или, например, при сворачивании приложения. Поэтому необходимо принимать меры, описанные в , чтобы с помощью обработчика событий OnPaint восстанавливать испорченное изображение. Это делает компонент DrawGrid не слишком удобным для использования.
Все свойства и события, позволяющие определить выбранную пользователем ячейку таблицы, были рассмотрены в . Там же вы найдете описание свойств, отвечающих за внешний вид и допустимость перестройки пользователем таблицы во время выполнения приложения.
Примеры компонента Shape
Другое существенное свойство компонента — Brush (кисть). Это свойство является объектом типа TBrush, имеющим ряд подсвойств, в частности: цвет (Brush.Color) и стиль (Brush.Style) заливки фигуры. Заливку при некоторых значениях Style вы можете видеть на Рисунок 4.7. Третье из специфических свойство компонента Shape — Pen (перо), определяющее стиль линий. Это свойство, как и свойство Brush, уже рассматривались в . Справочные данные об этих свойствах вы можете найти в главе 10*.
* В книге нет главы 10. Вероятно, автор планировал поместить в этой главе справочные материалы по рассмотренным в книге объектам Дельфи. - Примечание разработчика электронной версии.
Редактор отображаемых данных
Более простым, но, возможно, более полезным на странице библиотеки ActiveX является компонент Graph* (Рисунок 4.15). Он позволяет отображать данные в виде диаграмм различных типов. Настройку можно проводить так же, как и в других компонентах ActiveX, или в Инспекторе Объектов, или командой Properties из меню, всплывающего при щелчке правой кнопкой мыши на компоненте. В многостраничном диалоговом окне, всплывающем при выполнении этой команды, на странице Graph можно выбрать тип диаграммы или графика (опция GraphType) и число точек аргумента (NumPoints). На странице Data можно задать данные: GraphData — значения функции в различных точках, XPosData — значения аргументов в этих точках, ColorData — значения цветов в точках (для диаграмм). Остальные опции достаточно похожи на те, которые рассматривались для предыдущих компонентов.
Таблицы изображений — компоненты DrawGrid и StringGrid
Компонент DrawGrid используется для создания в приложении таблицы, которая может содержать графические изображения (см. пример на Рисунок 4.6). Этот компонент подобен компоненту StringGrid (см. ), поскольку последний является производным от DrawGrid. Поэтому в DrawGrid присутствуют все свойства, методы, события компонента StringGrid, кроме относящихся к тексту, т.е. кроме свойств Cells, Cols, Rows, Objects. С этой точки зрения компонент StringGrid обладает существенно большими возможностями, чем DrawGrid, поскольку он может хранить в ячейках и изображения, и тексты. А если вы захотите внести текст в какие-то ячейки DrawGrid, то вам надо будет использовать для этого методы вывода текста на канву (см. ), что не очень удобно.
Универсальный проигрыватель MediaPlayer
В Delphi (начиная с Delphi 2) имеется компонент MediaPlayer — универсальный проигрыватель аудио- и видео-информации. Этот медиа-плеер расположен на странице System библиотеки компонентов.
Компонент можно использовать в двух режимах. Во-первых, можно предоставить пользователю возможность управлять воспроизведением информации с помощью кнопочного интерфейса, напоминающего панель управления различными проигрывателями. Во-вторых, можно сделать сам компонент невидимым и управлять воспроизведением информации с помощью его методов.
Пользовательский интерфейс медиа-плеера представлен на Рисунок 4.23. Он имеет ряд кнопок, управляемых мышью или клавишей пробела и клавишами со стрелками.
Воспроизведение немых видео клипов — компонент Animate
Теперь рассмотрим способ воспроизведения в приложении Delphi стандартных мультипликаций Windows и файлов .avi — клипов без звукового сопровождения. Это позволяет сделать компонент Animate, расположенный на странице Win32 библиотеки.
Компонент Animate позволяет воспроизводить на форме стандартные видео клипы Windows (типа копирования файлов, поиска файлов и т.п.) и немые видео файлы .avi — Audio Video Interleaved. Эти файлы представляют собой последовательность кадров битовых матриц. Они могут содержать и звуковую дорожку, но компонент Animate воспроизводит только немые клипы AVI.
Откройте новое приложение, перенесите на форму компонент Animate и познакомьтесь с ним.
Воспроизводимое им изображение задается одним из двух свойств: FileName или CommonAVI. Первое из этих свойств, как ясно из его названия, позволяет в процессе проектирования или программно задать имя воспроизводимого файла. А свойство CommonAVI позволяет воспроизводить стандартные мультипликации Windows. Это свойство объявлено следующим образом: type TCommonAVI = (aviNone, aviFindFolder, aviFindFile, aviFindComputer, aviCopyFiles, aviCopyFile, aviRecycleFlle, aviEmptyRecycle, aviDeleteFile); property CommonAVI: TCommonAVI;
Тип TCommonAVI определяет множество предопределенных в Windows мультипликаций типа копирования файлов, поиска файлов, удаления файлов и т.п. Что означает каждое значение вы увидите из тестового приложения, которое построите чуть позже.
А пока установите значение CommonAVI, например, равным aviCopyFile. Это соответствует стандартному изображению копирования файла. Соответствующий начальный рисунок немедленно появится на вашей форме. Свойство Repetitions компонента Animate задает число повторений воспроизведения клипа. Если оно равно 0 (значение по умолчанию), то воспроизведение повторяется вновь и вновь до тех пор, пока не будет выполнен метод Stop. При выполнении этого метода генерируется событие OnStop, которое можно использовать, например, чтобы стереть изображение — сделать его невидимым.
Если же свойство Repetitions задать большим нуля, оно определит число повторений клипа. Задайте его, например, равным 3. А теперь установите свойство Active компонента Animate в true. Вы увидите (Рисунок 4.21), что еще в процессе проектирования ваше приложение заработает. Изображение оживет и клип будет повторен 3 раза.
Выбор типа диаграммы в Редакторе Диаграмм
Поэтому вы сразу можете наблюдать результат применения различных опций к вашему приложению, что очень удобно.
Страница Series, также имеющая ряд закладок, дает вам возможность выбрать дополнительные характеристики отображения серии. В частности, для круговой диаграммы на закладке Format полезно включить опцию Circled Pie, которая обеспечит при любом размере компонента Chart отображение диаграммы в виде круга. На закладке Marks кнопки группы Style определяют, что будет написано на ярлычках, относящихся к отдельным сегментам диаграммы: Value — значение, Percent — проценты, Label — названия данных и т.д. В примере Рисунок 4.8 включена кнопка Percent, a на закладке General установлен шаблон процентов, обеспечивающий отображение только целых значений.