У вас вопросы?
У нас ответы:) SamZan.net

Проигрыватель Цельработысоздатьпрограммупроигрывательфайловмультимедиаснабженный системойвизуа

Работа добавлена на сайт samzan.net: 2016-03-05

Поможем написать учебную работу

Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 25.2.2025

Практическая работа№ 36

«Проигрыватель»

Цельработы-создатьпрограмму-проигрывательфайловмультимедиа,снабженный системой визуализации. Для начала многооконность будет реализована посредством стандартных диалогов. Проигрыватель файлов мультимедиа, проигрывающий различные форматы, а такжесопровождающиймузыкальныефайлы визуализацией.

1. Создатьна дискепапку (например C:\MyDelphi\MyMPlayer), в которой будет создан проект, скопировать в эту папку несколько музыкальных файлов и клипов. Для демонстрации полноценной работы проигрывателя понадобятся мультимедийные файлы wav, mid, wma, mp3, avi, которые можно найти в соответствующих папках.

Видеофайлы:

C:\Program Files\Borland\Delphi5\Demos\Coolstuf\

Аудиофайлы: C:\Windows\Media\

C:\Program Files\Microsoft Office\Office10\Media\ C:\Мои документы\Мои музыкальныезаписи\

2. Создать простейшую программу проигрывания аудиофайлов (см. практическая работа№ 10). Для этого поместить на форму кнопку, медиапроигрыватель, диалог загрузки.

Рис. 72.

3.  Настроить  фильтр  диалога на  файлы  мультимедиа,  соответственно  заполнив таблицу.Убратьненужныенамкнопкипроигрывателя,отключивихвИнспектореОбъектов

(VisibleButtons). В обработчикенажатия на кнопкуописать загрузкуфайла.

OpenDialog – диалог загрузки

 

Рис. 73.

Основное  свойство  – FileName:  string,  основной  метод  –  Execute.  При  вызове из программы  методаExecute  происходит  вывод   на  экран  диалога.  Параметры   вывода

110


определяютсясвойствамикомпонента:Title,Options,Filterидр.Еслипользовательвыберет файлдляоткрытияинажмет"Открыть",товсвойствоFileNameкомпонентабудетзаписано имяэтогофайлавформатеstring,арезультатомметодаExecuteбудетзначениеtrue.Иначе, если пользователь нажмет в диалоге кнопку"Отмена", результатExecute будетfalse, т.е. Execute является булевойфункцией.

MediaPlayer –  медиапроигрыватель.

Основное свойство–FileName:string, основные методы– Play,Pause,Stop. После тогокаквсвойствоFileNameпомещеноимяфайламультимедиа,этотфайлнужнооткрытьс помощью методаOpen (если установлено свойствоAutoOpen, то открытие происходит автоматически, но это не всегда хорошо, поскольку, еслиFileName не задано или задано неверно, то при автооткрытии произойдет ошибка).

Когда файл открыт, он может быть воспроизведен. Это можно сделать с помощью кнопок самого компонента, либо вызвав методPlay. То же касается остановки и паузы– методовStop иPause. Для настройки внешнего вида компонента используется множество свойств, к примеру, можно скрытьчасть кнопок, настраивая свойство VisibleButtons.

4. В обработчике нажатия наButton1 вызывается метод диалогаExecute, и если он выдает результат   true   (пользователь выбрал файл и нажал   "Открыть"), то медиапроигрывателюпередаетсяимяэтогофайлаифайлоткрывается.Теперьпользователь может воспроизвести его, нажав кнопки проигрывателя.

procedure TForm1.Button1Click(Sender: TObject);

begin

 ifOpenDialog1.Execute then begin

   MediaPlayer1.FileName := OpenDialog1.FileName;

   MediaPlayer1.Open;

end;

end;

5. При запуске программы пользователь видит кнопку и проигрыватель. Проигрывательнеявляетсяактивным,посколькуфайл,которыйондолженвоспроизводить, не открыт.

Рис. 74.

При нажатии на кнопку активизируется диалог. Параметры диалога соответствуют значениям свойств, заданных предварительно в Инспекторе Объектов. К примеру, выбранныйфильтр звуковых файлов скрывает все файлы с отличающимся расширением.

После выбора в музыкальной папке файла при нажатии кнопки  "Открыть"

проигрыватель стал доступным. Файл открыт,и можно воспроизвести его.

111


Если необходимо воспроизвести видеофайл, то при запуске автоматически будет создано отдельное окно, в котором отобразится изображение.

6. Проигрыватель готов. Необходимо оформить пользовательский интерфейс. Поместите на форму панель, а на ней расположите компонентImage, растянутый на всю панель. Добавьте  таймер.  Сохраните  модуль  как MainUnit  и  проект  какMyMPlayer  в приготовленную папку.

Рис. 75.

Дайте каждому компоненту подходящее название. Обработчик кнопки поменяйте согласно  последним  изменениям  и  добавьте  растяжение  видеоэкрана. Для  того  чтобы видеофайлы воспроизводились не в отдельномокне, а в заданном месте, например, на Panel1, необходимо соответствующим образом установить свойство медиапроигрывателя Display. Для того чтобы установить и растянуть нужным образом изображение, нужно установить свойство DisplayRect:

MPlayer.DisplayRect:=Rect(0,0,ScreenPanel.Width, ScreenPanel.Height);

где Rect(x1, y1, x2, y2: integer):TRect – функция, преобразующая четыре числа к формату TRect – прямоугольник,а свойствоDisplayRectимеет именно этот формат.

Для того чтобы переименовать компоненты измените свойствоName. Настройте параметры компонентов:

1)  MainForm: TmainForm

Caption = ‘Мультимедиа-проигрыватель’ ClientWidth = 402

ClientHeigth = 290

2)  LifeTimer: Ttimer Enabled = false Interval = 100

