Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.07.30;
Скачать: CL | DM;

Вниз

Создание потомка TComponent с нестандартным владельцем   Найти похожие ветки 

 
FunkyByte ©   (2006-01-03 18:59) [0]

Доброго времени суток, уважаемые мастера. Попытался я сделать класс-потомок TComponent, который требовал бы себе в качастве владельца объект класса TForm, а не TComponent. Думал, что всё пройдёт просто - достаточно перекрыть конструктор TComponent следующим образом:

type
 TMyClass = class(TComponent)
   public
     constructor Create (AOwner: TForm);
 end;

implementation

constructor TMyClass.Create(AOwner: TForm);
begin
 inherited;
end;

В ответ на это компиллятор выдал мне сообщение о несовместимости типов (ошибку короче). Непонятно правда, почему. Ведь если создавать какой-либо компонент в design-time и в качестве владельца при вызове его конструктора указать объект класса TForm, то ошибок не будет.
Вот и возникло у меня 2 вопроса: почему возникает вышеупомянутая ошибка и как создать объект-потомок TComponent, требующий в качестве владельца себе объект класса TForm или его потомков?
Заранее благодарен.


 
FrykT ©   (2006-01-03 19:17) [1]

Если  должна быть проверка, AOwner это TForm или нет, можно сделать так:

type
TMyClass = class(TComponent)
  public
    constructor Create (AOwner: TComponent); override;
end;

implementation

constructor TMyClass.Create(AOwner: TComponent);
begin
inherited;
if AOwner is TForm then
 //Хы... чтото делаем
end;


>>почему возникает вышеупомянутая ошибка
потому-что конструктор у TComponent идёт вида constructor Create (AOwner: TComponent);
а тут вы пытаетесь вызвать inherited метод, да еще и не перекрывая несуществующего конструктора :)))

В коде выше, то что я написал, если AOwner не TForm , то я незнаю как прервать создание компонента, но это можно сделать.


 
FrykT ©   (2006-01-03 19:18) [2]

Поясните подробнее, что вы хотите сделать


 
Юрий Зотов ©   (2006-01-03 19:53) [3]

> FunkyByte ©   (03.01.06 18:59)  

> достаточно перекрыть конструктор TComponent следующим образом

Таким образом Вы его не перекрыли, а спрятали (о чем компилятор, кстати, предупреждал). См. reintroduce.

> компиллятор выдал мне сообщение о несовместимости типов

Потому что вызов inherited без указания имени метода предполагает полную идентичность параметров, а они у Вас не идентичны. При таком вызове ошибки возникать не должно:
inherited Create(AOwner);

> как создать объект-потомок TComponent, требующий в качестве
> владельца себе объект класса TForm или его потомков?

Так, как написано в [1], только код конструктора надо немного изменить:

constructor TMyClass.Create(AOwner: TComponent);
begin
 if not (AOwner is TForm) then
   raise Exception.Create("Owner must be TForm");
 inherited;
 ... // Здесь остальной код конструктора, если он нужен
end;

> FrykT ©   (03.01.06 19:17) [1]
> я незнаю как прервать создание компонента
Надо возбудить исключение в любом месте конструктора.


 
FunkyByte ©   (2006-01-03 21:21) [4]

Сорри, я не совсем корректно поставил вопрос. Дело в том, что необходимо, чтобы владелец класса TForm требовался ещё в design-time и при попытке "подсунуть" конструктору моего класса в качестве владельца объект класса, стоящего выше TForm в дереве классов, возникала ошибка при компилляции.


 
GuAV ©   (2006-01-03 22:11) [5]

Юрий Зотов ©   (03.01.06 19:53) [3]

> Так, как написано в [1], только код конструктора надо
>немного изменить:
>
>constructor TMyClass.Create(AOwner: TComponent);
>begin
> if not (AOwner is TForm) then
>   raise Exception.Create("Owner must be TForm");
> inherited;
>  ... // Здесь остальной код конструктора, если он
>нужен
> end;


А зачем изменять ?


 
Юрий Зотов ©   (2006-01-03 23:40) [6]

> FunkyByte ©   (03.01.06 21:21) [4]
Без разницы, см. [3].

> GuAV ©   (03.01.06 22:11) [5]
Чтобы уничтожить неверно созданный объект.


 
FunkyByte ©   (2006-01-04 01:32) [7]


>Юрий Зотов ©   (03.01.06 23:40) [6]
> Без разницы, см. [3].

Как показывает практика, разница есть. Перекрыв указанным вами способом конструктор, написал следующий код:

