想给一个动态创建的控件赋一个双击事件,因为还要传递一个参数进去,结果这样做却不行,望高手指点,怎么让我的代码通过.
代码如下:
procedure TForm1.View(var i:integer);
begin
  showmessage('hi');
end;procedure TForm1.FormCreate(Sender: TObject);
var
  PL:TPanel;
begin
  PL:=TPanel.Create(Self);
  PL.Parent:=Form1;
  PL.OnDblClick:=View(1);
end;

解决方案 »

  1.   

    例如
    procedure TForm1.view1(Sender: TObject);
    begin
      ShowMessage('1');
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      Panel1.OnDblClick := view1;
    end;如果真的要处理参数,可以将参数改成窗体的私有变量(在private下声明)
      

  2.   

    一起研究一下吧,这个问题挺有意思的。我下面这些代码还有错误,大家一起改正吧:
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        procedure MyView(var i:integer);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.MyView(var i:integer);
    begin
      showmessage(intToStr(I));
    end;var
          I : integer;procedure TForm1.FormCreate(Sender: TObject);
    var
      PL:TPanel;
      M : TMethod;
    begin
      PL:=TPanel.Create(Self);
      PL.Parent:=self;
      M.Code := TForm1.MethodAddress('MyView');
      M.Data := @I;
      PL.OnDblClick := TNotifyEvent(M);
    end;
      

  3.   

    procedure MyEven(Sender:TObject);
    procedure MyPro2(Sender:TObject; i:integer);procedure TDlg_CosPowerRptA.MyEven(Sender: TObject);
    begin //自定义事件
      MyPro2(view1, i);
    end;procedure TDlg_CosPowerRptA.MyPro2(Sender: TObject; i: integer);
    begin //自定义过程
      TView(sender).................
    end;之后
    PL.OnDblClick:=MyEven;另外,如果你指想传一个整数,可以把整数赋值给sender.tag.
      

  4.   

    前面我写的代码里,如果有人试验了,会发现,ShowMessage(IntToStr(I))显示的并不是预期的I值。那是因为类方法默认传递一个Sender参数,在这程序里,就是PL这个Panel的指针值。即使没有显式地声明这个参数。(ShowMessage的就是这个指针值)我现在要去接孩子了,大家继续。
      

  5.   

    procedure View(sender:TObject);
    procedure TForm1.Button1Click(Sender: TObject);
    var
    PL:TPanel;
    begin
    PL:=TPanel.Create(Self);
    PL.Parent:=Form1;
    PL.Caption:='A';
    PL.Tag:=1;
    PL.OnDblClick:=View;
    end;procedure TForm1.View(sender: TObject);
    begin
      showmessage( TPanel(sender).Caption );
      showmessage( IntToStr( TPanel(sender).Tag ) );
    end;
      

  6.   

    To hongqi162(失踪的月亮)
    还是你高,问题已解决
      

  7.   

    也可以继承TPanel控件再写一个组件,添加一个保存指针的属性,这样想要什么都有了
      

  8.   

    MyPro2(view1, i);////楼主怎么对这个i赋值?怎么区分不同的TPanel?所以信息还是要保存在sender内.
      

  9.   

    唉!~~~~  前面犯晕了....  TMethod.Data 是传的一个地址,而我却一心一意地要按整型去取出来.... 下面这样就可以传参了:
    var
      F : integer = 6688; //用一个变量试验procedure Proc( I : Integer);//别看是传Integer,实际上是传递变量的地址
    begin
      ShowMessage(IntToStr(PInteger(I)^));//所以要转换为地址把变量找出来
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      PL : TPanel;
      M : TMethod;
    begin
      PL := TPanel.Create(self);
      PL.Parent := self;
      PL.Caption := 'Panel''s Addr = ' + IntToStr(Integer(PL));
      M.Code := @Proc;
      M.Data := @F; //  !! 传参就是用这个 Method.Data
      PL.OnDblClick := TNotifyEvent(M);
    end;
      

  10.   

    承上:简化一下procedure Proc :procedure Proc( I : PInteger);
    begin
      ShowMessage(IntToStr(I^));
    end;刚开始时的试验,还有一个导致不成功的很重要的原因,是用了类方法。
      

  11.   

    procedure (Self: TObject; Sender: TObject);
      

  12.   

    问:1975
    为什么procedure Proc( I : Integer);接收的参数是F:Integer的指针呢?
    就因为Tmethod的Data指定了@F?
    如果我传两个参数一个string ,一个integer
    那么Proc( I :integer)接受的值也什么呢?
      

  13.   

    呵呵,照着写了一个,不知道这样实现有啥用啊?实际意义在哪?
    type
      PMyInfo=^TInfo;
      TInfo=packed record
        i:integer;
        s:string;
      end;
    procedure proc(i:Integer);
    var p3:PMyInfo;
    begin
      p3:=PMyInfo(i);
      showmessage('i:'+Inttostr(p3^.i)+'s:'+p3^.s);
    end;procedure TForm1.Button1Click(Sender: TObject);
    var panel:TPanel;
        m:TMethod;
    begin
      panel:=TPanel.Create(Self);
      panel.Parent:=self;
      panel.Caption:='a';
      m.Code:=@proc;
      new(pp);
      pp^.i:=1234;
      pp^.s:='abcd';
      m.Data:=pp;
      panel.OnClick:=TNotifyEvent(M);
      panel.Show;
    end;
      

  14.   

    TO : 楼上:下面是传三个参数:type
      VV = record
       I1,I2,I3 : integer;
       end;var
      F : VV; procedure Proc( I : PInteger);
    begin
      ShowMessage(IntToStr(I^));
      ShowMessage(IntToStr(Pinteger(integer(I)+4)^));
      ShowMessage(IntToStr(Pinteger(integer(I)+8)^));
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      PL : TPanel;
      M : TMethod;
    begin
      PL := TPanel.Create(self);
      PL.Parent := self;
      PL.Caption := 'Panel''s Addr = ' + IntToStr(Integer(PL));
      M.Code := @Proc;
      M.Data := @F; 
      PL.OnDblClick := TNotifyEvent(M);
    end;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      F.I1 := 8888;
      F.I2 := 6666;
      F.I3 := 9999;
    end;指针偏移量,要看类型的长度了。关于“有什么意义”?我也不知道。
      

  15.   

    重新给楼上出现的dd_zhouqian先生改写了一下代码:(也许,对我来说,这就是“实际意义”吧:每天吃粮食,每天有点小小进步,不致于自愧)type
      TStr = string[10];
      VV = record
       iField : integer;
       sField : TStr;
       dField : double;
       end;
      PStr = ^TStr;
    var
      F : VV;procedure Proc( I : Integer);
    var P1 : PStr;
    begin
      ShowMessage(IntToStr(PInteger(I)^));
      ShowMessage(PStr(integer(I)+4)^); //注意,记录的成员是顺序存放的,注意偏移量
      ShowMessage(FloatToStr(PDouble(integer(I)+16)^));
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      PL : TPanel;
      M : TMethod;
    begin
      PL := TPanel.Create(self);
      PL.Parent := self;
      PL.Caption := 'Panel''s Addr = ' + IntToStr(Integer(PL));
      M.Code := @Proc;
      M.Data := @F;
      PL.OnDblClick := TNotifyEvent(M);
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      F.iField := 8888;
      F.sField := 'abcdefghij';
      F.dField := 12345.0876;
    end;这个代码的意义还在于让我们深入理解OO。因为这个课题(TMethod)还可以深究下去的。
      

  16.   

    Have a long distance, study~~~~~~~
      

  17.   

    procedure TForm1.view1(Sender: TObject);
    begin
    ShowMessage(IntToStr((Sender as TControl).Tag));
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
    Panel1.Tag := 1;
    Panel1.OnDblClick := @view1;
    end;
      

  18.   

    要传更多参数,就用结构。
    Tag放结构地址。type
    TDATAREC = record
    d1: integer;
    d2: integer;
    end;
    PDATAREC = ^TDATAREC;
    procedure TForm1.view1(Sender: TObject);
    begin
    with Sender as TControl do
    begin
    ShowMessage(IntToStr(d1));
    ShowMessage(IntToStr(d2));
    end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
    prec:PDATAREC;
    begin
    New(prec);
    prec.d1 := 10;
    prec.d2 := 11;
    Panel1.Tag := integer(prec);
    Panel1.OnDblClick := @view1;
    end;
      

  19.   

    楼上打错了type
    TDATAREC = record
    d1: integer;
    d2: integer;
    end;
    PDATAREC = ^TDATAREC;
    procedure TForm1.view1(Sender: TObject);
    begin
    with PDATAREC((Sender as TControl).Tag) do
    begin
    ShowMessage(IntToStr(d1));
    ShowMessage(IntToStr(d2));
    end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
    prec:PDATAREC;
    begin
    New(prec);
    prec.d1 := 10;
    prec.d2 := 11;
    Panel1.Tag := integer(prec);
    Panel1.OnDblClick := @view1;
    end;
      

  20.   

    @view1
    开头的 @还要去掉
      

  21.   

    with PDATAREC((Sender as TControl).Tag) do
    改成
    with PDATAREC((Sender as TControl).Tag)^ do
      

  22.   

    to lihuasoft:  跑题了,既然F : VV;已经定义成了全局变量,双击事件直接取不就ok了,事件是不能保存值的.
      

  23.   

    晕晕的,顺便BS楼上的,所到之处,必UP
      

  24.   

    procedure TForm1.View(var i:integer);
    var
     Panel : TPanel;
    begin
     Panel := TPanel.Create(Self);
     Panel.Parent := Self;
     Panel.Tag := i;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
    View(1);
    end;
      

  25.   

    procedure TForm1.View(var i:integer);
    begin
      showmessage(InToStr(i));
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
      PL:TPanel;
    begin
      PL:=TPanel.Create(Self);
      PL.Parent:=Form1;
      PL.OnDblClick:=View(1);
    end;
    ------------------------------------------
      以上问题如果用Delphi2009的匿名方法就容易解决了:procedure TForm1.FormCreate(Sender: TObject);
    var
      PL:TPanel;
      i: Integer;
    begin
      PL:=TPanel.Create(Self);
      PL.Parent:=Form1;
      i := 2;
      PL.OnDblClick:=new NotifyEvent(sender: TObject)
      begin
        showmessage(IntToStr(i));
      end;
    end;强烈期待Delphi新功能。
      

  26.   

    to asj(破喉咙):1、“让我们深入理解OO。”,这句话,本来是要表达我对TMethod类的一个看法,即:TMethod类很好地体现了面向对象的实现机制:Code和Data分离。因为问题已远离楼主的题目,所以没有继续说。但我始终认为,对TMethod类的研究绝对可以“让我们深入理解OO。”。而您说的“顶多是深入了解了Delphi实现的具体细节”,我想,这句话所用的汉字尽管与我的话不同,但实质上并没有很大出入。2、“看到过你的一些回复,可以看出来你是个十分热心而且很用心的人。给出的答复一般也是有用的。但是恕我直言,有些基础的概念并没有理的很清楚。”----谢谢。我没有什么基础,一直是业余自学编程,看过的书都寥寥无几,深知自己水平低下。但是,尽管水平低,在CSDN注册会员6个月以来,回过的所有技术贴,我都是先动手试验成功了才给出代码,一旦发现自己代码的错误,我都要紧接声明,以免误导了提问者。
        同时要请您明确指出:我的哪些贴子的哪些回复中有问题,以致于您说“有些基础的概念并没有理的很清楚”,您指出了,可以便于我进一步提高。提前谢谢您了。3、您所说的“回到lz的问题上,其实还是第二种办法最适合”,在前面“失踪的月亮”和“强哥”各位已经说过了,并且我也已在向前几楼承认这是最合适的办法(我是这样回复月亮的:“是哈... 惭愧,撤!”),我觉得没有必要重复接受每一个人的声讨,向每一个人承认“错误”。4、对于您的代码,我不发表评论。
      

  27.   

    呵呵,看来我还是表达的不够清楚,要是有什么冒犯,还请lihuasoft兄千万不要在意,影响了心情就不好了。我在这里先陪罪了,绝对不是故作姿态。其实前面多嘴几句也是因为首先注意到您的认真和热情,不免有希望通过探讨大家共同提高的想法。如果是因为我自己的表达问题显得有指手画脚的样子,都是我的问题,再次道歉了。回到基础概念问题。并不是说答案不对,而是有些问题并不是因为问题本身。就比如访问私有域这样的问题,我感觉解释这不应该是一个问题,给他另一个思路要胜过直接给个很生僻的方法要好。打个比方,如果有个小孩拿着漏勺喝汤,问我为什么喝不到,虽然我知道如果动作够快是可以达到目的的,但他要是仅仅是不知道工具的话,还是给他个调羹比较好。
    其实前面对lihuasoft兄有印象是在一个人问动态创建窗口释放出错的问题,看到这样一个问题您前前后后回了好几贴,使我都感到很感动,希望能帮忙说清楚问题。不要让兄台的好心浪费掉。但是感觉这种问题如果能比较系统的说明内存管理的方法,以及VCL结构中的特殊机制,让他避免以后出现这样的问题。比起解决当前的一个问题更好一点。特别是问问题的人处在轮着拿Application和Self做构造参数的“基于偶然编程”的状态。
    刚刚专门回顾了一下这个帖子,发现其实lihuasoft兄并非没有提到基础概念,只是我当时只是大略看到几段代码轻忽过去了。所以应该说我前面说的有些基础概念没有理得很清楚的说法是不准确的,准确的说是我觉得lihuasoft兄要是更多强调基础概念会比直接写出代码会更有效一些,所以多嘴提出来希望这样能让您的热心更好的帮助到提问者。至于这个问题,我觉得lz不理解为什么自己的代码不能通过编译,问题是在于没有很好的掌握事件的概念。而不会是因为没有掌握TMethod。所以就算用TMethod的代码是完全正确的,个人认为对他也还是误导。后面列出个人的4个方法,并说第二种最适合,其实是想表示综合各种方案,解决这个问题还是这种很不完美的方式最现实,实在是Delphi的一个遗憾。并没有声讨您的方法不对,只有我说的对的意思。呵呵,对我的代码不发表评论。大概是里面有不严谨的地方吧。我先承认了,对比lihuasoft兄的认真,实在惭愧。因为手头没有Delphi,对于真正细节的问题真的是不敢参与,也就到这样的概念问题帖里掺和掺和了。如果有什么地方错的会造成误解的,还望指出,免得贻笑大方啊。最后还有个尾巴问题,TMethod结构确实仅仅是个Delphi实现细节,而且是不面向对象的。因为以当时的object pascal语言的特性如果完全面向对象方式来设计会相当的繁琐。所以采用了这个巧妙的折衷设计。这个问题我们可以继续讨论,不过觉得另开贴或者私下进行会更好一些。
      

  28.   

    to asj(破喉咙):你是在说这一贴吧:http://community.csdn.net/Expert/topic/5444/5444419.xml?temp=.8697016这贴的提问者,最初并没有明确表述问题,所以绕了几个弯才弄明白他的代码什么样子,最终给他解决办法。的确,给提问者讲原理,比直接给他代码会更让他受益。但往往事与愿违:在提问者对问题表述不清时,不可能从hello world开始讲起。总是要几个回合之后,才能明白他的处境,然后才能说到点子上。况且,大篇幅地打字,讲述课本上已经写得明明白白的基础理论,实在令人痛苦。这对于抢分和快餐式的解决问题无益。呵~~ 早就想从这贴撤了,这又接二连三地回了几条...谢谢你。我接受你的建议。我撤了。
      

  29.   

    to asj(破喉咙):看来你真的是----破喉咙编程这玩意儿,对于初学者来说是不可能讲太多的道理的,当你会用了,然后才可以深入!
    就如你学习汽车驾驶,不可能一开始就讲汽车维修吧?会开就行,慢慢的你才能去修。
      

  30.   

    这个的问题,看看VCL 源码就知道!