Форум: "Компоненты";
Текущий архив: 2006.07.30;
Скачать: [xml.tar.bz2];
ВнизСоздание потомка 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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.013 c