Получить класс по его имени в Delphi

Я хотел бы написать функцию, которая принимает имя класса и возвращает соответствующий TClass. Я заметил, что функция System.Classes.GetClass не работает, если имя класса не зарегистрировано.

Пример:

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

Предыдущий код всегда показывает:

TButton не найден!

Чего-то не хватает?


person Hwau    schedule 06.04.2015    source источник


Ответы (1)


Вы можете получить незарегистрированный класс, используемый в приложении Delphi, через расширенный RTTI. Но вы должны использовать полное имя класса, чтобы найти класс. 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;
person Dalija Prasnikar    schedule 06.04.2015
comment
Спасибо за четкий и полный ответ. Я полагаю, что нет обходного пути, чтобы избежать использования полного имени класса. - person Hwau; 07.04.2015
comment
Я добавил дополнительную функцию, которую вы можете использовать без использования полного имени класса. - person Dalija Prasnikar; 07.04.2015
comment
Удивительно! Я не разбираюсь в использовании Rtti, я бы никогда не нашел решение! Большое тебе спасибо! - person Hwau; 07.04.2015