初步实现:
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中用控件,
但这个属性不知怎么赋值。。
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中用控件,
但这个属性不知怎么赋值。。
procedure TcpServerExecute(AThread: TIdPeerThread);
然后在创建时
MyTcpServer := TIDTCPServer.Create(Application);
MyTcpServer.OnExecute := TcpServerExecute ;
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;