Возьмем, к примеру,
Microsoft Word. У него есть главное внешнее
окно, внутри которого располагаются дочерние
окна, в которых открываются документы.
Предположим, пользователь запустил Word и
редактирует какой-нибудь документ. И вдруг он
где-то в "Проводнике" увидел еще один файл,
который ему срочно нужно редактировать в том же
Word. Юзер два раза кликает по файлу, и опять
запускается Word. Word-копия проверяет,
единственный ли он и неповторимый, или уже есть
его запущенный собрат. Если есть, то он посылает
некое сообщение оригиналу и благополучно
закрывается. Word-оригинал ловит это сообщение и
из него узнает, что нужно открыть такой-то файл,
и открывает его, а пользователь даже и не
заметил, что Word запускался второй раз. Winamp
поддерживает ряд нестандартных сообщений.
Благодаря этим сообщениям существует огромное
количество плагинов к нему и программ, которые
умеют управлять Winamp'ом.
Чтобы послать Winamp'у какое-либо сообщение,
нужно прежде всего определить идентификатор его
окна. Делается это при помощи
WinApi-функции:
FindWindow(lpClassName,
lpWindowName: PChar): HWND;
(здесь и далее используется синтаксис Object
Pascal);
- lpClassName - название
класса искомого окна;
- lpWindowName - заголовок
искомого окна.
Для посылки сообщения используется еще одна
WinApi-функция:
SendMessage(hWnd:HWND;Msg:UINT;wParam:WPARAM;lParam:LPARAM):LRESULT;
- hWnd - идентификатор окна,
которому посылается сообщение;
- Msg - посылаемое сообщение;
- wParam - первый параметр
сообщения;
- lParam - второй параметр
сообщения.
Winamp поддерживает два основных типа
сообщения (параметр Msg):
- WM_COMMAND: служит только для
подачи определенных команд Winamp'у (Play, Stop,
Next, Close и т.д.);
- WM_USER: используется не только для
выполнения действий, но и для определения
различной информации (версия, текущая
композиция, количество композиций и т.д.).
В таблице 1 приведены основные константы для
первого параметра сообщения WM_COMMAND.
Команда |
Описание команды |
40044 |
Кнопка «Prev» |
40048 |
Кнопка «Next» |
40045 |
Кнопка «Play» |
40046 |
Кнопка «Pause» |
40047 |
Кнопка «Stop» |
40157 |
Остановиться после текущей
композиции |
40148 |
На 5 секунд вперед |
40144 |
На 5 секунд назад |
40154 |
Перейти на первую песню Playlist’а (режим
«Suffle» — случайное проигрывание - должен быть
отключен) |
40158 |
Перейти на последнюю песню Playlist’а (режим
«Suffle» должен быть отключен) |
40192 |
Запустить плагин визуализации |
40036 |
Показать/Спрятать эквалайзер |
40040 |
Показать/Спрятать редактор
Playlist’ов |
40258 |
Показать/Спрятать главное окно |
40298 |
Показать/Спрятать мини-браузер |
40022 |
Кнопка «Repeat» |
40023 |
Кнопка «Suffle» |
40188 |
Показать информацию о файле |
40058 |
Увеличить громкость на один
процент |
40059 |
Уменьшить громкость на один
процент |
40001 |
Закрыть
Winamp | |
Для их использования можно применять
процедуру:
Procedure
WinampCommand(Command:Integer); var
WinampHWND:HWND; begin //поиск окна
Winamp'a WinampHWND:=findwindow('Winamp
v1.x',nil); //если поиск успешен, то
посылаем сообщение if
WinampHWND<>0 then
SendMessage(WinampHWND, WM_Сommand, Command,
0); end;
Теперь для подачи сообщения типа WM_COMMAND
нужно выбрать из таблицы понравившуюся константу
и передать ее в качестве параметра процедуре
WinampCommand. Пример:
WinampCommand(40044); - переход к
предыдущей композиции.
В таблице 2 перечислены основные константы
для сообщений WM_USER.
Id |
Data |
Пояснения |
0 |
0 |
Возвращает версию Winamp’а |
102 |
0 |
Начать проигрывать выбранную в playlist’е
композицию |
104 |
0 |
Возвращает статус проигрывания: 1 — играет,
3 — пауза, иначе остановлен |
105 |
0 |
Возвращает в миллисекундах позицию
проигрывания |
105 |
1 |
Возвращает в секундах длину
композиции |
121 |
n |
Выбирает в playlist’e композицию под номером
n |
122 |
n |
Устанавливает громкость в значение n (от 0
до 255) |
123 |
n |
Устанавливает баланс в значение n (от 0 до
255) |
125 |
0 |
Возвращает позицию текущей песни в
playlist’е |
126 |
0 |
Возвращает samplerate (частоту
дискретизации) |
126 |
1 |
Возвращает bitrate (скорость передачи
информации) |
126 |
2 |
Возвращает количество каналов (1 — моно, 2 —
стерео) |
135 |
0 |
Перезагружает Winamp (например, для
подключения нового
плагина) | |
Для их использования запишите следующую
функцию:
Function WinampUser(data:Integer,
id:Integer):integer; var
WinampHWND:HWND; begin WinampHWND:=findwindow
('Winamp v1.x', nil); if
WinampHWND<>0 then
result:=SendMessage (WinampHWND,WM_USER,data,
id) else
result:=-1; end;
Пример:
WinampUser(1, 105); - возвращает
длину текущей композиции в
секундах.
Управлять Winamp'ом мы уже научились, это
умение пригодится для написания плагинов к
нему.
Плагины к Winamp'у бывают пяти видов:
- Input - плагины для проигрывания различных
форматов;
- Output - для записи музыки в различных
форматах;
- General Purpose - плагины общего назначения,
в них наиболее часто используются сообщения,
которые мы рассмотрели выше;
- DSP/Effect - для обработки звука;
- Visualization - плагины, которые делают
что-нибудь в такт музыке.
На сайте http://www.winamp.com/ можно
скачать шаблоны всех типов плагинов. Для примера
рассмотрим маленький визуализационный плагин,
который заставит мигать лампочки Num Lock, Caps
Lock и Scroll Lock в такт музыке. Для этого
воспользуемся соответствующим шаблоном
(vis_minisdk). В нем присутствует функция
Render, которая через заданный промежуток
времени получает от Winamp'a информацию о
текущих уровнях частот проигрываемой музыки.
Остается только написать обработчик этих
данных:
{Если плагин пишется не на C, то не следует
забывать, что параметры процедур должны
передаваться так же, как в этом языке. Поэтому в
данном случае нужно использовать служебное слово
cdecl (c-declaration)}
function Render(this_mod: PwinampVisModule):
integer;cdecl;
//внутренняя процедура, которая будет
гаситьзажигать нужные
лампочки Procedure SetLock(n,
state:byte); var KS:
TKeyboardState; c:
byte; begin //смотрим, с
какой лампочкой будем работать case n
of 0:
c:=VK_NUMLOCK; 1:
c:=VK_CAPITAL; 2:
c:=VK_SCROLL; end; //в
зависимости от параметра state, зажигаем либо
гасим лампочку
GetKeyboardState(KS);
KS[c]:=state;
SetKeyboardstate(KS); end;
var
i:byte; begin //в зависимости от
уровня звука,
гасимзажигаем //соответствующие
лампочки for i:=0 to 2 do if
this_mod.spectrumData [0,i]>40 then
SetLock(i, 1) else SetLock(i,
0); result:=0; end;
Весь исходный код и готовый плагин можно
найти на странице www.IvanFDC.narod.ru/download.html.
Хочу отметить, что данный плагин управляет
только состоянием лампочек, а сами клавиши не
трогает. Поэтому при использовании плагина можно
набирать текст безо всяких проблем.
Как видим, всю работу по обработке звука
Winamp берет на себя, поэтому создавать плагины
к этому популярнейшему плееру может даже
человек, весьма далекий от музыки. |