procedure ReSetObjEvent(OldEventAddr: pointer;NewEventValue: pointer;ReSetObject: TObject);
begin
  TMethod(OldEventAddr^).Code := NewEventValue;
  TMethod(OldEventAddr^).Data := ReSetObject;
end;
通过上面的一个函数可以给事件绑定相应的处理函数,比如按钮的OnClick事件
procedure MyClick(Sender: TObject);我可以替换成为procedure MyClick(Sender: TObject;s:string);
begin
  showmessage((Sender as Tbutton).Caption+'____'+ s);
end;问题是:我怎么才能把MyClick的s传进去,应该涉及到消息处理什么的。。

解决方案 »

  1.   

    可以用(Sender as Tbutton).Hint来保存信息
    showmessage((Sender as Tbutton).Caption+'____'+ (Sender as Tbutton).Hint);
      

  2.   

    delphi2007测试通过!
    procedure MyClick(Sender: TObject;s:string);
    begin
      showmessage((Sender as Tbutton).Caption+'____'+ s);
    end;procedure MyClickWrapper(O, Sender: TObject);
    begin
      MyClick(Sender, 'abcd');
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      ShowMessage('');
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      asm//将MyClickWrapper赋给Button1.OnClick
        mov edx,[eax+Button1]
        mov [edx+$110], offset MyClickWrapper
        mov [edx+$114], eax
      end;end;
      

  3.   


    首先,那段汇编没有调用MyClickWrapper成功。最重要的是,我的目的是让事件对应的过程多一个参数,跟你的想法完全不一样。
    想达到你这段代码的效果很简单:
    var
      Event: TNotifyEvent;
    begin
      integer(@Event) := integer(@MyClickWrapper);
      btn1.OnClick :=  Event;
    end;
      

  4.   

    不如在TButton的基础上封装个控件!
      

  5.   

    首先,那段汇编在我这边的delphi2007环境下调用MyClickWrapper成功了。
    其次,你的那段模拟的代码是有问题的,不信你可以在MyClickWrapper中调用ShowMessage(O.ClassName)试试!
      

  6.   

    感觉应该从TButton继承一个控件出来
      

  7.   


    很感谢你的回复,汇编没有作用可能是Delphi版本不一样,汇编不怎么懂,也不会改。ShowMessage(O.ClassName)错误的原因大概是没有传递Self,如果用我前面提到的ReSetObjEvent函数就没有问题了。
    参考:http://www.cnpack.org/showdetail.php?id=628&lang=zh-cn看了下底层的Click貌似是私有方法,不能覆盖,所以实现这个貌似很困难~~
      

  8.   

    你只能使用形参与目标函数参数(实际是指向对象方法的指针)一致的方法,不能额外的增加或者减少参数,或者改变参数类型比如Button的onclick事件,它是TNotifyEvent即:
    TNotifyEvent = procedure(Sender: TObject) of object;你不能搞一个参数不同的另类方法赋值给onClick,所以另想它法吧...
      

  9.   

    Controls.pas:
      TControl = class(TComponent)
        ...
      protected
        ...
        procedure Click; dynamic;
      

  10.   

    不知道这样能满足你的需要不unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TMyClick=procedure(sender:TObject;Text:string) of object;
      TButton= class (StdCtrls.TButton)
      private
        FMyClick: TMyClick;
        FOldCilck:TNotifyEvent;
        procedure SetMyClick(const Value: TMyClick);
        procedure OnclickEx(sender:TObject);  published
      public
        procedure DefaultMyclick(sender:TObject;Text:string);
        property OnMyClick: TMyClick read FMyClick write SetMyClick;  end;  TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}{ TButton }procedure TButton.DefaultMyclick(sender: TObject; Text: string);
    begin
        ShowMessage(Text);
    end;procedure TButton.OnclickEx(sender: TObject);
    begin
      if Assigned(FOldCilck) then
       begin
          FOldCilck(sender);   end;
       if Assigned(FMyClick) then
        FMyClick(sender,'fdsfds');
    end;procedure TButton.SetMyClick(const Value: TMyClick);
    begin  FMyClick := Value;
      if Assigned(OnClick) then
      begin
         FOldCilck := OnClick;
         OnClick :=OnclickEx;
      end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
        ShowMessage('old');
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
        Button1.OnMyClick:= Button1.DefaultMyclick;
    end;end.