Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

SendMess.pas

01.01.2007
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Author:       Alexander Vaga
EMail:        primary:   icq2000cc@hobi.ru
              secondary: alexander_vaga@hotmail.com
Web:          http://icq2000cc.hobi.ru
Creation:     May, 2002
Legal issues: Copyright (C) 2002 by Alexander Vaga
              Kyiv, Ukraine
 
              This software is provided 'as-is', without any express or
              implied warranty.  In no event will the author be held liable
              for any  damages arising from the use of this software.
 
              Permission is granted to anyone to use this software for any
              purpose, including commercial applications, and to alter it
              and redistribute it freely.
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
 
unit SendMess;
 
interface
 
uses
  Windows, Messages, SysUtils, Classes, Graphics,
  Controls, Forms, Dialogs,  StdCtrls, Animate,
  ExtCtrls, AppEvnts, ComCtrls, Inifiles, ToolWin,
  Types,Packet,Main, RxCombos;
 
const PostSendInterval = 1000; //1 secs
type
  TMessageTo = class(TForm)
    SendMemo: TMemo;
    ApplicationEvents1: TApplicationEvents;
    SendTimer: TTimer;
    Panel2: TPanel;
    Panel1: TPanel;
    SendAnime: TAnimatedImage;
    SendButton: TButton;
    Label3: TLabel;
    Chars: TEdit;
    CancelButton: TButton;
    MesFmtBox: TCheckBox;
    BGCombo: TColorComboBox;
    Label4: TLabel;
    FGCombo: TColorComboBox;
    Label5: TLabel;
    Panel3: TPanel;
    NNEd: TEdit;
    Label1: TLabel;
    ICQEd: TEdit;
    Label2: TLabel;
    ToolBar1: TToolBar;
    UINi: TToolButton;
    procedure CancelButtonClick(Sender: TObject);
    procedure SendButtonClick(Sender: TObject);
    procedure ApplicationEvents1Message(var Msg: tagMSG;
      var Handled: Boolean);
    procedure SendTimerTimer(Sender: TObject);
    procedure SendMemoKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormShow(Sender: TObject);
    procedure FGComboChange(Sender: TObject);
    procedure BGComboChange(Sender: TObject);
    procedure CalcChars;
  private
    { Private declarations }
    SEQ1, SEQ2 : word;
    CharCount : integer;
  public
    { Public declarations }
    User : PListRecord;
    FromWhom : longint;
  end;
 
implementation
{$R *.DFM}
 
const FG=0;BG=1;
function GetColor(Memo:TMemo;Mode:byte):longint;
begin
     Result:=0;
     case Mode of
     FG:Result:=ColorToRGB(Memo.Font.Color);
     BG:Result:=ColorToRGB(Memo.Color);
     end;
     GetColor:=DSWAP(Result);
end;
 
procedure TMessageTo.CancelButtonClick(Sender: TObject);
begin
     Close;
end;
 
procedure TMessageTo.SendButtonClick(Sender: TObject);
var sNN,sMess,sUIN : string;
    tmp : PPack;
    sTmp : string;
    d1,d2 : longint;
    buf : TByteArray;
    ind,indmem : word;
const capab : string{16}= #$09#$46#$13#$49#$4C#$7F#$11#$D1+
                          #$82#$22#$44#$45#$53#$54#$00#$00;
      blok : string{26} = #$1B#$00#$07#$00#$00#$00#$00#$00+
                          #$00#$00#$00#$00#$00#$00#$00#$00+
                          #$00#$00#$00#$00#$00#$00#$03#$00+
                          #$00#$00;
     x:word=0;
begin
     sNN := NNEd.Text;
     sUIN := ICQEd.Text;
     if SendMemo.Lines.Count = 0 then exit;
     sMess := SendMemo.Text;
