Skype — это один из самых популярных сервисов обмена быстрыми сообщениями и интернет-голосовой и видео связи. Количество клиентов и возможностей, которые им предлагает Skype растут с каждым днем. На мой взгляд — это самое время научиться использовать Skype в своих целях.
Дистанционное управление
Skype ранее принадлежал компании Skype Limited, а после был выкуплен Microsoft`ом. Microsoft активно участвуют в развитии проекта: в частности, к их достижениям можно отнести редизайн веб сайта и разработку интерфейса Windows 8 (хоть и с большим числом ошибок, которые, я надеюсь, будут исправлены). Однако одно остается традиционным: в разработке Skype участвует лишь компания-правообладатель. Однако, в отличии от многих других проектов, Skype не против, чтобы разработчики всего мира улучшали его для себя и дорабатывали для более удобной работы в той или иной обстановке. Любое приложение может подключиться к активному клиенту Skype, а после чего отправлять ему команды и следить за его работой. Применений этой возможности можно найти много: начиная от темных, вроде перехвата сообщений или их отправки от чужого имени, заканчивая созданием средств для Skype рассылок, использования Skype протокола для связи между сервером и клиентом, создания Skype-ботов и.т.д.
В этой статье я расскажу о некоторых приемах дистанционного управления Skype через Delphi. Более подробную информацию можно найти на официальном сайте.
Подключение
Первое, с чего начинается управление клиентом — это подключение к нему. Создайте в Delphi новый проект и поместите на форму кнопку «Подключиться» (Button1). Перейдите к обработчику события клика по кнопке (onClick) и введите в него следующий код:
SkypeWindowHandle := 0;
MsgAttach:=RegisterWindowMessage('SkypeControlAPIAttach');
MsgDiscover:=RegisterWindowMessage('SkypeControlAPIDiscover');
PostMessage(HWND_BROADCAST, MsgDiscover,HandleEx, 0);
В первой строке инициализируется переменная SkypeWindowHandle. В более новых версиях Delphi инициализация не требуется, но я оставил эту строку на всякий случай. В будущем эта переменная нам понадобится. Далее в системе регистрируются два сообщения: SkypeControlAPIAttach и SkypeControlAPIDiscover. Ссылки на них сохраняются в переменных MsgAttach и MsgDiscover. Первое мы используем чуть позже, а второе используется уже в четвертой строке. В ней происходит отправка нашего сообщения всем приложениям. Все программы, кроме Skype проигнорируют его, а сам Skype начнет процедуру соединения с нашей программой.
Прямо сейчас этот код не скомпилируется. Для успешной компиляции добавьте объявление переменных после ключевого слова var в секции interface следующим образом:
var
MsgAttach : LongWord;
MsgDiscover : LongWord;
SkypeWindowHandle : HWND;
Получив наше сообщение Skype отобразит пользователю уведомление о том, что некая программа пытается получить доступ к нему. Это уведомление выглядит примерно так:
[942x259]В случае использования соединения для легальных целей это вполне приемлемо. В противном случае необходимо реализовать автоматическое подтверждение. Сделать это можно путем активации ока Skype специальными Api функциями и последующим поиском нужной кнопки на экране и эмулированию клика мыши по ней. Приводить этот код я не буду, однако он не сложен.
После получения разрешения? Skype ответит нам встречным сообщением, а наша задача его принять и обработать. Добавьте в секции public описания объекта формы функцию ProcessMessages следующим образом:
Function ProcessMessages (var Msg : TMessage) : Boolean;
Эта функция будет автоматически вызвана при поступлении сообщения, а само сообщение будет находиться в переменной Msg. Нажмите Ctrl+Shift+C для того, чтобы Delphi подготовила реализацию функции. Внесите в нее следующий код:
if (Msg.Msg = MsgAttach) Then
Begin
SkypeWindowHandle := Msg.WParam;
Case Msg.LParam of
0 : ShowMessage('Соединение установлено');
2,3 : ShowMessage('Произошла ошибка');
End;
Result := true;
Exit;
End;
if (Msg.Msg = WM_COPYDATA) and (HWND(Msg.WParam) = SkypeWindowHandle) Then
Begin
RecvCommand(PAnsiChar(PCopyDataStruct(Msg.LParam).lpData));
Msg.Result := 1;
Result := true;
Exit;
End;
Result := False;
Skype ответит нам тем сообщением, что храниться у нас в переменной MsgAttach. Первым делом выполняется проверка, является ли это сообщение таковым. Далее из сообщения извлекается ссылка на окно Skype и сохраняется в переменной SkypeWindowHandle. Затем из сообщения извлекается результат соединения. Если он равен нулю, то соединение успешно. Иначе — произошла ошибка (например, пользователь отклонил запрос). Далее регистрируется успех принятия сообщения и выполняется выход из функции.
Далее программе понадобиться принимать и другие сообщения от Skype. Их прием реализован ниже. В начале проверяется, поступило ли это сообщение от Skype, путем проверки переменной SkypeWindowHandle. Затем вызывается функция, которая будет обрабатывать сообщение и аналогично регистрируется успех и выполняется выход.
Прием сообщений
Как я отметил выше, для обработки сообщений будет использована функция RecvCommand. Самое время реализовать ее. Для этого вернитесь в секцию public и допишите в ней:
Procedure RecvCommand (Cmd : PAnsiChar);
Снова нажмите Ctrl+Shift+C и внесите в реализацию процедуры следующий код:
Memo1.Lines.Add('Skype: '+cmd);
Этот код выведет сообщение в редактор Memo1. Добавьте его на форму. Самое время запустить программу на выполнение. Нажмите кнопку «Подключиться» и подтвердите подключение. Далее попробуйте менять статус, делать звонки и отправлять сообщения. Вы убедитесь, что каждое действие отображается в Memo. Теперь попробуем дать команду…
Отправка сообщений
И снова вернитесь к секции public. Теперь внесите в нее описание функции отправки сообщений:
Procedure SendCommand (Cmd : AnsiString);
Аналогично создайте обработчик и впишите в него следующее:
Procedure TSkype.SendCommand(Cmd: AnsiString);
Var CopyData : CopyDataStruct;
StrBuff : Array [0..1023] of AnsiChar;
I : Integer;
Begin
if SkypeWindowHandle = 0 Then Exit;
CopyData.dwData := 0;
CopyData.cbData := Length(Cmd) + 1;
CopyData.lpData := @StrBuff;
for I := 1 to CopyData.cbData do StrBuff[I-1] := Cmd[I];
StrBuff[CopyData.cbData] := #00;
Windows.SendMessage(SkypeWindowHandle, WM_COPYDATA,HandleEx, LPARAM(@CopyData));
End;
Обратите внимание, что я привел не код внутреннего содержимого обработчика, а обработчик полностью. Первое, что он делает — это проверяет, установлено ли соединение. Это легко сделать, сверив ссылку на окно Skype с нулем. Далее подготавливается к отправке сообщение из переменной Cmd и выполняется отправка. Столь сложная процедура подготовки обусловлена тем, что формат, в котором со стоками работает Windows несколько отличается от стандартов Delphi.
Hello World!
Наконец, переходим к профиту. Поместите на форму еще одну кнопку — «Отправить»,а так же поле вводе TEdit. Эта кнопка будет отправлять Skype содержимое поля. В обработчике нажатия кнопки введите этот код:
SendCommand(Edit1.Text);
Тут, я думаю, не требуются комментарии. Запустите программу и выполните соединение. Теперь наберите в поле ввода SEARCH CHATS и нажмите «Отправить». В Memo появится перечень идентификаторов всех чатов Skype. Скопируйте любой из них и введите новую команду: SENDMESSAGE ID Hello, how are you?. Здесь ID — это скопированный ID. Команда отправит сообщение в чат.
Аналогичным образом можно совершать звонки, отправлять файлы и.т.д. Более подробно обо всех командах Skype можно прочитать в официальной документации.
Серия сообщений "Компьютер и всё для него":
Часть 1 - Простой способ переноса закладок из одного браузера в другой
Часть 2 - Вы хотите посмотреть Видео без тормозов?
...
Часть 39 - Бесплатные программы для компьютера
Часть 40 - Самые нужные программы.
Часть 41 - Дистанционное управление Skype
Часть 42 - Полезная программка.
Часть 43 - А Вы знаете, что...