Delphi 使用 RTTI 动态通过名称调用函数和设置控件属性值
// 设置控件的属性名
uses TypInfo, JclAnsiStrings;
function GetObject(obj:TObject; path:String): TObject; var objName:String; begin Result := obj;
while System.Length(path) > 0 do begin objName := JclAnsiStrings.StrToken(path, '.'); if obj is TComponent then begin Result := TComponent(Result).FindComponent(objName); end else begin Result := TypInfo.GetObjectProp(Result, objName); end; end; end;
procedure SetPropValue(obj:TObject; path:String; value:Variant); var tk:TTypeKind; i:Integer; propName:String; begin i := JclAnsiStrings.StrLastPos('.', path); if i > 0 then begin obj:= GetObject(obj, JclAnsiStrings.StrLeft(path, i-1)); propName:= JclAnsiStrings.StrRestOf(path, i+1); end else begin propName := path; end; TypInfo.SetPropValue(obj, propName, value); end;
procedure TForm1.Button1Click(Sender: TObject); begin SetPropValue(Self, 'button1.caption', 'test'); SetPropValue(Self, 'button1.width', '200'); SetPropValue(Self, 'label1.Visible', false); end;
// 动态调用函数/过程
type TMyProcedure = procedure of object; TMyMethod = function(x, y: Integer): integer of object;
function GetMethod(obj: TObject; MethodName: string): TMethod; var Rounte: TMethod; begin Result := nil; Rounte.Data := Pointer(obj); Rounte.Code := obj.MethodAddress(MethodName); if not System.Assigned(Rounte.Code) then Exit; Result := Rounte; end;
procedure Form1.Button1Click(Sender:TObject); var m1: TMyProcedure; m2: TMyMethod; i:Integer; begin m1 := TMyProcedure(GetMethod(Self, 'show')); m1(); // execute m2 := TMyMethod(GetMethod(), 'Add'); i := m2(1,2); // execute end;
浙公网安备 33010602011771号