Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Компоненты";
Текущий архив: 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
4-1145035048
Antoshka
2006-04-14 21:17
2006.07.30
форматирование флэшки


15-1151951015
Ketmar
2006-07-03 22:23
2006.07.30
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1151946511&n=18


3-1148547033
apl
2006-05-25 12:50
2006.07.30
Как ускорить работу?


15-1150998368
anton773
2006-06-22 21:46
2006.07.30
Поток


15-1151640852
tButton
2006-06-30 08:14
2006.07.30
вот такое вот сообщение пришло... думаю...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский