Delphi 7:处理控制台应用程序中的事件(TidIRC)

时间:2012-07-06 14:43:56

标签: delphi events delphi-7 console-application indy

我正在尝试使用Indy的IRC组件(TIdIRC)创建一个控制台应用程序,但我遇到了事件的问题。这是我的代码:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Classes,
  Math,
  IdBaseComponent,
  IdComponent,
  IdTCPConnection,
  IdTCPClient,
  IdIRC;

type
  TEvents = class
  public
    procedure Raw(Sender: TObject; AUser: TIdIRCUser; ACommand, AContent: String; var Suppress: Boolean);
  end;

const
  IrcServ = 'gr.irc.gr';
  IrcPort = 6667;
  IrcChan = '#lalala';

var
  Irc: TidIRC;
  Event: TEvents;
  uName, rName: string;

function Log(s: string): string;
var now: TDateTime;
begin
  now := Time;
  result := FormatDateTime('[hh:nn:ss] ', now) + s;
end;

procedure TEvents.Raw(Sender: TObject; AUser: TIdIRCUser; ACommand, AContent: String; var Suppress: Boolean);
begin
  Log(AUser.Nick+' '+ACommand+' '+AContent);
end;

begin
  Event := TEvents.Create;
  Irc := TidIRC.Create(nil);
  Irc.OnRaw := Event.Raw;
  Randomize;
  Write('Nickname: ');
  ReadLn(uName);
  rName := 'IDM' + IntToStr(RandomRange(1000, 9999)) + uName;
  with Irc do begin
    AltNick := 'IDM' + IntToStr(RandomRange(1000, 9999)) + uName;
    Nick := rName;
    Username := rName;
    RealName := 'I.D.M.';
    Host := IrcHost;
    Port := IrcPort;
    //MaxLineAction := maException;  <-- [ERROR] Undeclared identifier: 'maException'
    ReadTimeout := 0;
    UserMode := [];
    Connect();
    Join(IrcChan);
  end;
  ReadLn;

end.

到目前为止,我已经尝试了所有我能想到的,但是,虽然应用程序已成功连接,但它不会返回任何原始消息...我缺少什么?

1 个答案:

答案 0 :(得分:4)

TdIRC使用内部工作线程来接收数据。当该线程正在解析数据时,将触发OnRaw事件。该线程使用TThread.Synchronize()进行解析。由于您的主线程没有活动的VCL消息循环,您可以手动抽取Synchronize()队列。连接后,在连接到IRC时,在循环中从CheckSynchronize()单元调用Classes函数,例如:

begin 
  ...
  Connect; 
  try
    Join(IrcChan); 
    do
      CheckSynchronize;
      Sleep(10);
    until SomeCondition;
  finally
    Disconnect;
  end;
  ...  
end. 

为了更好地衡量,您可以为WakeMainThread单元中的Classes事件分配处理程序,以帮助控制何时应调用CheckSynchronize(),以便主线程可以进入休眠状态IRC连接空闲,例如:

program Project1;     

{$APPTYPE CONSOLE}     

uses     
  SysUtils,     
  Classes,     
  Math,     
  IdBaseComponent,     
  IdComponent,     
  IdTCPConnection,     
  IdTCPClient,     
  IdIRC;     

type     
  TEvents = class     
  private
    FSyncEvent: TEvent;
  public     
    constructor Create;
    destructor Destroy; override;
    procedure Raw(Sender: TObject; AUser: TIdIRCUser; ACommand, AContent: String; var Suppress: Boolean);     
    procedure Wake(Sender: TObject);
    procedure CheckSync;
  end;     

function Log(s: string): string;      
begin      
  result := FormatDateTime('[hh:nn:ss] ', Time) + s;      
end;      

constructor TEvents.Create;
begin
  inherited;
  FSyncEvent := TEvent.Create(nil, False, False, '');
end;

destructor TEvents.Destroy;
begin
  FSyncEvent.Free;
  inherited;
end;

procedure TEvents.Raw(Sender: TObject; AUser: TIdIRCUser; ACommand, AContent: String; var Suppress: Boolean);      
begin      
  Log(AUser.Nick+' '+ACommand+' '+AContent);      
end;      

procedure TEvents.Wake(Sender: TObject);
begin
  FSyncEvent.SetEvent;
end;

procedure TEvents.CheckSync;
begin
  FSyncEvent.WaitFor(Infinite);
  CheckSynchronize;
end;

const     
  IrcServ = 'gr.irc.gr';     
  IrcPort = 6667;     
  IrcChan = '#lalala';     

var      
  Irc: TidIRC;      
  Event: TEvents;      
  uName, rName: string;      

begin
  Event := TEvents.Create;       
  try
    WakeMainThread := Event.Wake;
    Irc := TIdIRC.Create(nil);       
    try
      Irc.OnRaw := Event.Raw;       
      Randomize;       
      Write('Nickname: ');       
      ReadLn(uName);       
      rName := 'IDM' + IntToStr(RandomRange(1000, 9999)) + uName;       
      with Irc do begin       
        AltNick := 'IDM' + IntToStr(RandomRange(1000, 9999)) + uName;
        Nick := rName;       
        Username := rName;       
        RealName := 'I.D.M.';       
        Host := IrcHost;       
        Port := IrcPort;       
        //MaxLineAction := maException;  <-- [ERROR] Undeclared identifier: 'maException'       
        ReadTimeout := 0;       
        UserMode := [];       
        Connect;       
        try
          Join(IrcChan);       
          do
            Event.CheckSync;
          until SomeCondition;
        finally
          Disconnect;
        end;
      end;       
    finally
      Irc.Free;
    end;
  finally
    Event.Free;
  end;
end.