将普通过程赋值给事件,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;