//     if CharCount > 1024 then exit;
 
     tmp := CreatePacket(2,SEQ);
     SNACAppend(tmp,$4,$6);
     d1:=random($7FFFFFFF);
     d2:=random($7FFFFFFF);
     SEQ1:=dswap(d1);
     SEQ2:=dswap(d2);
     PacketAppend32(tmp,dswap(d1));
     PacketAppend32(tmp,dswap(d2));
 
     case MesFmtBox.Checked of
     true:
      begin // advanced message
        PacketAppend16(tmp,swap($0002));
        PacketAppendB_String(tmp,sUIN);
        ind:=0;fillchar(buf,sizeof(buf),'^');
        PLONG(@(buf[ind]))^:=dswap($0005FFFF);inc(ind,4);// TLV(5)+len
        PWORD(@(buf[ind]))^:=0;inc(ind,2);
        PLONG(@(buf[ind]))^:=dswap(d1);inc(ind,4);
        PLONG(@(buf[ind]))^:=dswap(d2);inc(ind,4);
        MOVE(capab[1],buf[ind],length(capab));inc(ind,length(capab));
        PLONG(@(buf[ind]))^:=dswap($000A0002);inc(ind,4);//TLV(A)=$0001
        PWORD(@(buf[ind]))^:=swap($0001);inc(ind,2);
        PLONG(@(buf[ind]))^:=dswap($000F0000);inc(ind,4);//TLV(F)empty
 
        PLONG(@(buf[ind]))^:=dswap($2711FFFF);inc(ind,4);// TLV(2711)+len
        indmem:=ind-2;
        MOVE(blok[1],buf[ind],length(blok));inc(ind,length(blok));
        PBYTE(@(buf[ind]))^:=0;inc(ind,1);
        PWORD(@(buf[ind]))^:=swap($FFFF);inc(ind,2);
        PWORD(@(buf[ind]))^:=swap($0E00);inc(ind,2);
        PWORD(@(buf[ind]))^:=swap($FFFF);inc(ind,2);
        PLONG(@(buf[ind]))^:=$0;inc(ind,4);
        PLONG(@(buf[ind]))^:=$0;inc(ind,4);
        PLONG(@(buf[ind]))^:=$0;inc(ind,4);//12 bytes=0
        PBYTE(@(buf[ind]))^:=1;inc(ind,1); // msg-type
        PBYTE(@(buf[ind]))^:=0;inc(ind,1); //sub_msg-type
        PWORD(@(buf[ind]))^:=swap($0000);inc(ind,2);
        PWORD(@(buf[ind]))^:=swap($0100);inc(ind,2);
 
        PWORD(@(buf[ind]))^:=length(sMess)+1;inc(ind,2);//LE len sMess+1
        move(sMess[1],buf[ind],length(sMess));inc(ind,length(sMess));
        PBYTE(@(buf[ind]))^:=0;inc(ind,1); //#00
        PLONG(@(buf[ind]))^:=dswap(GetColor(SendMemo,FG));inc(ind,4);//dswap($00FF0000);//FG
        PLONG(@(buf[ind]))^:=dswap(GetColor(SendMemo,BG));inc(ind,4);//dswap($08080800);//BG
 
        PWORD(@(buf[2]))^:=swap(ind-4);//len TLV(5)
        x:=length(blok)+27+length(sMess)+9;
        PWORD(@(buf[indmem]))^:=swap(x);//len TLV(2711)-!!!!!!!!!!!!
        PacketAppend(tmp,@buf,ind);
        // ack request ?
        PacketAppend32(tmp,dswap($00030000));// TLV(3)empry
      end;
     false:
      begin // simple message
        PacketAppend16(tmp,swap($0001));
        PacketAppendB_String(tmp,sUIN);
        PacketAppend16(tmp,swap(2));//tlv(2)
        PacketAppend16(tmp,swap(13+length(sMess)));//len tlv(2)
        PacketAppend32(tmp,dswap($05010001));
        PacketAppend16(tmp,swap($0101));
        PacketAppend8(tmp,$01);//7 bytes
        PacketAppend16(tmp,swap(4+length(sMess)));//lenmsg+4
        PacketAppend32(tmp,dswap($0)); //4 bytes=0
        PacketAppend(tmp,@(sMess[1]),length(sMess));
        PacketAppend16(tmp,swap($0006));//tlv(6)
        PacketAppend16(tmp,0);//len tlv(6)=0
      end;
     end;//case
     Form1.PacketSend(tmp);
     M(SendMemo,'Sending...');
     case MesFmtBox.Checked of
     true:  sTmp := '[A] ';
     false: sTmp := '[S] ';
     end;
     sTmp := '->'+sTmp+DateTimeToStr(Now)+' '+sNN+' ['+sUIN+']  "'+sMess+'"';
     M(Form1.Memo,sTmp);  Form1.LogMessage(sTmp);
 
     if MesFmtBox.Checked then begin
       SendAnime.Active := true;
       SendMemo.Enabled := false;
       SendButton.Enabled := false;
       MesFmtBox.Enabled := false;
     end else Close;
