Как Winamp принимает сообщения
Думаю многие создавали маленькие программки, которые позволяют управлять популярным плеером Winamp, ну или хотябы с этим разбирались. Для тех, кто еще не в курсе этого поясню. Работа операционной системы сопровождается посылкой огромного числа сообщений. Сообщение это нечто подобное команде. Если вы переместили мышку - посылается сообщение, изменили размер окна - снова сообщение, закрыли окно - опять сообщение. Без сообщений работа операционной системы невозможна. Каждая программа принимает эти сообщения и обрабатывает. Большинство сообщений можно обрабатывать без особых усилий и знаний с помощью интерфейса Delphi, такие как клики по кнопке, двойные клики, наведения и другое. Также программно можно послать любое сообщение любому окну, достаточно знать его дескриптор. Дескриптор это что-то вроде адреса. При создании окна, ОС наделяет его дескриптором, который уникален.
Естественно, можно послать любое сообщение любому окну, например, сообщение о том, чтобы окно изменило положение и размеры.
Примерно такая технология и используется в Winamp. Он обрабатывает сообщения определенного рода и выполняет инструкции которые несут эти сообщения. Например, остановить воспроизведение, возобновить и так далее.
В этой статье будет написано два приложения: одно будет отсылать сообщение, а другое принимать. Приступим.
Создайте новый проект. Сохраните. Теперь нужно будет написать код для обработки сообщения. Добавьте в раздел public:
procedure WMCommand(var Message: TMessage); message WM_Command;
|
Теперь нужно написать саму процедуру:
procedure TForm1.WMCommand(var Message: TMessage);
begin
inherited;
Caption := 'Принято: ' + IntToStr(message.LParam);
end;
|
Что и как тут делается? Все очень просто, message это структура, что пришла в программу. LParam это то, что именно нас интересует и что мы будем передавать в дальнейшем.
Далее нужно переименовать форму, например, в GetMessage. Потом используя это имя будем отсылать сообщение.
На этом с первым приложением все. Сохраните этот проект, он нам еще понадобится, и создайте новый.
Выкладываем на форму Button и Edit. В Edit будем вводить число, далее жмем кнопку и это число будет отправлено первой программе.
Теперь нужно написать функцию отсылки сообщения:
Function MyCommand(Command: Integer): boolean;
var H:HWND;
begin
H := FindWindow('TGetMessage', nil);
if H <> 0 then
begin
SendMessage(H, WM_Command, 0, Command);
result := True;
end
else
result := false;
end;
|
Теперь о том как это работает. В переменной H будет храниться дескриптор первой программы. Но он там не появится просто так - его нужно будет получить. Для его получения используем функцию FindWindow . Вот тут нам и понадобится имя той формы - GetMessage. По этому имени дается имя классу, просто добавляется буква T. Конечно, можно просто указать название окна программы, но ведь такое окно может уже быть где-то еще.
Далее идет проверка, получили ли мы дескриптор или нет. Если в H число отличное от 0, то что-то получили. А раз получили отсылаем по полученному дескриптору сообщение Command при помощи функции SendMessage.
Теперь создаем обработчик onClick кнопки. Там пишем:
procedure TForm1.Button1Click(Sender: TObject);
begin
if MyCommand(StrToint(Edit1.Text)) = false then
showmessage('Отсылка не удалась');
end;
|
Тут все еще легче. Вызываем только что написанную функцию, а в качестве параметра подаем то, что находится в Edit.
Запускаем обе программы, вводим в Edit число жмем кнопку и заголовок в первой программе должен измениться. Как обрабатывать конкретное сообщение уже решает каждый сам. На этом все.