3)  MediaOpenDlg: TOpenDialog

Options:ofFileExist=true

Title=‘Загрузить файл мультимедиа’

4)  LifeImage: TImage

Align = alClient

5)  ScreenPanel: TPanel Align = alTop Caption=‘’

Width = 402

Heigth = 252

6)  MediaOpenBtn: TButton

Captoin = ‘Открыть’

7)  MPlayer: TMediePlayer

Display = ScreenPanel

VisibleButtons = [btPlay,btPause,btStop]

112


7.Необходимосоздатьединуюформудлявоспроизведениязвуковыхивидеофайлов. Причем воспроизведение звуковых файлов тоже будет сопровождаться анимацией.   В качествеэтого сопровожденияиспользуетсяигра "Жизнь".

Для этого добавимсоответствующий "рассчитывающий" и "рисующий" код.

Опишемконстанты,определяющиеразмерполя,введемновыйтип–массивклетоки объявимглобальную переменную этого типа.

const

 XSize = 40;

 YSize = 25;

type

TLifeCells= array[0..XSize-1,0..YSize-1]ofboolean;

var

 MainForm: TMainForm;

 A: TLifeCells;

Создадимпроцедуру,случайнымобразомзаполняющую массив.

procedure RandomCells;

var

i,j:integer;

begin

 fori:=0 to XSize - 1do forj:=0to YSize - 1do

         A[i, j] := random< 0.5;

end;

Это  процедура  случайного  заполнения  поля.  Булева  переменная  присваивается логически,ане спомощьюусловногооператораifrandom<0.5thenA[I,j]:=trueelseA[i.j]:= false.

Создадимфункцию, определяющую число живых клеток-соседей уданной клетки.

functionNumOfCells(x,y:integer):integer;

var

i,j,xx,yy:integer;

begin

 Result := 0;

fori:=-1to1do

forj:=-1to1do

 begin

xx:=x+i;yy:=y+j;

if xx = -1thenxx:=XSize-1; if yy = -1thenyy:=YSize-1; if xx = XSize then xx := 0;

if yy = YSize then yy := 0;

   ifA[xx,yy] then inc(Result);

end;

 ifA[x,y]then dec(Result);

end;

Это функция подсчета живых соседей. Обратите внимание на переменныеxx иyy. Подобным образом реализуется"сшивка" верхнего и нижнего, левого и правого краев. В конце исключаетсясама клеткаиз числа соседей:ifA[x,y]thendec(Result);

Создадимпроцедуру, рисующую поле клеток.

procedureDrawCells;

var

i,j:integer;

113


begin

with MainForm.LifeImage.Canvasdo

 begin

   Brush.Color := сlBlue;

   Pen.Color := Brush.Color;

Rectangle(0,0,XSize*10,YSize*10);

   Brush.Color := clRed;

  fori:=0to XSize - 1do

 forj:=0to YSize - 1do

if A[i, j] thenRectangle(i*10,j*10,i*10+10,j*10+10);

end;

end;

Опишем обработчик таймера; каждый такт у нас будет происходить перерасчет живых клеток по правилам игры.

procedure TMainForm.LifeTimerTimer(Sender: TObject);

var

i,j:integer;

B: TLifeCells;

begin

fori:=0 to XSize - 1do for j:=0 to YSIze - 1do

caseNumOfCells(i,j)of

 2: B[i, j] := A[i, j];

 3: B[i, j] := true;

else B[i, j] := false;

end;

A:=B;

DrawCells;

end;

Каждыйтакттаймерапересчитываютсяживыеклетки.Алгоритмигры,какизвестно, состоитвследующем.Еслиуживойклеткидваилитрисоседа,тоонаостаетсяживой,если меньшедвух,–погибаетотодиночества,еслибольшетрех,–гибнетоттесноты.Рождается клетка, если у нее ровно три соседа. С помощью оператораcase реализуются правила. Использование локального массиваB необходимо. Если записывать сразу вA, то клетки нового поколения будут также считаться при учете соседей, что недопустимо: каждому – свое.Вконце,однако,нужноскопироватьновоепоколение,содержащеесявB,вмассивA. Простые массивыможно копировать присвоением:A:=B.

Модифицируется обработчик нажатия кнопки под новые задачи. Проанализируйте расширениезагружаемогофайла,и,еслизагруженвидеофайл,Imageстановитсяневидимым, освобождая экран для ролика, в противном случае, наоборот, выводится картинку, на которой идет игра, заполняетсяполе клеток и запускается таймер.

procedure TMainForm.MediaOpenBtnClick(Sender: TObject);

begin

 if MediaOpenDlg.Execute then

 begin

   MPlayer.FileName := MediaOpenDlg.FileName;

  MPlayer.Open;

MPlayer.DisplayRect:=Rect(0,0, ScreenPanel.Width, ScreenPanel.Height);

   MPlayer.Play;

 if ExtractFileExt(MPlayer.FileName) = '.avi'then LifeImage.Visible := false

elsebegin

LifeImage.Visible:=true;

114


   RandomCells;

LifeTimer.Enabled:=true;

end;

end;

end;

Экран  вывода "растягивается"  на  всю  панель.  Добавлен  автоматический  запуск воспроизведения. В зависимости от расширения воспроизводимого файла, LifeImage, на котором происходит"Жизнь", либо прячется (в  случае'.avi'), либо выводится (в  других случаях).

Рис. 76.

8.Необходимопредоставитьпользователювозможностьнастройкицветов.Наформу добавляемтрикомпонента–двадиалогавыборацветаFieldColorDlg:TColorDialog(Color= clNavy),CellColorDlg:TColorDialog(Color=clYellow) и одну кнопкуSetColorBtn:TButton

(Caption= ‘Цвета’).

В обработчикенажатияна этукнопкунужно описать вызов диалогов.

Рис. 77.

