2013-02-07 21 views
8

Chcę utworzyć formularz podając jego nazwę klasy jako ciąg, which has been asked about before, ale zamiast wywoływania GetClass, chcę użyć nowej funkcji RTTI Delphi.Jak utworzyć instancję klasy z jej TRttiType?

Z tym kodem, mam TRttiType, ale nie wiem jak go utworzyć.

var 
    f:TFormBase; 
    ctx:TRttiContext; 
    lType:TRttiType; 
begin 
    ctx := TRttiContext.Create; 
    for lType in ctx.GetTypes do 
    begin 
    if lType.Name = 'TFormFormulirPendaftaran' then 
    begin 
     //how to instantiate lType here? 
     Break; 
    end; 
    end; 
end; 

Próbowałem również lType.NewInstance bez powodzenia.

Odpowiedz

9

Musisz rzucić TRttiType do klasy TRttiInstanceType, a następnie wywołać konstruktora, używając funkcji GetMethod.

Spróbuj próbkę

var 
    ctx:TRttiContext; 
    lType:TRttiType; 
    t : TRttiInstanceType; 
    f : TValue; 
begin 
    ctx := TRttiContext.Create; 
    lType:= ctx.FindType('UnitName.TFormFormulirPendaftaran'); 
    if lType<>nil then 
    begin 
    t:=lType.AsInstance; 
    f:= t.GetMethod('Create').Invoke(t.MetaclassType,[nil]); 
    t.GetMethod('Show').Invoke(f,[]); 
    end; 
end; 
+0

Po utworzeniu obiektu Form, nie trzeba już używać RTTI, aby wywołać metodę 'Show()'. Po prostu wywołaj to normalnie: 'f.Show;' –

+0

@RemyLebeau, na tym przykładzie f jest parametrem telewizyjnym, poza tym OP może wprowadzić zmienną helpera TForm lub po prostu rzucić TValue na format Tform, tak jak to 'TForm (f.AsObject) .Show; ' – RRUZ

+0

Przepraszam, nie zauważyłem, że' f' było 'TValue', patrzyłem na kod Niyoko kiedy to zobaczyłem. –

4

trzeba zastosować metodę TRttiContext.FindType() zamiast ręcznie pętli poprzez Mimo że lista TRttiContext.GetTypes(), np

lType := ctx.FindType('ScopeName.UnitName.TFormFormulirPendaftaran'); 
if lType <> nil then 
begin 
    ... 
end; 

ale tak czy inaczej, po zlokalizowaniu TRttiType dla żądany typ klasy, można utworzyć instancję w następujący sposób:

type 
    TFormBaseClass = class of TFormBase; 

f := TFormBaseClass(GetTypeData(lType.Handle)^.ClassType).Create(TheDesiredOwnerHere); 

Albo to, jeśli TFormBase pochodzi od TForm:

f := TFormClass(GetTypeData(lType.Handle)^.ClassType).Create(TheDesiredOwnerHere); 

Albo to, jeśli TFormBase pochodzi od TCustomForm:

f := TCustomFormClass(GetTypeData(lType.Handle)^.ClassType).Create(TheDesiredOwnerHere); 

Aktualizacja: Albo zrobić jak @RRUZ pokazał. Jest to bardziej ukierunkowane na TRttiType i nie polega na używaniu funkcji ze starszej jednostki TypInfo.

Powiązane problemy