end;
 
procedure TMessageTo.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
     if Msg.message = msg_OnSrv then begin
       if (Msg.wParam = SEQ1)and(Msg.lParam = SEQ2) then begin
         SendAnime.Active := false;
         M(SendMemo,'<Srv`s ACK>');
         Handled := true;
       end;
     end;
     if Msg.message = msg_Sent then begin
       if (Msg.wParam = SEQ1)and(Msg.lParam = SEQ2) then begin
         SendAnime.Active := false;
         SendTimer.Interval := PostSendInterval;
         SendTimer.Enabled := true;
         M(SendMemo,'Message sent... ');
         Handled := true;
       end;
     end;
     if Msg.message = msg_SentErr then begin
       if (Msg.wParam = SEQ1)and(Msg.lParam = SEQ2) then begin
         SendAnime.Active := false;
         M(SendMemo,'Server`s Error... try SIMPLY message-format');
         SendMemo.Enabled := true;
         SendButton.Enabled := true;
         MesFmtBox.Enabled := true;
         Handled := true;
       end;
     end;
end;
 
procedure TMessageTo.SendTimerTimer(Sender: TObject);
begin
     SendTimer.Enabled := false;
     Close;
end;
 
procedure TMessageTo.CalcChars;
begin
     CharCount := length(SendMemo.Text);
     case CharCount of
     0..1023: with Chars do begin Font.Color := clGreen;  Color := clMenu; end;
         else with Chars do begin Font.Color := clYellow; Color := clRed;  end;
     end;
     Chars.Text := inttostr(CharCount);
end;
 
procedure TMessageTo.SendMemoKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
     CalcChars;
end;
 
procedure TMessageTo.FormClose(Sender: TObject; var Action: TCloseAction);
begin
     User^.EXTRA.BG := ColorToString(SendMemo.Color);
     User^.EXTRA.FG := ColorToString(SendMemo.Font.Color);
     Destroy;
end;
 
procedure TMessageTo.FormShow(Sender: TObject);
var sNN : string;
begin
     SendMemo.Color:=StringToColor(User^.EXTRA.BG);
     BGCombo.ColorValue:=SendMemo.Color;
     SendMemo.Font.Color:=StringToColor(User^.EXTRA.FG);
     FGCombo.ColorValue:=SendMemo.Font.Color;
     if User^.EXTRA.ICON_INDEX = simply_icq then
       UINi.ImageIndex := offline else
       UINi.ImageIndex := User^.EXTRA.ICON_INDEX;
     if (ICQStatus = STATE_INVISIBLE)or
        (User^.EXTRA.ICON_INDEX = simply_icq)then begin
        MesFmtBox.Enabled := false;
        MesFmtBox.Checked := false;
     end else begin
        MesFmtBox.Enabled := true;
        MesFmtBox.Checked := true;
     end;
     sNN := NNed.Text;
     CalcChars;
end;
 
procedure TMessageTo.FGComboChange(Sender: TObject);
begin
     SendMemo.Font.Color:=FGCombo.ColorValue;
     SendMemo.SetFocus;
end;
 
procedure TMessageTo.BGComboChange(Sender: TObject);
begin
     SendMemo.Color:=BGCombo.ColorValue;
     SendMemo.SetFocus;
end;
 
end.