初步实现:
var
  E: TIdServerThreadEvent;
begin
  TMethod(E).Code := @tmpExecute;//替代函数
  TMethod(E).Data := Self;
  IdTCPServer1.OnExecute:=  E;
end;
//-------------------------------------------------------------procedure tmpExecute(AThread: TIdPeerThread);
begin
  ChatUse.ClientStr:= AThread.Connection.ReadLn();
  ChatUse.RecAThread:= AThread;
  AThread.Synchronize(Form1.CreateChatForm);
end;
tmpExecute中的AThread怎么赋值进去?
大家有什么好的方法呢,其它的方式也行。我的目的是动态创建IdTCPServer1,不想在Form中用控件,
但这个属性不知怎么赋值。。

解决方案 »

  1.   

    先定义事件
      procedure TcpServerExecute(AThread: TIdPeerThread);
    然后在创建时   
       MyTcpServer := TIDTCPServer.Create(Application); 
       MyTcpServer.OnExecute := TcpServerExecute ; 
      

  2.   

    注: procedure tmpExecute(AThread: TIdPeerThread);  并不在一个类中。。
      

  3.   

    问题已解决:(From Baidu)var
      E: TIdServerThreadEvent;
    begin
      TMethod(E).Code := @tmpExecute;//替代函数
      TMethod(E).Data := Self;
      IdTCPServer1.OnExecute:=  E;
    end;
    我建议你还是用对象方法去做,你用对象方法转函数的话,比较麻烦.
    普通函数指针pointer 为4个字节,但是对象的方法指针是8个字节,由对象指针和函数指针组合而成.
    TMethod(E).Data := Self;本身因该是OnExecute方法中的AThread参数,所以,执行tmpExecute时,这参数并没有实际意义,在触发IdTCPServer1.OnExecute时,只是触发了tmpExecute中的代码.而参数并没有被正确传递.
    举例
    procedure  Button2Click(Sender: TObject);
    begin
      ShowMessage(TButton(sender).Caption);
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Method: TMethod;
    begin
      Method.Code := @Button2Click;      //函数指针
      Method.Data := button2;         //对象,你可以尝试用 Method.Data :=self,nil,button1,以便了解参数的意思
      Button2.OnClick := TNotifyEvent(Method);end;所以,你这个程序,如果你想传递AThread参数,上面的代码应该是放在定义控件事件代码部分,这样的话,还不如直接用对象方法来做,还省事些.unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, IdBaseComponent, IdComponent, IdTCPServer, StdCtrls;
    type
      //自定义控件
      NewIdTCPServer =class( TIdTCPServer)
      private
        procedure tmpExecute(AThread: TIdPeerThread);
      public
        constructor Create(AOwner: TComponent);reintroduce;
        destructor Destroy(); override;
    end;
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      GvNewIdTCPServer : NewIdTCPServer;
    implementation{$R *.dfm}
    { NewIdTCPServer }procedure NewIdTCPServer.tmpExecute(AThread: TIdPeerThread);
    var
      str : string;
      Len : integer;
    begin
      Len:=AThread.Connection.ReadFromStack();
      if Len >0 then
      begin
        str := AThread.Connection.ReadString(Len);
        showmessage(str);
      end;
    //  ChatUse.ClientStr:= AThread.Connection.ReadLn();
    //  ChatUse.RecAThread:= AThread;
    //  AThread.Synchronize(Form1.CreateChatForm);
    end;constructor NewIdTCPServer.Create(AOwner: TComponent);
    var
      Method: TMethod;
    begin
      inherited Create(AOwner);
      self.OnExecute := tmpExecute;
    end;destructor NewIdTCPServer.Destroy;
    begin  inherited;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      if GvNewIdTCPServer =nil then
        GvNewIdTCPServer := NewIdTCPServer.Create(self);
      GvNewIdTCPServer.Bindings.Clear;
      GvNewIdTCPServer.Bindings.Add;
      GvNewIdTCPServer.Bindings[0].IP := '0.0.0.0';
      GvNewIdTCPServer.Bindings[0].Port:= 5002;
      GvNewIdTCPServer.Active := true;
    end;