procedure TForm1.Button1Click(Sender: TObject);
begin
 MyClass1:=TMyClass.Create(Form1.Button1);
end;

Компиллятор в ответ на это даже предупреждение не выдал, не говоря уже об ошибке (оно и не удивительно, если проверка класса объекта-владельца происходит в run-time). Хотя TButton - это не TForm и не его потомок.


 
Юрий Зотов ©   (2006-01-04 01:58) [8]

> FunkyByte ©   (04.01.06 01:32) [7]

> Перекрыв указанным вами способом конструктор

Значит, где-то напортачено. Похоже, что конструктор Вы так и не перекрыли. Показывайте код (объявление класса и конструктор).

> проверка класса объекта-владельца происходит в run-time

То есть, в design-time, конструктор, по-Вашему, не отрабатывает? Это новость.


 
FunkyByte ©   (2006-01-04 10:21) [9]

Код в студии:

type
 TMyClass = class(TComponent)
 public
   constructor Create(AOwner: TComponent); override;
 end;

implementation

constructor TMyClass.Create(AOwner: TComponent);
begin
 if not (AOwner is TForm) then raise Exception.Create("Owner must be TForm");
 inherited;
end;

И ещё хотелось бы уточнить: design-time - это этап собственно набивания кода, я правильно понимаю?


 
Юрий Зотов ©   (2006-01-04 12:19) [10]

> FunkyByte ©   (04.01.06 10:21) [9]

Ошибок нет, работать обязано (если только TMyClass не сидит в DLL, собранной без run-time пакетов).

Design-time - это этап, когда компонент работает в среде IDE, а не в среде нашей еще не запущенной программы. Когда компонент кладут на форму, IDE вызывает его конструктор и далее компонент УЖЕ работает.

Набивание кода тут ни при чем (ведь Delphi - это не интерпретатор, поэтому код, который еще не скомпилирован - это пока еще просто текст, а не код, работать он не может).


 
DimaBr   (2006-01-04 14:58) [11]


> Сорри, я не совсем корректно поставил вопрос. Дело в том,
>  что необходимо, чтобы владелец класса TForm требовался
> ещё в design-time и при попытке "подсунуть" конструктору
> моего класса в качестве владельца объект класса, стоящего
> выше TForm в дереве классов, возникала ошибка при компилляции.
>

GetParentForm - вам поможет» Юрий Зотов:» Компонент невизуальный, GetParentForm не поможет. Да и при чем тут GetParentForm, если нужно проверить класс владельца?


 
vuk ©   (2006-01-05 20:50) [12]

Ышшо можно ValidateContainer перекрыть.


 
vuk ©   (2006-01-06 15:45) [13]

Перекрывать нужно именно ValidateContainer, а не конструктор, иначе можно оконфузится. :o)


 
Юрий Зотов ©   (2006-01-06 16:19) [14]

> vuk ©   (06.01.06 15:45) [13]

Леш, имеешь в виду Insert/RemoveComponent?


 
vuk ©   (2006-01-06 16:23) [15]

Угу.


 
vuk ©   (2006-01-06 16:26) [16]

Да и вообще, создать можно с AOwner = nil, а потом уже делать InsertComponent. При этом если проверять в конструкторе, создание проходит, и вставка тоже, а Owner может получиться тот, которого не должно быть.


 
tech ©   (2006-01-08 21:39) [17]

constructor TMyClass.Create(AOwner: TComponent);
begin
if not (AOwner is TForm) then raise Exception.Create("Owner must be TForm");
inherited;
end;

Этот эксепшен сработает и в design-time но только ПОСЛЕ того, как компонент будет включен в среду Дельфи в составе одного из пакетов.
Т.Е. - новый компонент должен быть и скомпилирован, И ИНСТАЛЛИРОВАН в Дельфи.» Юрий Зотов:» Действительно. Иначе будет довольно сложно положить его на форму. А без этого довольно сложно вообще говорить о каком-либо design-time.



Страницы: 1 вся ветка

Текущий архив: 2006.07.30;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.036 c
2-1152204596
SergP.
2006-07-06 20:49
2006.07.30
О порядке деструкции объектов которые создаются автоматически


2-1152625504
Grotesque
2006-07-11 17:45
2006.07.30
Небольшой вопрос


3-1148722578
alex1980
2006-05-27 13:36
2006.07.30
производительность SqlServ2000


1-1150388056
***(H@kker)***
2006-06-15 20:14
2006.07.30
Изменение ресурса файла


2-1152324813
antoxa2005
2006-07-08 06:13
2006.07.30
Что это:подключение не установлено т.к. конечный компьютер отверг