ColorDialog(основноесвойствоColor:TColor,основнойметод–Execute)-  диалог выборацвета.Еслипользовательвыбралцветинажал"ОК",результатэтогометода–true, если пользователь нажал "Отмена",то результат false.

procedure TMainForm.SetColorBtnClick(Sender: TObject);

begin

 if MessageDlg('Изменить цвета?', mtConfirmation, [mbYes, mbNo], 0) = mrNothen exit;

if MainForm.FieldColorDlg.Execute then ScreenPanel.Color := MainForm.FieldColorDlg.Color;

 MessageDlg('Теперь изменитецвет клеток',mtInformation, [mbOk], 0);

 CellColorDlg.Execute;

115


DrawCells;

end;

MessageDlg(const Msg: string; DlgType:TMsgDlgType;Buttons:TMsgDlgButtons; HelpCtx: Longint): Word; - вызовокна сообщения. Это служебноеокно.

Msg – текст сообщения.

DlgType – тип диалога. Возможные значения:mtWarning,mtError,mtInformation, mtConfirmation, mtCustom.

Buttons–используемыекнопки.Переменнаятипа"множество",возможныеэлементы: mbYes,  mbNo,mbOK,mbCancel,mbAbort, mbRetry,mbIgnore,mbAll,mnNoToAll, mbYesToAll,mbHelp.

HelpCtx– индекс контекстной справки. В данном примере индекс равен нулю. При написании проектов сразвернутой справочной системой указываетсяреальныйиндекс.

MessageDlg  возвращает  число,  равное  одной  из  следующих  констант:mrNone, mrAbort, mrYes,mrOk,mrRetry,mrNo,mrCancel,mrIgnore,mrAll. Эти константы – так называемый  модальный  результат (modal result)  нажатия  на  соответствующую  кнопку диалога.

Вданнойпрограммепроверяется,равенлимодальныйрезультатmrNo,т.е.нажатали кнопка"Нет";еслинажата,товызываетсяexit,ипрограмманемедленновыходитизтекущей процедуры-обработчика.

Функции MessageDlg и Execute Delphi позволяет вызывать как процедуры: MediaOpenDlg.Execute вместо if MediaOpenDlg.Execute then …

При этом невозможно проконтролировать, какие кнопки были нажаты: "OK" или

"Отмена".

Далее  необходимо откорректировать процедуру рисования, затем запустить программу, загрузить музыкальный файл и настройте цвета. Наконец, необходимо использовать цвета диалогов при рисовании.

Внеситеизмененияв DrawCells:

with MainForm.LifeImage.Canvasdo

begin

Brush.Color := MainForm.FieldColorDlg.Color;

Pen.Color := Brush.Color;

Rectangle(0, 0, XSize * 10, YSize * 10); Brush.Color := CellColorDlg.Color;

Brush.Color := MainForm.CellColorDlg.Color;

……….

Рис. 78.

116


Рис. 79.

9. На данный момент форма может быть масштабирована во время работы приложения. Для того  чтобы зафиксировать  размер формы, необходимо установить соответствующеесвойствоBorderStyle.Крометого,нужнозапретитьразворачиваниеформы на весь экран (это такженежелательно).

Перечислимосновныесвойстваисобытия формы.

Свойства

BorderIcons: TBorderIcons –  иконки  заглавной  панели  формы,  тип  свойства– множество, возможные элементы:biSystemMenu,biMinimize,biMaximize,biHelp(в данном случаенужно отключить biMaximize, чтобы формунельзя было развернуть).

BorderStyle: ТBorderStyle – стиль бордюра bsDialog, bsSingle, bsNone, bsSizeable, bsToolWindow, bsSizeToolWin. Если установить bsNone, то форма будет без заглавной панели,азначитибезкнопкизакрытияпрограммы.Следовательнр,выходитьизпрограммы возможнолибоспомощьюAlt-F4,либопредусмотретьдополнительнуюкнопку сметодом Close.

ClientWidth, ClientHeigth: integer – ширина и высотаклиентской области формы.

FormStyle:TFormStyle –  стиль  формы.  Наиболее  важным  значением  является fsStayOnTop. Если установлено это значение, то форма будет находиться над остальными формами, дажеесли она не активна, и пересекаетсяс активной на данный момент формой.

Position:TPosition – расположение формы. Здесь задаются различные начальные положения формы, например, задать положение по центру экрана(poScreenCenter). При запускепрограммы онаокажетсяв центре.

WindowState: TWindowState –  состояние  окна.  Возможные  значения: wsNormal, wsMinimized,wsMaximized.Спомощьюэтогосвойстваможноразворачиватьисворачивать форму.

События

OnActivate, OnDesactivate(Sender:TObject)– события, возникающие, когда форма активируется и дезактивируется (при этом в формупереходит или ее покидает фокус ввода). OnCloseQuery(Sender:TObject;var CanClose:Boolean)– событие, возникающее при попыткезакрытьформу.Например,некотораяпрограммаспрашивает:"Выхотитезавершить программу?".  Это  –  результат  действия  подобного  события.  Делается  это  в  обработчике подобнымобразом:CanClose:=MessageDlg('Exitnow?',mtConfirmation,[mbYes,mbNo],0)=

mrYes.

OnCreate,  OnDestroy(Sender:  TObject)  – событие, необходимое для описания действий,требуемыхв началеили в концеработыприложения(открытиеизакрытиефайлов, чтениеи сохранениенастроек, инициализацияпеременныхи т.п.).

OnHide, OnShow(Sender:TObject)– вызываются, когда форма становится видимой или невидимой (при присвоении соответствующегозначениясвойства Visible).

OnResize(Sender:TObject)– происходит, когда форма растягивается или сжимается.

Здесь описывают изменениеразмеров и расположениекомпонентов на форме.

117


10. Продолжить оформлениемедиапроигрывателя.

1) Для того чтобы случайное заполнение было более случайным, в событии формы

