бросок TObject использование его ClassType?

Для 'слова замены', попробуйте cw в нормальном режиме.

Для 'абзаца замены', попробуйте cap в нормальном режиме.

5
задан Alin Sfetcu 4 July 2009 в 22:33
поделиться

5 ответов

Было бы проще использовать RTTI вместо явного приведения, например:

uses
  TypInfo;

setCtrlState([ memo1, edit1, button1], False);

procedure setCtrlState(objs: array of TObject; bState: boolean = True);
var
  obj: TObject;
  PropInfo: PPropInfo;
begin
  for obj in objs do
  begin
    PropInfo := GetPropInfo(obj, 'ReadOnly');
    if PropInfo <> nil then SetOrdProp(obj, PropInfo, not bState);

    PropInfo := GetPropInfo(obj, 'Enabled');
    if PropInfo <> nil then SetOrdProp(obj, PropInfo, bState);
  end;
end;
5
ответ дан 18 December 2019 в 07:31
поделиться

Вам необходимо преобразовать объект ct в TMemo / TEdit / TButton, прежде чем вы сможете установить свойства объекта.

Строка, в которой вы получаете ошибки, содержит ошибку, потому что ct все еще TClass, а не TButton / и т. д. Если вы приведете к TButton, то вы сможете установить для параметра enabled значение true.

Я рекомендую прочитать приведение в Delphi . Лично я бы также рекомендовал использовать операторы as / is вместо ClassType. В этом случае код будет проще и понятнее.


Лично я бы написал это скорее так:

procedure setCtrlState(objs: array of TObject; bState: boolean = True);
var
  obj: TObject;
begin
  for obj in objs do
  begin
    // I believe these could be merged by using an ancestor of TMemo+TEdit (TControl?)
    // but I don't have a good delphi reference handy
    if (obj is TMemo) then
        TMemo(obj).ReadOnly := not bState;

    if (obj is TEdit) then
        TEdit(obj).ReadOnly := not bState;

    if (obj is TButton) then
        TButton(obj).Enabled := bState;
  end;
end;
4
ответ дан 18 December 2019 в 07:31
поделиться

Нет необходимости выполнять приведение к TMemo и TEdit по отдельности, поскольку они оба являются потомками общего родительского класса, который имеет свойство ReadOnly:

procedure TForm1.FormCreate(Sender: TObject);

  procedure P(const Obj: TComponent);
  begin
    if Obj is TCustomEdit then
      TCustomEdit(Obj).ReadOnly := True;
  end;

begin
  P(Memo1);
  P(Edit1);
end;
3
ответ дан 18 December 2019 в 07:31
поделиться

Вы должны явно преобразовать возражать против какого-то класса. Это должно работать:

 procedure setCtrlState(objs: array of TObject; bState: boolean = True);
 var
   obj: TObject;
   ct: TClass;
 begin
  for obj in objs do
  begin
    ct := obj.ClassType;

    if ct = TMemo then
      TMemo(obj).ReadOnly := not bState
    else if ct = TEdit then
      TEdit(obj).ReadOnly := not bState
    else if ct = TButton then
      TButton(obj).Enabled := bState;
  end;
end;

Это можно сократить с помощью оператора « is » - переменная ct не требуется:

 procedure setCtrlState(objs: array of TObject; bState: boolean = True);
 var
   obj: TObject;
 begin
   for obj in objs do
   begin
     if obj is TMemo then
       TMemo(obj).ReadOnly := not bState
     else if obj is TEdit then
       TEdit(obj).ReadOnly := not bState
     else if obj is TButton then
       TButton(obj).Enabled := bState;
   end;
 end;
7
ответ дан 18 December 2019 в 07:31
поделиться

Вы можете избежать ссылок на различные блоки и явного приведения типов, если не возражаете против небольшого снижения производительности и ограничиваете изменения опубликованными свойствами. Взгляните на модуль TypInfo, включенный в Delphi.

2
ответ дан 18 December 2019 в 07:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: