IGROMANIA.RU
Registration
MoreLess
Популярные за неделю
Популярные за месяц
Ассасины и тамплиеры на большом экране. Фильм «Кредо убийцы» Кино > Ассасины и тамплиеры на большом экране. Фильм «Кредо убийцы»
Ассасины и тамплиеры на большом экране. Удался ли эксперимент?
Комментариев: 45
    В прошлый раз мы создали многофункциональный медиа-комбайн. Сегодня мы сделаем из него супермашину, способную если не по удобству, то по возможностям заткнуть за пояс такого гиганта, как Windows Media Player.
    Давайте немного помечтаем. Что сможет делать наш комбайн? Во-первых, он без лишних проблем откроет файлы форматов dib, jpg, bmp, ico, emf, wmf, avi, wav, mid и уникальный формат плейлистов — list. Во-вторых, он все эти файлы может микшировать в плейлисты, которые, в свою очередь, без проблем можно будет сохранить на винчестере. Комбайн организует слайд-шоу и даже создает презентации с музыкой и видео. Всеми этими процессами несложно управлять с удобной панельки. Есть даже независимое — чтобы перетаскивать с помощью мышки — окошко вывода. Скорость пролистывания слайдов можно изменять.
    Доставайте из заначки исходники недоделанного комбайна — и продолжим. Если по каким-то причинам вы не читали статью позапрошлого номера “Мании”, не отчаивайтесь — материал ждет вас в разделе “ИнфоБлок” нашего CD- или DVD-диска. Там же разместились исходники комбайна.

8 Kb
Чтобы создать подобное
окошко, потребуется не более
трех минут.
   В дорогу дальнюю...
   
В прошлой статье мы остановились на пункте меню Запустить слайд-шоу. С него и продолжим. Допустим, пользователь желает запустить слайд-шоу. Создайте обработчик события для этого пункта меню (у меня он называется
TForm1.N11Click). Для начала введите глобальную переменную, которая показывает, запущено слайд-шоу или нет. Назовите ее is_show. В глобальный раздел Var добавьте описание этой переменной:
    is_show:boolean=false;
   
По умолчанию значение переменной установите в “ложь”, ведь изначально слайд-шоу отключено. Помните, в прошлый раз мы решили не вводить дополнительный пункт меню для остановки слайд-шоу? Вместо этого давайте сделаем так, чтобы при его запуске название пункта меню изменилось на Остановить слайд-шоу. Как это сделать? Сначала необходимо “переключить” переменную is_show. То есть если ее значение true, установить его в false и наоборот. Быстрее всего это сделать строчкой:
    Is_show:= not is_show;
   
Логический оператор not как раз переключает переменные. Теперь, в зависимости от значения переменной is_show, надо задать надпись пункту меню. Давайте создадим элементарную конструкцию выбора case с переменной is_show в качестве селектора. Вариантов всего два: true и false. Если значение переменной is_show равно true, то слайд-шоу уже запущено и его необходимо остановить. Если же false, то слайд-шоу надо, наоборот, запустить. Вот участок кода, который это реализует:
    case is_show of
    true:N11.Caption:='Остановить слайд-шоу';
    false:N11.Caption:='Запустить слайд-шоу';
    end;
   
Теперь, если слайд-шоу запускается, надо показать первый элемент в списке воспроизведения. Мы уже делали это, когда создавали обработчик для пункта меню Открыть... Зачем делать одну и ту же работу дважды? Скопируйте участок кода, который отвечает за загрузку:
    if form1.listbox1.ItemIndex<0 then form1.listbox1.ItemIndex:=0;
    s:=ExtractFileExt(opendialog1.FileName);
    if (s='.dib') or (s='.jpg') or (s='.jpeg')
   
17 Kb
Плеер в действии.
Проигрывается трейлер к
популярной игре.
or (s='.bmp') or (s='.ico') or (s='.emf') or (s='.wmf') then
    begin
    Form2.Hide;
    Form3.image1.picture.loadfromfile(opendialog1.filename);
    Form3.Width:=Form3.image1.Picture.Width;
    Form3.Height:=Form3.image1.Picture.Height;
    Form3.image1.picture.loadfromfile(opendialog1.filename);
    Form3.Image1.Visible:=true;
    Form3.show;
    end;
    if (s='.avi') or (s='.wav') or (s='.mid') then begin
    Form2.Show;
    Form3.Hide;
    if s='.avi' then Form3.Show;
    Form3.Image1.Visible:=false;
    Form2.Mediaplayer1.Display:=Form3.Panel1;
    Form2.MediaPlayer1.FileName:=opendialog1.FileName;
    Form2.MediaPlayer1.Open;
    Form3.Width:=Form2.MediaPlayer1.DisplayRect.Right-Form2.MediaPlayer1.DisplayRect.left;
    Form3.Height:=Form2.MediaPlayer1.DisplayRect.Bottom-Form2.MediaPlayer1.DisplayRect.Top;
    Form2.MediaPlayer1.play;
    end;

   
В таком виде код еще неработоспособен. В нем нет переменной s. Поэтому объявите ее в локальном разделе var:
22 Kb
В окошке открытия файла
теперь можно выбрать одну из
четырех групп типов файлов,
которые поддерживает
программа.

    s:string;

   
Осталась лишь одна проблема: откуда брать имя файла, который требуется открыть? Ведь никакого оператора opendialog нет. Если пользователь запустит слайд-шоу, то начаться оно должно с текущей выделенной строки в ListBox1. Как получить индекс выделенной строки? Очень просто: listbox1.ItemIndex. Следовательно, как получить содержимое выделенной строки (по совместительству искомое имя файла)? Еще проще: listbox1.Items.Strings[listbox1.ItemIndex].

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

    If is_show then begin
    // ваш код
    end;

   
Почему условие выглядит так непривычно? Дело в том, что
для переменных типа boolean условие вида переменная=true можно сократить просто до имени переменной. Это очень удобно.
    Между операторами условия begin и end вставьте скопированный код. На протяжении всего кода замените функцию opendialog1.filename на listbox1.Items.Strings[listbox1.ItemIndex]. После этого скрипт заработает.

   Основные переключатели
   
Пришло время обеспечить переключение файлов во время слайд-шоу. К картинкам и активным файлам (видео и звук) подход различен. Если текущий файл — картинка, перед запуском следующего пункта Listbox1 надо сделать время задержки (хранится в переменной M). С видео и звуками дело обстоит по-другому. Следующий файл надо запустить не через какое-то определенное время (откуда мы знаем, как долго длится клип?), а когда текущий клип завершится.
    Давайте рассмотрим эти два варианта по порядку. Начнем с картинок. Как организовать задержку? Для этого существует специальный невизуальный компонент Timer. Самый первый на вкладке System. Найдите его и поместите в любое место на форме. Соответствующий объект будет называться Timer1. Поначалу таймер должен быть отключен, поэтому его свойство Enabled установите в false. У таймера одно-единственное событие — OnTimer, которое срабатывает, как только время, задающееся свойством Interval, истечет. Не забудьте, что время задается в миллисекундах (одна тысячная секунды). Как только пользователь включает слайд-шоу, нам надо запустить таймер. В обработчике N11Click найдите второе условие (текущий объект — картинка) и после строчки Form3.show пропишите:
    Timer1.Interval:=M*1000;
    Timer1.Enabled:=true;
53 Kb

   
Почему “M*1000”? В миллисекундах время считают только совсем уж крутые программисты. А пользователь, скорее всего, будет
вводить время в привычных секундах. Отсюда это простое преобразование.
    Таймер запущен. Как только он сработает, мы должны его выключить (до поры до времени), выделить следующую строчку в списке и запустить этот файл стандартным куском кода.
    Создайте обработчик события таймера Timer1Timer и пропишите для него код:
    Timer1.Enabled:=false;
    if listbox1.Items.Count-1=listbox1.ItemIndex then
    listbox1.ItemIndex:=0 else listbox1.ItemIndex:=listbox1.ItemIndex+1;
   
Это еще не все содержимое обработчика Timer1Timer, но к нему мы вернемся после. У вас, скорее всего, возник закономерный вопрос: зачем нужно условие во второй строчке? Почему бы просто не присвоить единицу свойству ItemIndex? Представьте себе, что после нескольких слайдов указатель выделения списка дойдет до его конца. Очередной командой приращения указатель сдвинется... на несуществующую строку. Естественно, возникнет критическая ошибка, и программа вылетит. Поэтому перед приращением необходимо проверить, не добрался ли счетчик до конца списка. Если добрался, то указатель выделения (свойство ItemIndex) обнуляется, если нет — увеличивается на единицу. Вот и все премудрости.

   Окольные дорожки

   
Перейдем ко второму варианту. Что, если очередной файл из списка воспроизведения — не картинка, а звуковой или видеоклип? В этом случае необходимо дождаться его завершения, а потом открыть следующий в списке файл. Как узнать, что клип подошел к концу? Есть много способов. Но самый простой, на мой взгляд, — воспользоваться обработчиком события компонента TmediaPlayerOnNotify. Это событие срабатывает, когда меняется режим работы медиа-плеера. Сам режим можно определить с помощью свойства Mode. Нам интересно только одно его значение — mpStopped. Как вы уже догадались, оно показывает, что плеер
остановился, потому что клип закончился.
44 Kb
Все пять форм программы

    Когда клип не проигрывается, режимы тоже могут меняться. Поэтому появятся неизбежные ложные срабатывания обработчика. Эти ложные срабатывания надо как-то устранить. Самое простое — ввести еще одну переменную и установить ее в положение true непосредственно перед началом воспроизведения. Внутри обработчика OnNotify необходимо проверить состояние переменной Mode и новой булевой переменной. Если обе проверки проходят — воспроизведение точно прекратилось, и можно переключаться на следующий файл списка. Объявите эту вспомогательную глобальную переменную:
    video:boolean=false;
   
По умолчанию она “выключена”. Где ее включать? В нашем коде, который отвечает за последовательное воспроизведение. Вновь открывайте обработчик N11Click и во второй условной ветке после строчки Form2.MediaPlayer1.play пишите:
    video:=true;
   
Теперь предусмотрены почти все варианты действий пользователя, за исключением одного — когда юзер кликает по пункту меню Остановить слайд-шоу. Так как программно этот пункт меню находится в N11Click, надо изменить первое его условие. Найдите предпоследний оператор end обработчика и удалите точку с запятой. Прямо после end пишите:
    else begin
    Timer1.Enabled:=false;
    video:=false;
    end;
   
Теперь, если переменная is_show не равна true (то есть равна false), слайд-шоу остановится. Выключите таймер и переменную video. Обработчик N11Click готов. В конечном варианте он выглядит так:
    procedure TForm1.N11Click(Sender: TObject);

    var
    s:string;
    begin
    Is_show:= not is_show;
    case is_show of
    true:N11.Caption:='Остановить слайд-шоу';
    false:N11.Caption:='Запустить слайд-шоу';
36 Kb
Код, обслуживающий форму
№ 4, запрашивающую у
пользователя время задержки

    end;
    if is_show then begin
    if
form1.listbox1.ItemIndex<0 then form1.listbox1.ItemIndex:=0;
    s:=ExtractFileExt(listbox1.Items.Strings[listbox1.ItemIndex]);
    if (s='.dib') or (s='.jpg') or (s='.jpeg')
    or (s='.bmp') or (s='.ico') or (s='.emf') or (s='.wmf') then
    begin
    Form2.Hide;
    Form3.image1.picture.loadfromfile(listbox1.Items.Strings[listbox1.ItemIndex]);
    Form3.Width:=Form3.image1.Picture.Width;
    Form3.Height:=Form3.image1.Picture.Height;
    Form3.image1.picture.loadfromfile(listbox1.Items.Strings[listbox1.ItemIndex]);
    Form3.Image1.Visible:=true;
    Form3.show;
    Timer1.Interval:=M*1000;
    Timer1.Enabled:=true;
    end;
    if (s='.avi') or (s='.wav') or (s='.mid') then begin
    Form2.Show;
    Form3.Hide;
    if s='.avi' then Form3.Show;
    Form3.Image1.Visible:=false;
    Form2.Mediaplayer1.Display:=Form3.Panel1;
    Form2.MediaPlayer1.FileName:=listbox1.Items.Strings[listbox1.ItemIndex];
    Form2.MediaPlayer1.Open;
    Form3.Width:=Form2.MediaPlayer1.DisplayRect.Right-Form2.MediaPlayer1.DisplayRect.left;
    Form3.Height:=Form2.MediaPlayer1.DisplayRect.Bottom-Form2.MediaPlayer1.DisplayRect.Top;
    Form2.MediaPlayer1.play;
    video:=true;
    end;
    end
    else begin
    Timer1.Enabled:=false;
    video:=false;
    end;
    end;
