将普通过程赋值给事件,TMethod的妙用

来源:互联网 发布:阿里云的域名还要备案? 编辑:程序博客网 时间:2024/05/20 23:56

OnClick是TNotifyEvent类型;  type   TNotifyEvent   =   procedure(Sender:   TObject)   of   object;  就是说他是一个过程,而且是有一个TObject的参数,并且包含在一个对象里~~  关于类的方法:   (不是类方法,这里指object   pascal中的静态方法,相当于C++的成员函数)        1:   带有隐含参数   self        2:   方法是方法,数据是数据。        3:Delphi的方法是一个结构              type                  TMethod   =   record                      Code:   Pointer;     //方法的入口地址                      Data:   Pointer;     //类实例指针(Self参数)                  end;       我们调用类的方法,其实分为2个部分,        1:调用方法的代码,通过类来获得方法入口地址。        2:访问对象的数据(也可能不访问),通过类的方法的那个隐含参数Self来访问。 我做了一个测试:        TMyObject   =   class        private            FName:   string;        public            procedure   ChangeName(AName:   string);            procedure   ShowPrivate;        end;       procedure   TMyObject.ChangeName(AName:   string);    begin        FName   :=   AName;   //修改私有变量        ShowMessage('My   name   is   to   be   changed   to   '   +   AName);    end;       procedure   TMyObject.ShowPrivate;    begin        ShowMessage('My   name   is   '   +   FName);    end;       procedure   TForm1.Button1Click(Sender:   TObject);    type        TCallFun   =   procedure(AName:   string)   of   object;    var        E:   TMyObject;        M:   TMethod;    begin        E   :=   TMyObject.Create;        M.Code   :=   @TMyObject.ChangeName;   //这里设置要访问的方法的入口地址        M.Data   :=   @Pointer(E)^;       //设置Self参数,即类实例指针 @Pointer(E)^与Pointer(E)一样的       TCallFun(M)('Xbl');        E.ShowPrivate;     //My   name   is   Xbl        E.Free;    end;    来个简单点的,以前记录。 procedure   Form1_FormDblClick(aSelf:   TForm1;   aSender:   TObject);begin    aSelf.Caption   :=   'Double   click   me!!!';    aSelf.OnDblClick   :=   aSelf.FormDblClick;end;procedure   TForm1.FormCreate(Sender:   TObject);var    M:   TMethod;    P:   Pointer;begin    M.Code   :=   @Form1_FormDblClick;    M.Data   :=   Self;    OnDblClick   :=   TNotifyEvent(M);end;procedure   TForm1.FormDblClick(Sender:   TObject);begin    Caption   :=   'The   original   event   is   restored.';end; //他祖先的procedurevar M:TMethod;P:Pointer;begin  p:=self.ClassParent.ClassParent.MethodAddress('actNewExecute');  M.Code:=p;// 或者直接用 @TfrmBaseMD.actNewExecute;  M.Data:=self;  TNotifyEvent(M)(Sender);end;


原创粉丝点击