2015-04-06 220 views
3

我想编写一个接受类名并且产生相应TClass的函数。我注意到,System.Classes.GetClass函数不起作用,如果类名未注册。在Delphi中通过名称获取类

例子:

if(GetClass('TButton') = nil) 
then ShowMessage('TButton not found!') 
else ShowMessage('TButton found!'); 

上面的代码总是显示 'TButton的不存在!'。 有什么缺失? 希望有人能帮助我。 谢谢!

回答

5

您可以通过扩展RTTI获取Delphi应用程序中使用的未注册类。但是你必须使用完全合格的类名来查找类。 TButton是不够的,你必须寻找Vcl.StdCtrls.TButton

uses 
    System.Classes, 
    System.RTTI; 

var 
    c: TClass; 
    ctx: TRttiContext; 
    typ: TRttiType; 
begin 
    ctx := TRttiContext.Create; 
    typ := ctx.FindType('Vcl.StdCtrls.TButton'); 
    if (typ <> nil) and (typ.IsInstance) then c := typ.AsInstance.MetaClassType; 
    ctx.Free; 
end; 

注册类确保类将被编译成Delphi应用程序。如果在代码中没有使用类并且没有注册,它将不会出现在应用程序中,在这种情况下,扩展RTTI将有任何用处。

附加功能,将返回任何类(注册),而不使用完全合格的类名:

uses 
    System.StrUtils, 
    System.Classes, 
    System.RTTI; 

function FindAnyClass(const Name: string): TClass; 
var 
    ctx: TRttiContext; 
    typ: TRttiType; 
    list: TArray<TRttiType>; 
begin 
    Result := nil; 
    ctx := TRttiContext.Create; 
    list := ctx.GetTypes; 
    for typ in list do 
    begin 
     if typ.IsInstance and (EndsText(Name, typ.Name)) then 
     begin 
      Result := typ.AsInstance.MetaClassType; 
      break; 
     end; 
    end; 
    ctx.Free; 
end; 
+0

谢谢清晰,完整的答案。我想没有解决方法来避免完全限定类名的用法。 – Hwau 2015-04-06 21:41:59

+0

我已添加额外的功能,您可以使用,而无需使用完全合格的类名 – 2015-04-07 07:51:56

+0

令人惊叹!我不熟练使用Rtti,我永远也找不到解决方案! 谢谢你! – Hwau 2015-04-07 17:45:09