我有一个TSock控件,TSock控件有一个OnRead事件,当Tsock控件打开open的时候,开始侦听来自网络的UDP消息。如果只是一个在窗体上放一个Tsock就好说了,我现在需要动态生成Tsock控件,我该怎么给动态生成的控件赋予OnRead事件?
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Sock;type
  TForm1 = class(TForm)
    Button1: TButton;
    Sock1: TSock;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Sock1Read(Sender: TObject; Count: Integer);
    procedure Button2Click(Sender: TObject);
  private
  public
    function onRead(Asender: Tobject;A:Tsock): TNotifyReadEvent;
  end;var
  Form1: TForm1;implementation{$R *.dfm}{ TForm1 }function TForm1.onRead(Asender: Tobject;A:Tsock): TNotifyReadEvent;
var
  s,Addr: string;
begin
  S:=A.ReceiveDatagram(Addr);
  Showmessage(s);
end;//动态创建的Onread事件,只能侦听一次procedure TForm1.Button1Click(Sender: TObject);
var
 cnt: integer;
 SockA:TSock;
begin
  SockA := TSock.Create(nil);
  SockA.PortName:='514';
  SockA.SocketType:=stDatagram;
  SockA.open;
  SockA.OnRead := Form1.onRead(Sender,SockA);
end;//动态创建控件。procedure TForm1.Sock1Read(Sender: TObject; Count: Integer);
var
  s,Addr: string;
begin
  S:=Sock1.ReceiveDatagram(Addr);
  Showmessage(s);
end;//固定放置在窗体上的控件Onread事件,可以一直处于侦听状态。procedure TForm1.Button2Click(Sender: TObject);
begin
  Sock1.PortName := '514';
  Sock1.Open;
end;//打开固定放置控件。end.我运行,只能向应一次事件,但实际上控件的OnRead一直在自动侦听。每来一个UDP包都会Showmessage().
请大虾帮忙。------------------------------
对象创建了,他的事件都继承了,直接可以写在你的Socket对象OnRead事件中处理
  
 
Top  
 回复人: hyrongg(世道变得太快) ( ) 信誉:91  2006-01-22 11:53:00  得分: 0  
 
 
   to whbo(王红波(年轻人,要有所作为)) 关键是我的窗体上没有放Tsock控件,因为我可能要创建多个,数目不固定,单其实Onread里面的代码都一样,才想到用一个自己创建的事件来附给我创建的对象。
按照你描述的,我的Onread实践里面的代码应该写在哪里呢?to jadeluo(秀峰)cnt其实是一个不重要的变量而已,按照我的代码它能运行一次。第二次有包进来就不行了。关键问题是让她处于一直侦听的状态。如果在窗体上放置一个Tosck控件,双击Onread在里面写Showmessage('test'),他就能自动一直侦听。
  
 
Top  
 回复人: jadeluo(秀峰) ( ) 信誉:100  2006-01-22 12:05:00  得分: 0  
 
 
   一般动态创建的对象的事件处理都是通过设置对象的OnXXXXX属性值,将它们设置为某一个对象处理代码来实现的。为了能在同一个事件处理代码中区分出不同的对象,需要完成以下两个步骤:
1. 设置动态创建的对象的Tag属性,设置为一个唯一的整数值,以便于事件处理代码来区分不同的对象;
2. 事件处理代码的参数中必须有ASender: TObject;  这是用来传入对象实例的。
  
 
Top  
 回复人: zklove(花花公子) ( ) 信誉:99  2006-01-22 13:25:00  得分: 0  
 
 
   SockA := TSock.Create(self);
SockA.OnRead := OnRead;
  
 
Top  
 回复人: hyrongg(世道变得太快) ( ) 信誉:91  2006-01-22 13:28:00  得分: 0  
 
 
   zklove(花花公子)的也不行
  
 
Top  
 回复人: jadeluo(秀峰) ( ) 信誉:100  2006-01-22 15:07:00  得分: 0  
 
 
   保留那个Sock1控件, 然后修改成下面这样:procedure TForm1.Button1Click(Sender: TObject);
var
 cnt: integer;
 SockA:TSock;
begin
  SockA := TSock.Create(nil);
  SockA.PortName:='514';
  SockA.SocketType:=stDatagram;
  SockA.OnRead := Sock1Read;
  SockA.Open;
end;procedure TForm1.Sock1Read(Sender: TObject; Count: Integer);
var
  s, Addr: string;
begin
  S:=TSock(Sender).ReceiveDatagram(Addr);
  Showmessage(s);
end;测试一下此时的动态创建的Sock
  
 
Top  
 回复人: jadeluo(秀峰) ( ) 信誉:100  2006-01-22 15:08:00  得分: 0  
 
 
   问题应该出在你定义的OnRead事件处理代码的参数格式上。
  
 
Top  
 回复人: baiduan(-_-小猩猩 @_@ 大金刚-_-) ( ) 信誉:98  2006-01-22 16:56:00  得分: 0  
 
 
   不很明白,觉得不是onread的事。
那个Tsock有没有属性是设置一直侦听的?
动态创建的时候需要你自己添加默认属性设置的。  
 
Top  
 回复人: hyrongg(世道变得太快) ( ) 信誉:91  2006-01-22 18:46:00  得分: 0  
 
 
   该设的属性我都设了,还是不行
  
Top  

解决方案 »

  1.   

    修改如下:procedure TForm1.Sock1Read(Sender: TObject; Count: Integer);//这句
    var
      s,Addr: string;
    begin
      S:=A.ReceiveDatagram(Addr);
      Showmessage(s);
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
     cnt: integer;
     SockA:TSock;
    begin
      SockA := TSock.Create(nil);
      SockA.PortName:='514';
      SockA.SocketType:=stDatagram;
      SockA.open;
      SockA.OnRead := Form1.onRead;//这句
    end;
      

  2.   

    to:楼主
    动态给一个事件赋值的方法你可以做个简单的程序先试试。to:aiirii大虾
    你帮他改的代码,是编译不过的,你看看他Form1.onRead这个函数是怎么定义的?
      

  3.   

    我感觉你 SockA.OnRead(cnt) := Form1.onRead(cnt);这个语句可能有问题
    第一,自定义事件函数的声明:你在form里放一个你的tsockt控件,然后点击onread事件,delphi会在pas文件中生成这个事件的声明部分和实现部分。你自定义的onRead的声明格式应该和delphi自动生成的声明格式一样。
    第二,自定义事件的赋值:然后,在form上点击右键,选'view as text’在你放的tsocket控件那段里,你会看见tsocket的onread是如何被赋值的。你在代码中照着格式写应该就可以了。