OnCreate добавить Randomize.

procedure TMainForm.FormCreate(Sender: TObject);

begin

  Randomize;

  RandomCells;

end;

2)  Также желательно  зациклить воспроизведение медиафайла,  описать  обработчик событиямедиапроигрывателяOnNotify.УMediaPlayerестьдвасвойства–Position:LongIntи Length:LongInt. Это, соответственно, текущая позиция в записи и длина записи. Событие проигрывателяOnNotify  возникает  при  завершении  различных  управляющих  методов MediaPlayer. Состояниепроигрывателяможноузнать из свойства Mode.

Когда запись будет доигрываться до конца, будет вызываться метод  Play,

запускающий ее с начала. При остановкепроигрывателя «перематываем» запись на начало. if Position = Length then Play

procedure TMainForm.MPlayerNotify(Sender:TObject);

begin

with MPlayer do caseMode ofmpPlaying:ifPosition=Length then Play;

mpStopped: Rewind;

end;

end;

3)  Установить название приложения и выбрать ему иконку. В главном меню открыть Project=>Options. На вкладкеApplication, задать название приложения(это название, в частности,  будет  отображаться  снизу  на  панели  задачWindows),  а  также  загрузить подходящую иконку. Стандартную иконку можно найти в папкеC:\ProgramFiles\Common Files\BorlandShared\Images\Icons,создатьсвоюиконку–вредактореDelphi(меню Tools=> Image Editor) или в любом другом редакторересурсов.

Рис. 80.

118


Рис. 81.

11. Проанализируем недостатки: не выводится название проигрываемого файла, компоненты  на  форме  не  очень-то  гармонируют  друг  с  другом,  неизвестно,  сколько процентов записи проиграно на данный момент, нельзя устанавливать скорость визуализации, нет возможности редактированияи сохраненияпозиций игры "Жизнь".

Создайте копию проекта. Добавить в проект новую форму для управления воспроизведениеммедиафайла.Длясозданияновойформыщелкнитенакнопкуменю.Есть возможность сделать это и в пункте менюFile=>New… Там же можно создать форму с помощью мастера.

Добавьте на формупять кнопокSpeedButton,TrackBar итаймер.

Рис. 82.

Кнопка SpeedButton отличается от обычной кнопки, во-первых, тем, что может содержатькартинку,а во-вторых,тем, что может оставаться нажатой.

Рис. 83.

Основные свойства – Glyph:TPicture (картинка), Down:boolean(нажата), основное событие– OnClick. У этой кнопки есть еще несколько важных свойств. Для того чтобы кнопка могла быть нажата, ее свойство Group: integer должно быть больше нуля. В этом случае все кнопки с одинаковым значением группы становятся переключателями– если нажать одну, остальные отщелкиваются. Это может быть нежелательно в случае одной кнопкисненулевойгруппой–одинразнажав,еенельзяотключить.Вэтомслучаепоможет свойство AllowAllUp: boolean. Современныйвид кнопкам придает свойство Flat: boolean.

В программе откажемся от стандартного интерфейса MediaPlayer, и, сделав его невидимым, будем обращаться к нему через созданные кнопки. Коллекция иконок для кнопок находится в папке C:\Program Files\Common Files\Borland Shared\Images\Buttons\.

119


Настройка TrackBar проводится с помощью свойств ThumbLength:integer(длина бегунка), TickMarks:TTickMark(положение рисок линейки), TickStyle:TTickStyle(стиль рисок).

Настройтеформуи компоненты. Изменитеимена компонент.

1) ControlForm: TControlForm Caption = ‘медиафайл не загружен’ BorderStyle=bsToolWindow ClientHeight = 24

ClientWidth = 402

2) NewSpBtn: TSpeedButton

AllowAllUp = true

Flat=true Glyph: rety.bmp GroupIndex=1

3) PosTrk: TTrackBar

ThumbLength = 15

TickMarks=tmBoth

TickStyle=lsNone

4) PosTimer = TTimer Enabled = false Interval = 500

5) MediaOpenSpBtn: TSpeedButton

Flat=true

Glyph: MdOpen.bmp

6) PlaySpBtn: TSpeedButton

AllowAllUp = true

Flat=true

Glyph:vcrplay.bmp

GroupIndex=1

7) PlaySpBtn: TSpeedButton

AllowAllUp = true

Flat=true

Glyph: vcrpause.bmp

GroupIndex=1

8) StopSpBtn: TSpeedButton

AllowAllUp = true

Flat=true

Glyph: vcrstop.bmp

GroupIndex=1

12.Когдатребуетсяобратитьсяккаким-топеременным,функциям,типам,объектам, описанным в другом модуле, необходимо описать ссылку на этот модуль в разделеuses. Однако тонкость состоит в том, чтоuses может располагаться и в разделеinterface, и в разделе implementation.  При  запуске  приложенияновое  окно  должно  находиться  под главным окном. Но если описать ссылки двух модулей друг на друга в разделахinterface, возникнет так называемая ошибка круговой ссылки. В рамкахPascal два модуля не могут использовать интерфейс друг друга. Ссылка в интерфейсе нужна для того, чтобы при описании типов, классов, переменных интерфейса использовать типы и константы, описанныевдругихмодулях.Вданноминтерфейсеиспользуется,кпримеру,классTForm, TSpeedButton, TTrackBar, TTimer, описанные, соответственно, в модулях Forms, Buttons, ComCtrls,ExtCtrls.Тоестьиспользованиедругихмодулейвинтерфейседаетвозможность, прежде всего, описать новые типы с помощью уже описанных типов. Именно поэтому

120


запрещена круговая ссылка. Тогда потенциально возможно было бы описать: TypeA = array[0..4]ofTypeB–водноммодулеиTypeB=array[0..99]ofTypeA–вдругом.Тоесть ignotumperignotius –неизвестноечерез еще более неизвестное (лат.).

Что же касается использования не типов, но конкретных переменных и объектов, фигурирующихвдругихформах,тоэтоиспользованиепроисходиткакразвimplementation, итуткруговыессылкивполнедопустимы.Приработеснесколькимиформамиважнотакже учитывать порядок их создания. Это касается обработки событийOnCreate– обращаться можно только к созданнымформам.

VarControlFom:TControlFom;

implementation

{$R*.DFM}

procedure TControlFom.FormCreate(Sender:Tobject);

begin

 Top := MainForm.Top + MainForm.Height + 4;

 Left := MainForm.Left;

end;

end.

Свои свойстваLeft иTop вторая  форма  подстраивает  под  те  же  свойства первой формы.Припопыткезапускапрограммы,однако,выводитсясообщениеотом,чтонеуказан модуль, в котором описанаперваяформа.

Рис. 84.

Еслинажатькнопку Yes,тов разделuses автоматическидобавится ссылкана нужный модуль.  Однако,  система  не  всегда  автоматически  работает.  Лучше  добавлять  ссылки самостоятельно. В данномслучае– в раздел implementation.

implementation uses MainUnit;

ЗдесьидетобращениекMainForm,и даннаяформадолжнабытькэтомумоменту(то есть моментусоздания ControlForm) уже созданной.

Поумолчаниюприсозданииприложенияполагается,чтобыпризапускевыводилась толькоглавнаяформа.Однаковданномслучаевпрограммедолжныбытьвидныобеформы. Обязательно,уControlFormустановитьсвойствоVisible:=true.Иначеформабудетневидна при запуске программы.

121


Рис. 85.

Можно  описать  тот  же  код,  с  точностью  до  перемены  ссылок,  в  обработчике MainForm.OnCreate главной формы. Для того чтобы выбрать нужный модуль, нажмите на кнопкупанели инструментов (выбрать модуль для редактирования). Соседняякнопкаслужит длявыбораформ(выбратьформудляредактирования).Следующаякнопка–переключатель модуль/форма.

Рис. 86.

Первая форма создается раньше второй. Следовательно, и событиеOnCreate у нее возникаетещедотого,каксозданавтораяформа,изначитпопыткадоступакней(попытка установить ее положение) вызовет ошибку.

13. Оставимглавной форме только предназначениеэкрана.Удалите код внутри обработчиков кнопок,а такжесами кнопки.

procedure TMainForm.MediaOpenBtnClick (Sender : TObject);

begin

end;

procedure TMainForm.SetColorBtnClick (Sender : TObject);

begin

end;

122


Установите медиапроигрывателю Visible := false, переместите его поверх панели. Если панель в форму добавлена позже проигрывателя, то проигрыватель окажется под панелью.Поэтомупредварительнопоменяйтепорядок –щелкнитеправойкнопкоймышина проигрыватель и выберите"BringToFront".

Рис. 87.

Теперь изменитеклиентскую высотуформы.Экран готов.

Рис. 88.

Теперь предстоит описать обработчики компонентов второй формы. Таймер будет передвигатьбегунок, отображая процент проигранной записи.

procedure TControlForm.PosTimerTimer(Sender: TObject);

begin

PosTrkBar.Position:=MainForm.MPlayer.Position;

end;

procedure TControlForm.PosTrkBarChange(Sender: TObject);

begin

 if not PosTimer.Enabled then

MainForm.MPlayer.Position:=PosTrkBar.Position;

end;

В обработчикекнопки загрузки помещаетсякод, похожий на тот, чтоуже писали.

Код относится к компонентам главной формы. Из-за этого необходимо указывать вторую форму,когдаобращаютсякеекомпонентам,хотяитакнаходятсяся вобработчике второй формы.

Обратитевниманиенадватаймера –одинзапускаетвизуализацию,адругойдвигает бегунок. Передвижения бегунка действенны, только когда воспроизведение остановлено– PosTimer.Enabled:=false.Иначе происходитконфликт–таймерменяетпозициюбегунка,а

123


бегуноквответменяетпозициюпроигрывателя.Еслинеобходимоменятьпозициювовремя воспроизведения, придется вводить дополнительныепроверки.

Когда запись остановлена, можно поменять ее позицию тем же бегунком. Кнопки управленияпрограммнозапускаютиостанавливаютпроигрыватель.Покафайлнезагружен, их следует отключить, иначе при нажатии на них произойдет ошибка. Последняя кнопка определит, проигрывать ли запись в цикле.

procedureTControlForm.PlaySpBtnClick(Sender: TObject);

begin

 MainForm.MPlayer.Play;

PosTimer.Enabled:=true;

end;

procedure TControlForm.PauseSpBtnClick(Sender: TObject);

begin

 MainForm.MPlayer.Pause;

 PosTimer.Enabled := false;

end;

procedure TControlForm.StopSpBtnClick(Sender: TObject);

begin

 MainForm.MPlayer.Stop;

 PosTimer.Enabled := false;

end;

Запуская  и  останавливая  проигрыватель, мы  запускаем  и  останавливаем  таймер.

Необходимо внести измененияв код в модуле MainUnit,событие OnNotify проигрывателя:

procedure TMainForm.MPlayerNotify(Sender:TObject);

begin

 if ControlForm.RewSpBtn.Down then

with MPlayer do

 if NotifyValue = nvSuccessful then

 begin

Notify:=true;

   Play;

end;

end;

Здесь происходит проверка, зажата ли кнопка "цикличного воспроизведения" во второйформе.Приоткрытиифайланеобходимо включитьвсекнопкиибегунок(изначально Enabled :=false), запустить таймеры, настроить PosTrkBar на длину записи и вывести названиевоспроизводимого файла в Caption формы:

procedure TControlForm.MediaOpenSpBtnClick(Sender: TObject);

begin

