Введение

LostMessages (далее LM) – разработка с открытым кодом, представляющая собой программу для обмена сообщениями по протоколу ICQ на основе компонента TICQClient. LM включает в себя простейший код, самый необходимый для функционирования и построения более сложных клиентов на его основе.

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

Описание

Основная идея LM в реализации в программе лога и командной строки, а также единого окна приема/отправки сообщений.

Лог LM

Рис. 1 – Лог LM

В логе прописывается каждое событие, происходящее в программе: процесс подключения, отчет об ошибках, различные оповещения. Также через лог производится настройка подключения.

Настройка, подключение, отключение и другие манипуляции (кроме отправки сообщений) в программе ведутся через командную строку (нижняя часть лога на рис. 1). Список команд и их описание можно получить, введя “man” в командной строке и нажав “Enter”. Выход из него – клавиша “ESC”.

Рис. 2 – Справка по командам LM

Для ускоренного ввода команд имеется их постоянный список, который вызывается нажатием Ctrl+X:

Рис. 3 – список команд

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

Рис. 4 – Окно полученных/отправленных сообщений

Отправка сообщения осуществляется нажатием комбинации Alt+S.
Сообщение отсылается тому, кто в текущий момент выбран в списке (см. рис.4).

Также выбор собеседника можно производить мышкой в окне лога:

Рис. 5 – Окно лога со списком контактов

LM постоянно находится в трее. При получении сообщения его иконка меняет цвет на желтый, при отсутствии сети иконка становится синей.

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

Имеется поддержка подключения через прокси, сохранение лога и сообщений. В LM нет звуков и лишней анимации. Все сделано предельно эргономично и просто.

Теперь непосредственно об исходном коде.

LM написан на Delphi7 и в своем составе имеет 8 юнитов не считая файлов компонентов.
Рассмотрим процесс подключения и получения списка контактов.

В Unit1 прописаны процедуры подключения, отсылки сообщений, считывания настроек. После введения uin и пароля (процедура TForm1.Edit2KeyDown) и проверки их корректности считываются настройки прокси, если прокси включен, затем вызывается процедура ICQClient1.Login.

procedure TForm1.ICQClient1Login(Sender: TObject);
begin
   if ICQClient1.LoggedIn then begin
   //если соединение установлено
     ICQClient1.Status:=$00000000+ $10000000;
     //статус онлайн с скрытием IP
     form3.Timer1.Enabled:=true;
     icqclient1.Password:='';
     //вход уже произошел, поэтому пароль стирается из памяти
       form3.memo1.Lines.Add('-->>  Удалось подключение под номером '+ inttostr(form1.ICQClient1.UIN));
      form3.memo1.Lines.Add('Получение списка...');
        FullReloadContactList := True;
      form3.Caption:='LM_LOG: '+inttostr(form1.ICQClient1.UIN);  //установка заголовков
      form4.Caption:='LM_Mess: '+inttostr(form1.ICQClient1.UIN);  //в принципе, не нужно
      form3.CoolTrayIcon1.Hint:='LM: '+inttostr(form1.ICQClient1.UIN); //т.к. их нет
       form3.Edit1.SetFocus;
       form3.Timer2.Enabled:=true;
       //включается таймер, по которому начинается
       //получение списка контактов и статусов (процедура TForm1.ICQClient1ServerListRecv)
       form3.memo1.Lines.Add('-->> Получение статусов...');
        form3.CoolTrayIcon1.IconIndex:=0;  //меняется иконка
          eco:=-1;
        end;
end;

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

Процедура получения списка:

procedure TForm1.ICQClient1ServerListRecv(Sender: TObject;
  SrvContactList: TList);
var
  i : LongInt;
  UserInfo: TUINEntry;  //включает в себя uin и nick
    UINNickItem : PUINNickItem;
begin

if FullReloadContactList then
    begin
      FullReloadContactList := False;
      form3.ListBox1.Clear;
      //списки, в которых содержатся uin (этот список невидимый)
      form3.ListBox2.Clear;
      //nick и основные статусы
      form3.ListBox4.Clear;
       form4.combobox2.Clear;
             UINNickList.Clear;
      end;
   if SrvContactList.Count > 0 then
   //так как список может придти с сервера по
   //частям, листы очищаются каждый раз при получении нового списка
    for i := 0 to SrvContactList.Count - 1 do
      begin
        UserInfo := PUINEntry(SrvContactList.Items[ i ])^;
        if UserInfo.CType = 0 then
          //если это пользователь (CType = 0), то добавляем в список
          begin
          form3.ListBox4.AddItem(GetStatusFor(UserInfo.UIN), self);
          GetMem(UINNickItem, SizeOf(UINNickItem^));
            UINNickItem^.UIN := UserInfo.UIN;
            if UserInfo.Nick<>'' then
            UINNickItem^.Nick := UserInfo.Nick
             else UINNickItem^.UIN:=(userinfo.UIN);
            UINNickList.Add(UINNickItem);
                form3.ListBox1.AddItem(UINNickItem^.Nick, self);
                   form4.combobox2.AddItem(UINNickItem^.Nick, self);
                   //также nick добавляется в список combobox,
                   //который находится в окне сообщений
                      form3.ListBox2.AddItem(inttostr(UINNickItem^.UIN ), self);
                        form3.memo1.Lines.Add('LOAD: '+UINNickItem^.Nick);
         end;
         end;
  ICQClient1.DestroyUINList(SrvContactList);
   form3.memo1.Lines.Add('-->> Список получен');
   form3.memo1.Lines.Add('->> Готов');
…
end;

Вот, в принципе и все. После подключения включается таймер, отсылающий KeepAlive на сервер для информирования о том, что мы находимся в сети. Иначе через некоторое время произойдет отключение.

Вот пример процедуры, оповещающей, что собеседник сменил статус:

procedure TForm1.ICQClient1StatusChange(Sender: TObject; UIN: String;
  Status: Cardinal);
var
  n: integer;f: string[60];
  begin
      SetStatusToStatusList(UIN, Status);
  n:=form3.ListBox2.Items.IndexOf(UIN);
f:=form3.ListBox1.Items.Strings[n];
       form3.Memo1.Lines.Add('>> Контакт '+f+' сменил статус на '+StatusToStr_rus(Status));
  //Теперь меняем статус в списке контактов
 form3.ListBox4.Items.Strings[n]:=StatusToStr_rus(Status);
form3.refresh;
  end;

Работа LM зависит от компонента TICQClient, поэтому при смене протокола, если такое случится, нужно будет заменить компонент.

Заключение

Рассмотрены основные особенности клиента, его интерфейс, базовые функции. Что делать с ним дальше – решать вам. Можете взять его за основу при написании бота, либо для создания еще одного ICQ-клиента. Можно далее упрощать код, или, наоборот, добавить новые функции.

Тема на форуме . Скачать с сайта автора программу и скачать исходники. Справка на сайте автора

Сайт автора: LOSTeam (Malyshev Maxim)

Извините, комментарии отсутствуют.

Вы должны войти для того, чтобы оставить комментарий.