2015-04-06 98 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