with MainFormdo

 if MediaOpenDlg.Execute then

 begin

   MPlayer.FileName := MediaOpenDlg.FileName;

   MPlayer.Open;

   MPlayer.Display := ScreenPanel;

124


MPlayer.DisplayRect:=Rect(0,0, ScreenPanel.Width, ScreenPanel.Height);

   MPlayer.Play;

   LifeImage.Visible :=not (ExtractFileExt(MPlayer.FileName) = '.avi');

LifeTimer.Enabled:=true;

ControlForm.PosTimer.Enabled:=true;

   ControlForm.PosTrkBar.Max := MPlayer.Length;

ControlForm.PosTrkBar.Enabled:=true;

ControlForm.PlaySpBtn.Enabled:=true;

   ControlForm.PauseSpBtn.Enabled := true;

ControlForm.StopSpBtn.Enabled:=true;

   ControlForm.Caption := MediaOpenDlg.Filename;

end;

end;

14. Добавить к медиапроигрывателю игру«жизнь». Для управления визуализацией потребуется  отдельная  форма.  С  помощью  этой  формы  можно  очищать,  заполнять  и редактировать  конфигурации  клеток игры«Жизнь». Более  того, появляется  возможность сохранять интересные комбинации в специальные файлы с введенным нами расширением

.lif. Кроме того, можно будет управлять скоростью«жизни» и, что уже реализовывалось,

задавать цвет поля и клеток.

Создайте новую форму, сохраните ее модуль, поместите на нее пять кнопок Button, одну SpeedButton, один TrackBar, две надписи Label и диалоги загрузкии сохранения. Изменитепараметры компонент:

LifeSaveDlg: TSaveDialog

DefaultExt=‘lif’

Filter = ‘файлы игры «Жизнь» (*.lif)|*.lif’ Title=‘Загрузить позицию игры’ LifeOpenDlg: TOpenDialog

DefaultExt=‘lif’

Filter = ‘файлы игры «Жизнь» (*.lif)|*.lif’ Options.ofFileMustExist=true

Title=‘Сохранить текущую позицию игры’

Рис. 89.

В модуле второй формы добавьте строки, при открытии файла выводящие или скрывающие третью формуи отпускающиекнопку.

procedure TControlForm.MediaOpenSpBtnClick(Sender: TObject);

begin

with MainFormdo

 if MediaOpenDlg.Execute then

125


 begin

   MPlayer.FileName := MediaOpenDlg.FileName;

   MPlayer.Open;

   MPlayer.Display := ScreenPanel;

MPlayer.DisplayRect:=Rect(0,0, ScreenPanel.Width, ScreenPanel.Height);

   MPlayer.Play;

   LifeImage.Visible :=not (ExtractFileExt(MPlayer.FileName) = '.avi');

LifeForm.Visible:=LifeImg.Visible;

   LifeForm.EditSpBtn.Down := false;

LifeTimer.Enabled:=true;

ControlForm.PosTimer.Enabled:=true;

   ControlForm.PosTrkBar.Max := MPlayer.Length;

ControlForm.PosTrkBar.Enabled:=true;

ControlForm.PlaySpBtn.Enabled:=true;

   ControlForm.PauseSpBtn.Enabled := true;

ControlForm.StopSpBtn.Enabled:=true;

   ControlForm.Caption := MediaOpenDlg.Filename;

end;

end;

На новой формеLifeForm располагаются кнопкиLifeOpenBtn,LifeSaveBtn,FillBtn, ClearBtn, SetColorBtn, EditSpBtn, SpeedTrkBar.Настройтекомпоненты новой формы:

LifeForm: TLifeForm BorderStyle=bsToolWindow Caption = ‘Визуализация’ ClientWidth = 402

ClientHeight = 56

EditSpBtn:TSpeedButton

AllowAllUp = true

Caption = ‘редактировать’ GroupIndex=1

SpeedTrkBar:TTrackBar

Frequency=50

Max=1000

Min = 1

Position = 100

ThumbLength = 15

TickMarks=tmTopLeft

Рис. 90.

В обработчикезагрузки медиафайланеобходимо добавитьследующиестроки.

LifeForm.Visible:=LifeImg.Visible;

ЕслиLifeImg видимый, т.е. нужна визуализация для звукового файла, то форма управления визуализацией тоже выводится, если же LifeImg спрятан (воспроизводится видеофайл), то и присутствиеформыуправления визуализациейизлишне. LifeForm.EditSpBtn.Down := false;

КнопкаEditSpBtnбудетотвечатьзаредактированиеклеток(еслионанажата,включен режимредактирования).ВовремяредактированиятаймерLifeTimerдолженбытьотключен.

126


Посколькуздесь,приоткрытии,мывключаемэтоттаймер,торежимредактированиядолжен быть отключен и кнопкаотпущена.

… MPlayer.Play;

LifeImg.Visible:= not(ExtractFileExt(MPlayer.FileName) = '.avi'); LifeForm.Visible:=LifeImage.Visible;

LifeForm.EditSpBtn.Down := false;LifeTimer.Enabled := true; ControlForm.PosTimer.Enabled:=true;

….

15. Необходимо описать обработчики событий для новых компонентов. Определим при создании формы ее местоположение.

В модуле LifeUnit:

var LifeForm: TLifeForm;

implementation

uses MainUnit, ControlUnit;

procedure TLifeForm.FormCreate(Sender: TObject);

begin

 Top := ControlForm.Top + ControlForm.Height + 4;

 Left := ControlForm.Left;

end;

Принажатиинакнопкиочисткиизаполнениямыиспользуемпроцедуры,описанные в модуле главной формы.

В модуле LifeUnit:

procedure TLifeForm.ClearBtnClick(Sender:TObject);

var

i,j:integer;

begin

 fori:=0 to XSize - 1do

 forj:=0 to YSize - 1do

 A[i, j] := false;

