窗体上一个按钮,在onclick事件里面写了代码,
然后我用GetMethodProp把onclick事件的方法地址保存起来,再用SetMethodProp将按钮的事件替换成我的方法 NewClick,然后我再NewClick内部调用我原先保存的原来的OnClick,但是在执行原来的OnClick的时候,发生了内存错误,似乎是本应有的一个self值变成了nil,有没有办法通过汇编,在调用原来的onclck之前将self值设置好不知道有谁处理过类似问题,指点一下?

解决方案 »

  1.   

    撸过围观“然后我再NewClick内部调用我原先保存的原来的OnClick,但是在执行原来的OnClick的时候”
    没太看懂
      

  2.   

    你似乎是这个意思?unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, TypInfo;type
      TForm1 = class(TForm)
        btn1: TButton;
        btn2: TButton;
        procedure btn1Click(Sender: TObject);
        procedure btn2Click(Sender: TObject);
      private  public  end;var
      Form1: TForm1;
      oldMethod: TMethod;implementation{$R *.dfm}procedure NewClick;
    begin
      ShowMessage('NewClick()');
      asm
        pushad
        mov edx, oldMethod.Data
        call oldMethod.Code
        popad
      end;
    end;procedure TForm1.btn1Click(Sender: TObject);
    begin
      ShowMessage('btn1Click()');
      ShowMessage(Sender.ClassName);
    end;procedure TForm1.btn2Click(Sender: TObject);
    var
      newMethod: TMethod;
    begin
      oldMethod := GetMethodProp(Btn1, 'OnClick');
      oldMethod.Data := btn1;  // Sender
      newMethod.Code := @NewClick;
      SetMethodProp(btn1, 'OnClick', newMethod);
    end;end.
      

  3.   

    请教LS,一直不懂TMethod.Data 这个指针保存的是什么?
      

  4.   

    51行注释了,是保存的Sender。指向调用者对象,我猜楼主的问题也是这里了
      

  5.   

    我的意思是,你不主动给它 TMethod.Data := XXX 赋值,
    GetMethodProp 之后,TMethod.Data 和 TMethod.Code 都被传入一个相同的值,是什么?
      

  6.   


    当前对象的实例
    procedure TForm1.btn2Click(Sender: TObject);
    var
      newMethod: TMethod;
    begin
      oldMethod := GetMethodProp(Btn1, 'OnClick');
      ShowMessage(TObject(oldMethod.Data).ClassName);  // TForm1
      //oldMethod.Data := btn1;  // Sender
      newMethod.Code := @NewClick;
      SetMethodProp(btn1, 'OnClick', newMethod);
    end;
      

  7.   


    也就是Selfprocedure TForm1.btn2Click(Sender: TObject);
    var
      newMethod: TMethod;
    begin
      oldMethod := GetMethodProp(Btn1, 'OnClick');
      if oldMethod.Data = Self then
        ShowMessage('额,原来是窗体本身');
      //oldMethod.Data := btn1;  // Sender
      newMethod.Code := @NewClick;
      SetMethodProp(btn1, 'OnClick', newMethod);
    end;
      

  8.   

    to aqtata:
    那几行汇编编译不过去:
    call FOldMthod.Code
    [dcc32 Error] Unit1.pas(51): E2116 Invalid combination of opcode and operands
      

  9.   

    你delphi什么版本?改成试试
      asm
        pushad
        mov edx, oldMethod.Data
        mov ebx, oldMethod.Code
        call ebx
        popad
      end;