16 Kb
Вместо того чтобы делать новое
окошко О программе..., модно
взять стандартное окошко
Delphi и лишь слегка отредакти-
ровать в нем надписи. В Delph
i 6 это делается через опцию
File/New/Other/Forms/About
box.
    В обработчиках не хватает только операции запуска плеера. У нас уже есть готовый кусок кода для этого действия. Скопируйте его из N11Click, начиная со строки s:=ExtractFileExt(listbox1.Items.Strings[listbox1.ItemIndex]) и заканчивая предпоследним end.
    Перейдите в обработчик таймера и после последней команды вставляйте скопированный код. Не забудьте в локальном операторе var объявить строковую переменную s. Перейдите в OnNotify и пишите:
    if video and (mediaplayer1.Mode=mpStopped) then begin
    end;
   
Это условие мы уже детально разобрали. Между begin и end вставляйте код. Не забудьте объявить локальную строковую переменную s.
    Код мы поместили в другой модуль, а ссылаемся мы из этого кода на некоторые объекты первого модуля. Значит, второй модуль надо связать с первым. Перед самым обработчиком добавьте строку:
    uses unit1;
   
Теперь перед всеми упоминаниями listbox1 и Timer1 поставьте выражение form1. (прописывается слитно). Во второе условие обработчика (которое отвечает за ветвь картинок) вставьте строку:
    video:=false;
   
Запускайте медиа-комбайн и слайд-шоу. Все должно функционировать.

   Штрихи к портрету
   