DrawCells;

end;

procedure TLifeForm.FillBtnClick(Sender: TObject);

begin

 RandomCells;

DrawCells;

end;

Однакодлятого,чтобыподобныйвызовбылвозможен,необходимов главноммодуле объявить  эти  процедуры  в  интерфейсе.  Извне  доступно  только  то,  что  объявлено  в интерфейсе. В MainUnit необходимо "вывести" в интерфейсобъявлениепроцедур:

var

MainForm: TMainForm;

   A: TLifeCells; procedure RandomCells; procedure DrawCells;

127


implementation uses ControlUnit;

{&r *.DFM}

ТrackBar устанавливает интервал для таймера, задавая тем самым скорость визуализации. А кнопка редактированияпереключает режимредактирования, останавливаяи включая таймер.

procedure TLifeForm.FillBtnClick(Sender: TObject);

begin

 RandomCells;

DrawCells;

end;

procedure TLifeForm.SpeedTrkBarChange(Sender: TObject); {Меняет скорость«жизни»}

begin

 MainForm.LifeTimer.Interval := SpeedTrkBar.Position;

end;

procedureTLifeForm.EditSpBtnClick(Sender:TObject);{включает/выключает режимредактирования}

begin

 MainForm.LifeTimer.Enabled:=notEditSpBtn.Down;

end;

Само редактирование клеток происходит в главном модуле, в обработчике

OnMouseDown компонента LifeImg.

procedure TMainForm.LifeImgMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

 ifLifeForm.EditSpBtn.Down then

A[X div10, Y div10]:=notA[X div10, Y div 10];

DrawCells;

end;

В uses нужно описать ссылкунаLifeUnit.

При запускепрограммы получается примернотакая картинка.

Рис. 91.

Теперь можно редактировать позиции.

128


         16. Вначале при загрузке и сохранении картинок и прочих файлов использовались специальные методы объектов, в которые происходила загрузка. Теперь произведем эти операции вручную, пользуясьпроцедурами работы с типизированными файлами.

Типизированные файлы содержат записи определенного типа. К примеру,fileof integer может хранить произвольное количество переменных integer;fileof TLifeCells – произвольноеколичествопеременныхтипаTLifeCells.Однакодлянашихцелейдостаточно только одной записи. При работе с типизированными файлами используются следующие процедуры.

AssignFile(varF;FileName:string)–связываетфайловуюпеременнуюFстекстовымименем файла. Этодействиенеобходимо сделать перед всеми последующимиоперациями.

Reset(F) – открывает существующий файл, связанный с переменнойF, и устанавливает позицию чтения-записи в начало.

Rewrite(F)– создает файл, соответствующий файловой переменнойF.

Read(F,V)– читает из файла, связанного сF, данные в типизированную переменнуюV. Позиция файла увеличивается на один файловый компонент, байтовый размер которогоравен размерутипа переменной (для integer это 4 байта).

Write(F,V)–записываетвфайл,связанныйсF,типизированнуюпеременнуюV.Позиция файла увеличиваетсяна один файловыйкомпонент.

Seek(F,N:LongInt)– перемещает позицию файла к номеру N, начальнаяпозиция при N=0.

CloseFile(var F) – закрывает файл F.

В главноммодуле описан тип TFileCells:

{Privatedeclaration}

public

{Publicdeclaration}

end;

const

type

 

XSize = 40; YSize = 25;

         TFileCells =array [0 .. XSize – 1, 0 .. YSize – 1]of  boolean;

var

MainForm: TMainForm;

         A: TFileCells;

ВобработчикеOnClickкнопкиLifeOpenопределяемфайлтакогожетипа.Еслифайл выбранвдиалоге,ассоциируемимяфайласпеременной,устанавливаемпозициюдлячтения вначалоисчитываемизфайладанныевпеременнуюA,описаннуювMainUnitихранящую положения клеток.

procedure TLifeForm.LifeOpenBtnClick(Sender: TObject);

var

 F: file ofTLifeCells;

begin

ifLifeOpenDlg.Executethen

if FileExists(LifeOpenDlg.FileName) then

 begin

   AssignFile(F, LifeOpenDlg.FileName);

Reset(F);

   Read(F, A);

129


   CloseFile(F);

   DrawCells;

end;

end;

Подобное чтение корректно, посколькутипы файла и переменной Aсовпадают.

Призаписивфайлситуацияпохожая,тольковдобавокпроводитсяпроверка,существуетли файл.  Если  нет,  то  он  создается;  если  да,  то  должны  спросить,  действительно   ли пользовательхочетегоперезаписать.Еслионпростоошибся,тозакрываемфайливыходим изобработчика;еслинужнопереписать,открываемегоиустанавливаемпозициюзаписив начало. Затемпроизводится запись переменной и закрытиефайла.

procedure TLifeForm.LifeSaveBtnClick(Sender: TObject);

var

F: file ofTLifeCells;

begin

 ifLifeSaveDlg.Execute then

 begin

   AssignFile(F, LifeSaveDlg.FileName);

   if not FileExists(LifeSaveDlg.FileName)then

     Rewrite(F)

elseif MessageDlg('Перезаписать?', mtWarning, [mbYes, mbNo], 0) = mrYes then

     Reset(F)

elsebegin

     CloseFile(F);

     exit;

end;

Write(F, A);

   CloseFile(F);

end;

end;

Работа  с  нетипизированными  файлами  похожа  на  работу  с  типизированными. Отличиявтом,чтообъявляютсятакиефайлыпростоvarF:file;(безof…),приоткрытии– Reset(F,1)–нужноуказатьразмерблоказаписи(которыйпоумолчаниюравен128),чтение изаписьпроисходятспомощьюпроцедурBlockRead,BlockWirite(varF:File;varBuf;Count: Integer),гдеBuf–переменная,вкоторую(илиизкоторой)идетзапись,Count–числоблоков записи(размер блока был определен вReset). Если надо писать произвольные данные(к примеру,a:integer;b:boolean;c:TLifeCells; d: string[20]),сделайтеследующее.

