Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.06.2008, 17:35   #1
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию Автоматическое уничтожение объекта

Как в своем классе сделать так чтобы его объект автоматически уничтожался, когда уничтожается родитель?
Код:
TMyClass = class
  MyPaint: TPaintBox;
  Timer: TTimer;
  procedure MyPaintDraw(Sender: TObject);
  procedure MyPaintMouseMove(Sender: TObject; Shift: TShiftState; X,
  procedure TimerTick(Sender: TObject);
  constructor Create(Owner: TComponent; ParentCtrl: TWinControl; fn: string);
  destructor Destroy; override;
  end;

{MyClass}

constructor TMyClass.Create(Owner: TComponent; ParentCtrl: TWinControl; fn: string);
begin
MyPaint:=TPaintBox.Create(Owner);
MyPaint.Parent:=ParentCtrl;
MyPaint.Align:=alClient;
MyPaint.OnPaint:=MyPaintDraw;
MyPaint.OnMouseMove:=MyPaintMouseMove;
Timer:=TTimer.Create(Owner);
Timer.OnTimer:=TimerTick;
//Parent:=ParentCtrl;
end;

destructor TMyClass.Destroy;
begin
FreeAndNil(Timer);
FreeAndNil(MyPaint);
end;

//в программе

//MyTab: TTabSheet;
MyClass:=TMyClass.Create(Form1,MyTab,fn);

//освобождение вкладки, мне надо чтобы автоматически освобождался мой объект
PageControl1.ActivePage.Free;
Другими словами как заставить срабатывать деструктор Destroy?
Пробовал унаследовать его от TControl
TMyClass = class(TControl)
и затем назначить родителя
Parent:=ParentCtrl;
эта строка вызывает ошибку при выполнении, присваивание свойству Owner:=ParentCtrl; ошибки не вызывает но и не работает, Destroy не вызывается.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 24.06.2008 в 17:40.
mutabor вне форума Ответить с цитированием
Старый 24.06.2008, 17:57   #2
NikLik
Форумчанин
 
Аватар для NikLik
 
Регистрация: 22.11.2007
Сообщений: 224
По умолчанию

В деструктор MyTab(ParentCtrl) добавить строчку MyClass.Destroy.
Если таковых не 1, а больше, можно просто перебрать все компоненты и посмотреть на (Owner=ParentCtrl) и класс.
NikLik вне форума Ответить с цитированием
Старый 24.06.2008, 19:38   #3
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Если наследовать от TControl, то так:

Код:
type
   TMyClass = class(TControl)
      constructor Create(Owner: TComponent; ParentCtrl: TWinControl; fn: string);
      destructor Destroy; override;
   end;

constructor TMyClass.Create(Owner: TComponent; ParentCtrl: TWinControl; fn: string);
begin
   inherited Create(ParentCtrl);
   // не присваивание - а именно вызов констрактора
end;
Не совсем корректно поступаем с констрактором (в смысле замещаем виртуальный), но работает.

Последний раз редактировалось alexBlack; 24.06.2008 в 20:28.
alexBlack вне форума Ответить с цитированием
Старый 25.06.2008, 20:19   #4
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

alexBlack, так Destroy автоматически вызывается, но... Опять ошибка в ntdll

У меня уже каша в голове от этих Owner, Parent и прочего.

Вобщем опишу задачу, к-рую хочу реализовать: есть свой класс, в нем таймер и пэйнтбокс, ну и другие нужные мне свойства. Объекты этого класса создаются динамически. Родителем (пэйнтбокса как минимум) должен быть TTabSheet (это обязательно, на нем они отображаются) остальное не ясно, кто должен быть родителем (Parent), владельцем (Owner) моего объекта, объектов (таймер и прочие) внутри моего? Как вообще правильно реализуется этот механизм автоматического освобождения?

p.s. Я тут подумал, можно убрать все мое из конструктора, и вынести в метод, и вызывать следом за созданием объекта этот метод и передать в него что нужно. А конструктор сделать стандартный каким он должен быть, может так будет лучше?
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 25.06.2008 в 20:29.
mutabor вне форума Ответить с цитированием
Старый 25.06.2008, 20:55   #5
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

В первый раз просмотрел:

Код:
constructor Create;
MyPaint:=TPaintBox.Create(Owner);   
Timer:=TTimer.Create(Owner);   
...  
destructor TMyClass.Destroy;   
begin  
FreeAndNil(Timer);      // Мы не должны освобождать эти объекты
FreeAndNil(MyPaint);   // Их освободит владелец
Вот пример:

Код:
type
  TMyClass = class(TControl)
     MyPaint: TPaintBox;
     Timer: TTimer;
     constructor Create(aOwner: TComponent); override;
     destructor Destroy; override;
     procedure Connect(AParent:TWinControl);
  end;

// Owner - владелец - он же уничтожает наш объект.
// Если не указан, то мы сами должны освободить
constructor TMyClass.Create(aOwner: TComponent);
begin
   inherited Create(aOwner);
   MyPaint := TPaintBox.Create(aOwner);
   Timer := TTimer.Create(nil);
end;

destructor TMyClass.Destroy;
begin
   //MYPaint.free;    уничтожится при удалении владельца
   Timer.free;     // timer без владельца, поэтому уничтожаем сами
   ShowMessage('aaa');
   inherited Destroy;
end;

// Устанавливает объект, на котором будет отображаться
procedure TMyClass.Connect(AParent:TWinControl);
begin
   MyPaint.Parent := aParent;
end;

procedure TForm1.FormCreate(Sender: TObject);
var C:TMyClass;
begin
   C := TMyClass.Create(TabSheet1);
   C.Connect(TabSheet1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   TabSheet1.free;
end;
-----------------------
Кстати, кто уничтожает TabSheet ? С этим то-же могут быть проблемы. В методах MyClass этого делать не желательно. Лучше отправить сообщение форме чтобы она уничтожила.

Последний раз редактировалось alexBlack; 25.06.2008 в 21:09.
alexBlack вне форума Ответить с цитированием
Старый 25.06.2008, 22:09   #6
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

alexBlack, Спасибо большое.

Уже потихоньку своим ходом приблизительно до такого же варианта дошел, с помощью исходников VCL (делал по аналогии как там) и метода тыка.
Первая ошибка у меня была: при создании владельцем указывал форму а родителем вкладку, из-за этого и была ошибка в ntdll.
Вторая ошибка: вызывал Free сам в деструкторе, но тут меня удивило, везде пишут что Free проверяет объект или он не nil, не ожидал что ошибку вызовет, даже если не нужно оно там. Кстати они и не были nil, я проверил, значит ошибка была из-за повторного вызова Free.

Еще небольшой вопрос про это: Timer := TTimer.Create(nil); не встречал раньше такого.
Я туда того же владельца передавал, что и пэйнтбоксу, работает. Есть ли какая существенная разница, или можно и так и так?
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Старый 25.06.2008, 22:25   #7
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Цитата:
Сообщение от mutabor Посмотреть сообщение
Еще небольшой вопрос про это: Timer := TTimer.Create(nil); не встречал раньше такого.
Я туда того же владельца передавал, что и пэйнтбоксу, работает. Есть ли какая существенная разница, или можно и так и так?
Разницы в-общем-то нет.
Просто объект внутри класса. Указываем, что у него нет владельца и сами потом освобождаем.

Второй вариант - указываем владельца TTimer.Create(aOwner) и освождать будет владелец.

Просто мне видится более корректным если объект инкапсулирован в классе, то и управлять им должен этот класс, не зачем передавать его другому владельцу. С TPaintBox так не получается, т.к. он будет отображаться, поэтому владельцем указываем панель.
alexBlack вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создание/уничтожение объектов nimf Общие вопросы Delphi 10 14.04.2008 10:54
Автоматическое перемещение Kirik JavaScript, Ajax 4 16.11.2007 17:42
Уничтожение окна Kashp Win Api 20 07.09.2007 14:15
Автоматическое сохранение AndreichSB Microsoft Office Access 1 03.01.2007 23:15