Пришло время придать законченный вид комбайну. У нас осталось два необработанных пункта меню: Справка и О программе. Когда пользователь кликает по пункту Справка, должен открыться справочный файл программы в формате hlp (стандартная) или chm (продвинутая). Создание самого файла справки остается на вашей совести. Для этого существует множество программ, например ориентированный на любителей HTM2CHM или профессиональный HTML Help Workshop. Задача программиста — прописать в обработчике этого пункта меню открытие файла справки. Соответствующий обработчик выглядит так:
    procedure TForm1.N13Click(Sender: TObject);
    begin
    ShellExecute(Application.Handle,'open',PChar(extractfilepath(application.exename)+' help.hlp’),nil,nil,SW_SHOWNORMAL);
    end;
60 Kb
Одна из самых длинных
процедур в медиа-комбайне.
Но не так страшен черт, как
его... исходники! Стоит
разобрать “монстра” по
строчкам, и он становится
милым и пушистым.

   
Он состоит из одной довольно сложной команды. Ее основа — функция ShellExecute, которая позволяет открыть любую папку, документ (в том числе веб-страницу), выполнить некоторые системные команды, а также запустить программу или скрипт. Вот такая
функция-многостаночник. Рассмотрим ее поподробнее (не забудьте в текущий раздел uses добавить модуль ShellAPI, которому принадлежит функция).
    Первый параметр функции ShellExecuteдескриптор программы, которая осуществляет вызов. Пока не будем детально изучать, что такое дескриптор, иначе мы рискуем углубиться в основы API и ядра Windows. Неподготовленный программист там просто потеряется. Но в ближайших номерах мы обязательно рассмотрим ядро и API. Без этих знаний программист никогда не сможет стать профессионалом. Пока же вам будет достаточно знания, что дескриптор — это своеобразный индекс, который указывает на конкретную программу. Зная дескриптор программы, с ней несложно совершить практически любое действие. Получить дескриптор программы можно через свойство Application.Handle.
    Второй параметр — текстовая строка, содержащая один из трех стандартных методов работы с файловыми объектами: open, print и explore. Open и print работают почти со всеми файлами, а explore —только с папками. Open открывает документ, запускает другую программу или исполняет системную команду, print печатает документ, а explore открывает папку в окне Проводника. Сейчас нам нужно открыть файл справки как документ, поэтому выбираем метод open.
    Третий параметр — это путь к открываемому документу. Выражение extractfilepath(application.exename) вам уже знакомо — оно возвращает путь до конкретной программы, чтобы можно было адресоваться к файлам, которые лежат в той же папке.
    Далее следует указание на имя конкретного файла. Почему все выражение упрятано в скобки и перед ним стоит странный операнд Pchar? Дело в том, что Object Pascal (Delphi) — не “родной” язык программирования для Windows. Традиционно программы для него писались на C++. Само ядро
13 Kb
Программа с заполненным
плейлистом
и API также написаны по большей части на С++, поэтому унаследовали особенности этого языка.
    В С++ нет переменных типа String. Зато есть массивы символов (тип Char). Каждая строка оканчивается так называемым терминатором (знаком #0). Поэтому при вызове функций ядра все строки приходится конвертировать в тип PChar (указатель на область памяти, занятый массивом типа Char). Для этого служит команда Pchar, которой мы воспользовались.
    В четвертом параметре хранятся параметры запуска. Так как мы запускаем не программу, этот параметр надо забить нулем — nil.
    Пятый параметр также забиваем nil, потому что в нем должен храниться путь к рабочей папке программы.
    Последний параметр — переменная, которая показывает, как должно отображаться на экране окно программы или документа после запуска. Нам нужен стандартный запуск, поэтом ставим сюда значение SW_SHOWNORMAL.
    Код для пункта меню О программе вы уже сможете написать самостоятельно — действуя по аналогии.

    * * *

   
В вашем распоряжении мощнейший медиа-комбайн, который разве что носки не стирает и кашу не варит. Это и мощный слайд-шоу-генератор, и утилита для создания презентаций. Вы ждете домашних заданий? Их есть у нас. В комбайне во многих местах не проверяются вводимые значения. Например, если в окошке задания задержки для слайдов ввести не число, а букву, программа вылетит. Или, если открыть файл не того типа, появится сообщение об ошибке. Перехватить все эти ошибки и поставить надежную “защиту от дурака” — ваша главная задача. Также можете несколько усовершенствовать комбайн, например добавить поддержку формата mp3. Но для этого вам придется обращаться к сторонним компонентам, так как в Delphi такой поддержки нет.
    В следующей статье, посвященной Delphi, мы займемся программированием оболочки для компакт-диска.
2016-й выдался удачным для всех тех, кто предпочитает нападать на врагов со спины или вообще обходить их стороной.
Игр с открытыми мирами с каждым годом выходит все больше и больше, но в каких из этих миров у игроков больше всего возможностей?
Ассасины и тамплиеры на большом экране. Удался ли эксперимент?
Кооперативных игр в 2016 году хватало. Но какие из них действительно достойны внимания?
Комментарии к статьям
Войти и прокомментировать                Войти под логином игромании | Зарегистрироваться
Самые комментируемые статьи за месяц:
Кино > Ассасины и тамплиеры на большом экране. Фильм «Кредо убийцы»
Спец > Лучший мой подарочек — это Xbox One S!
Спец > Достать геймпад и плакать: игры, берущие за душу: от Ori and the Blind Forest и This War Of Mine до BioShock Infinite и Life is Strange
Спец > Игра в кубики. В чем сила Minecraft?
Рецензии > Соборы в небесах. Обзор Space Hulk: Deathwing
Спец > Влюбиться в убийцу: история серии Assassin’s Creed
Железный цех > В ожидании ZEN. Тестируем игровой компьютер Edelweiss MSI Edition на базе AMD 970
Спец > Горячий осенне-зимний сезон Windows Store. Главные игровые новинки
Спец > На скорости 160 км/ч, или Как работают гоночные игры
Прямым текстом > Darksiders: Warmastered Edition — жизнеспособное чудище Франкенштейна
Поиск по сайту Игровые платформы: PC  |   X360  |   XONE  |   PS3  |   PS4  |   Wii  |   Wii U  |   PSP  |   Vita  |   NDS  |   3DS  |   Android  |   iOS
1997-2017 ООО «Игромедиа». Мнение авторов и посетителей сайта может не совпадать с мнением редакции. Полное или частичное воспроизведение материалов сайта и журнала допускается только с согласия редакции. Для прямого контакта с редакцией пишите на основную почту «Игромании.ру».
Пользовательское соглашение

КОММЕРЧЕСКИЕ ССЫЛКИ:
Механизм выбора платформы позволяет отображать на страницах информационного портала материалы, относящиеся строго к выбранным платформам.

Каждый пользователь индивидуально выбирает для себя интересующие его игровые платформы.
 
Rambler's Top100 Яндекс цитирования