При записи: Rewrite(F, 1);

BlockWrite(F, a, SizeOf(a)); BlockWrite(F, b, SizeOf(b)); BlockWrite(F, c, SizeOf(c)); BlockWrite(F, d, SizeOf(d)); CloseFile(F);

При чтении, соответственно: Reset(F,1);

BlockRead(F, a, SizeOf(a)); BlockRead(F, b, SizeOf(b)); BlockRead(F, c, SizeOf(c));

130


BlockRead(F, d, SizeOf(d)); CloseFile(F);

17. Чтобы решить проблему цвета, необходимо сделать специальное собственное диалоговое окно, позволяющее выбрать цвет.Раньше мы вызывали стандартныедиалоги.

Диалог– это обычная форма, которая, однако, вызывается специальным методом ShowModalивозвращаетмодальныйрезультат.Модальныйвызовприводитктому,чтопри выведенном диалогенельзяпереключиться никоднойдругойформеприложения,покане будетнажатаоднаизмодальныхкнопокдиалога,послечегодиалогзакроетсяиуправление вернетсявприложение.Модальнымкнопкамдажененадоописыватьобработчики.Просто надоустановить свойство ModalResult не равным mrNone.

Создайтеновую форму, сохранитемодуль как ColorUnit.Добавьте на нее две фигуры Shape (CellShape: TShape, FieldShape: TShape), кнопку «Утвердить» (ModalResult = mrOk), кнопку «Отмена»(ModalResult=mrCancel).

Рис. 92.

Настройте  форму.  В  частности,  задайте  ее  позицию  и  определите  модальный результат для кнопок.

ColorForm: TColorForm BorderStyle=bsToolWindoiw Caption = выберитецвета Position = poScreenCenter

ВобработчикенажатиянафигурыShapeопишитевызовдиалгов.Обработчикидля кнопок можетене описывать.

В модуле ColorUnit – обработчики нажатияна FieldShapeи CellShape: procedure TColorForm.FieldShapeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

 MainForm.FieldColorDlg.Execute;

 FieldShape.Brush.Color := MainForm.FieldColorDlg.Color;

end;

procedure TColorForm.CellShapeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

 MainForm.CellColorDlg.Execute;

131


 CellShape.Brush.Color := MainForm.CellColorDlg.Color;

end;

В обработчике кнопки"задать цвета" на форме визуализации опишите модальный вызов этогонового диалога.

В модуле LifeUnit описываемобработчик SetColorBtn:

procedure TLifeForm.ColorBtnClick(Sender:TObject);

var

 C1, C2: TColor;

begin

 C1 := MainForm.FieldColorDlg.Color;

 C2 := MainForm.CellColorDlg.Color;

 ColorForm.FieldShape.Brush.Color := C1;

 ColorForm.CellShape.Brush.Color := C2;

 if ColorForm.ShowModal = mrCancel then

 begin

   MainForm.FieldColorDlg.Color := C1;

   MainForm.CellColorDlg.Color := C2;

end;

end;

ВданномслучаевызываетсяформаColorForm–диалогустановкицвета.Есливнем нажатакнопка"Отмена",тозначенияцветоввосстанавливаются.Ониспециальнодляэтого перед вызовом сохраняются вC1 и C2.

18. Пользователь проигрывателя может случайно закрыть окно формы управления.

Следователь, придется перезапускать программу.

Можно решить эту проблему следующим образом. При попытке закрытия спросить пользователя, хочет ли он совсем выйти из программы. И если хочет – закрыть главную форму.

procedure TControlForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);

begin

 if MessageDlg('Выйтииз программы?', mtWarning,

 [mbYes, mbNo], 0) = mrYes then MainForm.Close

 elseCanClose:=false;

end;

Этойконструкциейзакрываетсяглавнаяформаизформыуправления.Тожесобытие можно обработать и в главной форме, каждыйраз спрашивая о желании выйти.

Запуститепрограмму.

Рис. 93.

 

132


19. Подведемитоги. Для создания многооконности необходимо:

1. Создать очередную форму.

2. Модули, предназначенные пользователю, поместить в   interface, а модули,

предназначенныепрограммистуто, поместить в uses.

3. Необходимо  помнить  о  круговых  ссылкахи  и  избегать  ignotum per ignotius.  В

интерфейс поместить только необходимое.

4. В OnCreate делать описание, не забываяо порядкесоздания формв файле проекта.

5. Программа  заканчивается,  когда  закрывается  главная  форма.  Остальные  формы приложения могут закрыватьсясколькоугодно.

6. Диалоги: вызов ShowModal, результат – ModalResult нажатой кнопки.

7. Выбрать нужнуюформу или модуль для редактирования можно с помощью кнопок панели  инструментов  или  клавишами  Ctrl-F12  и  Shift-F12.  Переключение модуль- форма – просто клавишей F12.




1. Промышленно развитые страны
2. экономический институт Курсовая работа по дисциплине ldquo;Организация производства
3. Лабораторная работа 8 СТАТИСТИЧЕСКИЙ АНАЛИЗ ДАННЫХ Excel дает возможность собирать и обрабатывать данные
4. Американская социолингвистик
5. Молекулы. Основные положения МКТ.html
6. Реферат- Государственное управление как профессиональная деятельность
7. 17423
8. Производство в апелляционной и кассационной инстанциях
9. Титаник Дирк Питт3 С БЛАГОДАРНОСТЬЮ МОЕЙ ЖЕНЕ БАРБАРЕ ЭРРОЛ БОШАМ ДЖЕНЕТ И РЭНДИ РИХТЕР И ДИ
10. Контрольная работа- Животноводство в сельском хозяйстве