Текст книги "Программирование в Delphi. Трюки и эффекты"
Автор книги: Александр Чиртик
Жанр: Программирование, Компьютеры
сообщить о неприемлемом содержимом
Текущая страница: 11 (всего у книги 24 страниц)
Разработка звукового проигрывателя
Обладая достаточным багажом знаний о мультимедийных компонентах Delphi, мы вплотную подошли к созданию программы-проигрывателя. В рамках данной книги разработка многофункционального сложного проигрывателя не предусматривается, но создание легкореализуемого приложения с набором необходимых функций все же будет рассмотрено.
Приступим к проектированию проигрывателя. Для начала нужно определить набор необходимых функций. В качестве базовых возможностей любого проигрывателя как видео-, так и аудиофайлов выделяют: непосредственно воспроизведение выбранного файла, возможность кратковременной остановки и возобновления воспроизведения (функция паузы), остановка, перемещение позиции воспроизведения (перемотка). Необходимым также являются отображение времени проигрывания и имени воспроизводимого файла. Как известно, компонент MediaPLayer поддерживает почти все эти функции, за исключением двух последних. Следовательно, MediaPLayer почти идеально подходит на роль основного элемента разрабатываемого проигрывателя.
Свойства формы приложения настраиваются следующим образом. Убирается кнопка максимизации (в данном случае она является лишней): для этого свойству biMaximaze, которое находится на вкладке BorderIcons, присваивается значение False. Затем свойство BorderStyle устанавливается равным bsSingle (это не позволит пользователю изменять размеры формы). Для удобства использования проигрыватель будет появляется в центре экрана, следовательно, свойство Position нужно установить как poScreenCenter. После этого настраиваются цвета: в данном случае свойство Color равно clInactiveCaptionText.
Для отображения текстовой динамической информации удобно использовать компонент LabeL (метка). Время и позиция указателя воспроизведения в файле будут выводиться в специальный индикатор. Индикатор (в данном случае lbMainTime типа TLabel) будет отображать текущее время проигрывания. Создаваемый проигрыватель должен обладать удобным интерфейсом, поэтому он настраивается следующим образом: цвет фона Color устанавливается как clSkyBlue, цвет и размер шрифта индикатора – clMenuHighlight и 28 соответственно. Другой индикатор (надпись с именем воспроизводимого файла) будет иметь свойства, установленные по умолчанию.
Управление воспроизведением будет осуществляться частично с помощью кнопок проигрывателя. Функции перемотки реализуются в обработчиках двух других дополнительных кнопок, поэтому все кнопки компонента MediaPLayer, кроме кнопок воспроизведения, паузы и остановки, скрываются. Делается это с помощью присвоения свойству VisibleButtons массива значений [btPlay,btPause,btStop]. Кнопки управления перемоткой будут выглядеть стандартно. Кроме всего сказанного, также необходимо создать кнопку открытия файла для выбора файла воспроизведения. Для этого поместите на форму стандартную кнопку и оставьте ее настройки по умолчанию.
Далее нужно максимально эргономично разместить на форме вышеперечисленные компоненты – и можно переходить от создания дизайна к реализации функциональных возможностей. Для корректной работы индикатора времениего необходимо периодически обновлять. Для достижения этой цели понадобится таймер. Среда Delphi содержит компонент, выполняющий функции таймера Timer (вкладка System).
На форму приложения также помещается стандартное окно открытия файлов. Находится этот компонент на вкладке Dialogs. Один из вариантов размещения компонентов интерфейса показан на рис. 5.3.
Рис. 5.3. Интерфейс проигрывателя
Начнем рассмотрение исходного текста приложения. В программе присутствует секция констант с единственной константой, необходимой для задания интервала (положения указателя воспроизведения в файле), на которое будет осуществляться перемотка. В данном случае перемотка будет осуществляться на 10 секунд:
const
//Константа для перемотки на 10000 миллисекунд
perem=10000;
Далее необходимо создать функцию, которая будет преобразовывать численные значения времени (миллисекунды) в более удобный для вывода строковый формат с указанием минут и секунд (листинг 5.6).
Листинг 5.6. Функция преобразования времени
function TSoundPlayerForm.FileLangToStr(leng: longint): string;
var
//Переменная результирующей строки
strTime: string;
sec: longint;
min: longint;
begin
//Получаем секунды и минуты из миллисекунд (leng)
sec:= trunc(leng/1000);
min:= trunc(sec/60);
secc c cc:= sec– min*60;
strTimeee:= IntToStr(min);
//Если секунд меньше десяти, то преобразуем результирующую
//строку (участок минут), добавляя '0'спереди
if sec < 10 then strTime:= strTime + ':0'+ IntToStr(sec)
else strTime:= strTime + ':'+ IntToStr(sec);
FileLangToStr:= strTime;
end;
Далее нужно определить количество секунд, затем минут и преобразовать эти данные в строковый вид (для вывода на индикатор времени). Если после расчета количества минут секунд оказалось меньше десяти, то в результирующую строку добавляется 0. К примеру, получилось, что композиция имеет длительность три минуты и пять секунд. В этом случае строка должна выглядеть как 3:05, а не 3:5.
Процедуру создания корректного формата времени мы разобрали. Теперь необходимо выяснить, как можно узнать время, которое прошло с момента начала воспроизведения файла. Для этого потребуются свойства компонента MediaPLayer, а именно свойства Length (длина загруженного файла) и Position (текущая позиция в нем). Зная позицию, можно с помощью ранее рассмотренной функции FileLangToStr найти время воспроизведения (листинг 5.7).
Листинг 5.7. Процедура отображения или обновления индикаторов
procedure TSoundPlayerForm.UpdateViewTime;
var
//Длина файла и позиция в файле
leng, posit: longint;
begin
//Находим длину воспроизводимого файла
leng:= mdpSoundPlayer.Length;
//Находим позицию в воспроизводимом файле
posit:= mdpSoundPlayer.Position;
//Преобразум время в строку
lbMainTime.Captionnn:= FileLangToStr(posit);
//Устанавливаем имя файла
lbFileName.Caption:= mdpSoundPlayer.FileName;
end;
Как можно заметить из кода листинга 5.7, после получения позиции в файле и его имени данные о времени воспроизведения и путь к файлу попадают на индикаторы lbMainTime и lbFileName соответственно.
Открытие и загрузка файла в мультимедийный компонент происходит при выполнении кода листинга 5.8. Кроме того, обработчик вызывает процедуру UpdateVi ewTime и включает таймер (tmTimer. Enabled:= true).
Листинг 5.8. Открытие файла
procedure TSoundPlayerForm.bnOpenFileClick(Sender: TObject);
begin
if opdOpenDialog.Execute=true then
begin
//Открываем файл
mdpSoundPlayer.FileName:= opdOpenDialog.FileName;
mdpSoundPlayer.Open;
//Устанавливаем значения в индикаторах
UpdateViewTime;
//Включаем таймер
tmTimer.Enabled:= true;
end;
end;
Процедура обработки срабатывания таймера заключается в вызове функции обновления значений индикаторов (UpdateViewTime) (листинги 5.9 и 5.10).
Листинг 5.9. Событие таймера
procedure TSoundPlayerForm.tmTimerTimer(Sender: TObject);
begin
//Обновление значений экрана
UpdateViewTime;
end;
Листинг 5.10. Обработчик активизации формы
procedure TSoundPlayerForm.FormActivate(Sender: TObject);
begin
//Временное выключение таймера
tmTimer.Enabled:= false;
//Задание значений
lbMainTime.Caption:= '00:00';
lbFileName.Caption:= 'no file...';
//Установка фильтров для окна
opdOpenDialog.Filter:=
'MP3 music (*.mp3)|*.MP3|Wav files (*.wav)|*.WAV';
end;
Перемотка осуществляется с помощью двух кнопок. Для перемотки вперед на десять секунд необходимо нажать кнопку >>, назад – << (листинги 5.11 и 5.12).
Листинг 5.11. Перемотка вперед
procedure TSoundPlayerForm.bnNextStClick(Sender: TObject);
begin
if mpCanPlay in mdpSoundPlayer.Capabilities then
begin
if (mdpSoundPlayer.Position+perem) <= mdpSoundPlayer.Length then
mdpSoundPlayer.Position:= mdpSoundPlayer.Position + perem
else
mdpSoundPlayer.Position:= mdpSoundPlayer.Length;
mdpSoundPlayer.Play;
end;
end;
Листинг 5.12. Перемотка назад
procedure TSoundPlayerForm.bnPrevStClick(Sender: TObject);
begin
if mpCanPlay in mdpSoundPlayer.Capabilities then
begin
if mdpSoundPlayer.Position >= perem then
mdpSoundPlayer.Position:= mdpSoundPlayer.Position – perem
else
mdpSoundPlayer.Position:= 0;
mdpSoundPlayer.Play;
end;
end;
Таким образом, разработанный аудиопроигрыватель предоставляет минимальный набор функций и возможностей, но он обладает важным преимуществом – простотой реализации. Как вы могли заметить, созданная программа может проигрывать и МР3-файлы. Это становится возможным благодаря использованию специального программного обеспечения – кодеков, установленных в операционной системе. Современная и достаточно распространенная операционная система Windows XP содержит такие кодеки в комплекте базовой поставки. При использовании созданного проигрывателя в других операционных системах типа Windows, вероятно, понадобится самостоятельная установка кодеков.
На этом этапе принцип построения проигрывателя звуковых записей вам должен быть понятен. Что же касается просмотра видеозаписей, то благодаря универсальности компонент MediaPLayer этот процесс схож с воспроизведением звуковых файлов.
Видеопроигрыватель
Не менее интересной задачей, рассматриваемой в рамках этой главы, является разработка проигрывателя видеофайлов. Форматов видео существует достаточно много, но самым распространенным из них, несомненно, является AVI. Поэтому следующей, не менее интересной, задачей будет разработка проигрывателя видеофайлов в AVI-формате.
Учитывая, что среда Delphi предоставляет высокоуровневый доступ к мультимедийным возможностям компьютера, сам принцип построения проигрывателя не меняется. Как и в случае со звуковым проигрывателем, будет использоваться уже хорошо знакомый вам компонент MediaPlayer. Особенностью воспроизведения видео является только необходимость вывода изображения на экран в дополнение к звуковому сопровождению. Таким образом, необходимо определить, какие именно компоненты могут служить в качестве контейнеров для воспроизведения в них видеопотока.
Как и в случае со звуковым проигрывателем, понадобятся: компонент MediaPlayer, окно открытия файлов OpenDialog и компонент-контейнер для вывода изображения (будет использован компонент GroupBox). Сначала нужно настроить форму приложения. Для этого убирается кнопка максимизации (в данном случае она является лишней): присвойте свойству biMaximaze, которое находится на вкладке BorderIcons, значение False. Затем установите значение свойства BorderStyle равным bs Single – это не позволит пользователю изменять размеры формы. Для удобства использования проигрыватель лучше расположить в центре экрана – следовательно, установите свойство Position в значение poScreenCenter. В компоненте MediaPlayer оставьте видимыми только кнопки запуска, паузы и остановки воспроизведения (так же, как в проигрывателе звука). Поместите на форму компонент GroupBox и установите свойство Caption пустой строкой, так как именно в этот компонент будет выводиться видеоизображение.
Рис. 5.4. Вид видеопроигрывателя
Теперь рассмотрим некоторые особенности созданного видеопроигрывателя. В качестве элемента-контейнера для динамического изображения использовался компонент GroupBox, поэтому его необходимо было назначить элементом вывода видео для компонента MediaPlayer. Этот процесс сводится к присваиванию экземпляра компонента GroupBox свойству Display компонента MediaPlayer. Делать это необходимо во время активизации формы (листинг 5.13).
Листинг 5.13. Назначение элемента вывода изображения
procedure TFormVideoPlayer.FormActivate(Sender: TObject);
begin
//Устанавливаем область воспроизведения
mpVideoPlayer.Display:= gbViewVideo;
end;
В предложенном фрагменте текста программы переменная gbViewVideo является экземпляром компонента GroupBox.
В качестве доказательства простоты, удобства и гибкости использования компонента MediaPLayer ниже приведен весь исходный текст приложения (листинг 5.14).
Листинг 5.14. Видеопроигрыватель
unit video_player;
interface
uses
//Подключаемые модули
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, MPlayer;
Type
//Главная форма приложения
TFormVideoPlayer = class(TForm)
mpVideoPlayer: TMediaPlayer;
FileOpenDlg: TOpenDialog;
gbViewVideo: TGroupBox;
bnOpenFile: TButton;
//Нажатие кнопки открытия файла
procedure bnOpenFileClick(Sender: TObject);
//Активизация формы
procedure FormActivate(Sender: TObject);
private
{Private declarations}
public
{Public declarations}
end;
var
FormVideoPlayer: TFormVideoPlayer;
implementation
{$R *.dfm}
procedure TFormVideoPlayer.bnOpenFileClick(Sender: TObject);
begin
if FileOpenDlg.Execute = True then
begin
//Загружаем файл, выбранный в окне открытия файла
mpVideoPlayer.FileName:= FileOpenDlg.FileName;
//Активизируем проигрыватель
mpVideoPlayer.Open;
end;
end;
procedure TFormVideoPlayer.FormActivate(Sender: TObject);
begin
//Устанавливаем область воспроизведения
mpVideoPlayer.Display:= gbViewVideo;
end;
end.
Из предложенного фрагмента видно, что, обладая минимальным объемом исходного текста, данный видеопроигрыватель может выполнять все необходимые функции. Это становится возможным благодаря наличию компонента MediaPLayer в среде программирования Delphi.
Глава 6
Использование Windows GDI
• Графические объекты
• Аппаратно-независимый графический вывод
• Контекст устройства
• Графические режимы
• Работа со шрифтами
• Рисование примитивов
• Работа с текстом
• Работа с растровыми изображениями
• Альфа-смешивание
Операционная система Windows с самого начала создавалась прежде всего как графическая оболочка. Как следствие, в ней используется графическое представление информации. Вполне естественно, что почти любое приложение использует экран для отображения данных, с которыми оно работает. Сама операционная система, по крайней мере, отображает на экране визуальные элементы приложений. Windows обеспечивает универсальность представления информации как на экране, так и на других устройствах вывода, например на принтере. Стоит отметить, что для этого используются одни и те же примитивы отображения. Система самостоятельно определяет целевое устройство и активизирует соответствующий ему модуль. Операционная система Windows является многозадачной и предъявляет к приложениям ряд основных требований, исключающих возникновение конфликтов при использовании функций вывода. Однако это вовсе не означает, что Windows обеспечивает приложения только набором функций вывода на экран или печать, – система полностью управляет всем выводом.
Наверное, более правильно будет сказать, что приложения используют в качестве первичного вывода окно, а не непосредственно экран. Каждое устройство вывода в Windows характеризуется набором текущих параметров, с использованием которых происходит собственно вывод, причем в каждый конкретный момент времени только одному приложению соответствует некоторое устройство вывода, что исключает одновременный доступ к последнему, а также изменение параметров одним приложением перед началом процесса вывода другим.
Графические объекты
Для управления выводом операционная система Windows предоставляет приложению набор графических объектов.
• Битовые массивы (bitmaps) – прямоугольные массивы точек, формирующие растровые изображения.
• Карандаши (pens) – используются для задания таких параметров рисования линий, как толщина, цвет и стиль (сплошная, прерывистая и т. п.).
• Кисти (brushs) – применяются для задания таких параметров заливки замкнутых контуров, как цвет и стиль.
• Шрифты (fonts) – позволяют определить параметры вывода текста, включая имя шрифта, размер символов и т. д.
• Регионы (regions) – определяют области окна, которые могут быть ограничены прямоугольником, многоугольником, эллипсом или их произвольной комбинацией для выполнения операций заполнения, заливки, инверсии и т. д. Помимо этого, регионы служат для определения местоположения указателя.
• Логические палитры (logical palettes) – осуществляют взаеимодействие между приложением и таким цветным устройством вывода, как дисплей, а также содержат список цветов, необходимых приложению.
• Контуры (paths) – используются для заполнения или выделения контура различных фигур.
Аппаратно-независимый графический вывод
Одной из главных особенностей Windows API является независимость графического вывода от устройства. Программное обеспечение, которое поддерживает независимость, содержится в двух динамически компонуемых библиотеках. Первая – gdi.dll – обеспечивает общий графический интерфейс устройства (Graphics Device Interface, GDI), а вторая является драйвером конкретного используемого устройства. В результате приложение использует тот интерфейс, который предоставляется первой библиотекой. Перед тем как произвести какую-либо операцию вывода на некоторое устройство, приложению необходимо запросить GDI о загрузке соответствующего драйвера (обычно это осуществляется автоматически и не требует дополнительных действий со стороны программиста). После загрузки соответствующего драйвера приложение должно настроить ряд таких параметров вывода, как цвет линии и ее ширина, тип кисти и ее цвет, шрифт, область отсечения и т. д. Операционная система Windows обеспечивает хранение всех этих и других данных в специальной структуре, называемой контекстом устройства.
Стоит заметить, что GDI реализует интерфейс, используемый для рисования двухмерной графики. Этот интерфейс обеспечивает самый медленный из существующих способ отображения графики, однако является и самым простым для понимания основ. В основном он используется для создания простых эффектов с минимальными усилиями.
Контекст устройства
Контекст устройства – структура, определяющая набор графических объектов и связанных с ними атрибутов и графических режимов, которые воздействуют на вывод. Графические объекты включают карандаши для рисования линий, кисти для закрашивания и заполнения, битовые образы для копирования или прокрутки части экрана, цветовые палитры для определения набора доступных цветов, области для отсечения и других операций, а также контуры для операций рисования и закрашивания.
Приложение не имеет прямого доступа к контексту устройства, и настройка параметров осуществляется посредством вызова соответствующих функций Win32 API.
Существует четыре типа контекстов устройств:
• экранный – поддерживает операции рисования непосредственно на экране;
• принтера – поддерживает операции рисования непосредственно на принтере или плоттере;
• памяти – поддерживает операции рисования непосредственно в битовых массивах;
• информационный – поддерживает получение данных об устройстве.
Приложение может осуществлять следующие операции над контекстом устройства:
• перечисление существующих графических объектов;
• выбор новых графических объектов;
• удаление существующих графических объектов;
• сохранение графических объектов, их атрибутов и параметров графических режимов;
• восстановление графических объектов, их атрибутов и параметров графических режимов.
Помимо всего прочего, приложение может использовать контекст устройства для определения процесса графического вывода, прерывания длительных графических операций, начатых другим потоком многопоточного приложения, а также может инициализировать принтер.
Экранный контекст устройстваПриложение получает контекст устройства экрана посредством вызова функций BeginPaint, GetDC или GetDCEx. Полученный контекст устройства идентифицирует окно, в которое будет непосредственно осуществляться вывод. Как правило, приложение получает контекст устройства экрана непосредственно перед началом рисования в клиентской области. Когда приложение завершает вывод, оно обязано освободить контекст устройства, вызвав одну из соответствующих функций: EndPaint или ReleaseDC.
Win32 API позволяет получать три типа контекста устройства экрана: контекст класса, общий и частный. Контекст класса и частные контексты устройства используются в приложениях, выполняющих многочисленные операции вывода: например, программах автоматизированного проектирования, настольных издательских системах, то есть таких приложениях, которые самостоятельно и постоянно осуществляют вывод и, соответственно, для которых время, затрачиваемое на эти операции, критично с точки зрения производительности. Общие контексты устройства используются в приложениях, выполняющих операции вывода лишь время от времени.
Контекст класса поддерживается только для совместимости с предыдущими версиями Windows. При создании Win32-приложения вместо контекстов класса следует использовать частные контексты.
Общий контекст устройства – контекст устройства экрана, который обрабатывается в специальном кэше системы. Такие контексты устройства используются в приложениях, осуществляющих операции вывода не очень часто. Система, перед тем как возвратить описатель контекста устройства, предварительно инициализирует общие контексты устройства значениями по умолчанию, которые можно менять по мере необходимости с помощью специальных функций. Любая операция вывода, выполняемая приложением, будет использовать значения по умолчанию до тех пор, пока не будет вызвана одна из функций GDI, предназначенных для выбора нового графического объекта, изменения атрибутов существующего объекта или выбора нового режима. Поскольку может быть создано лишь определенное количество общих контекстов устройства, то приложение обязано освободить его, после того как осуществит операции вывода. Когда приложение освобождает общий контекст устройства, все произведенные изменения в данных по умолчанию отменяются. В результате параметры приходится устанавливать каждый раз заново.
Частный контекст устройства, в отличие от общего, сохраняет любые изменения для заданных по умолчанию данных. Этот контекст устройства не является частью системного кэша, и поэтому не должен освобождаться. Система автоматически освобождает его только после того, как последнее окно будет разрушено. Приложение создает частный контекст устройства при заполнении структуры (указав предварительно CS_OWNDC стиль окна), описывающей класс окна, регистрируемого функцией RegisterClass. После создания окна с указанным стилем приложение вызывает одну из функций – GetDC, GetDCEx или BeginPaint – для получения описателя, идентифицирующего частный контекст устройства. Приложение может использовать его до тех пор, пока не будет разрушено окно, созданное с этим классом. Любые изменения графических объектов и их атрибутов или графических режимов сохраняются системой до тех пор, пока окно не будет удалено.
Правообладателям!
Это произведение, предположительно, находится в статусе 'public domain'. Если это не так и размещение материала нарушает чьи-либо права, то сообщите нам об этом.