Изучение ООП

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: Изучение ООП

Сообщение Александр Яшин » 15.04.2010 12:17:02

Получается, что владельцем второй формы надо назначать Form1, а не глобальный объект Application?
Почему можно писать и так:
Код: Выделить всё
Form2:= TForm.Create(Form1);
и так:
Код: Выделить всё
Form2:= TForm1.Create(Form1);
Последний раз редактировалось Александр Яшин 15.04.2010 12:49:07, всего редактировалось 3 раз(а).
Александр Яшин
новенький
 
Сообщения: 67
Зарегистрирован: 21.11.2009 09:31:01

Re: Изучение ООП

Сообщение AbakAngelSoft » 15.04.2010 12:37:02

Александр Яшин писал(а):Почему можно писать и так:

Потому-что у вас Form2 имеет тип TForm т.е. может содержать указатель на объект любого класса-потомка TForm
Если необходимо обезопасить себя нужно указать корректный тип, например
Код: Выделить всё
Form2: TForm2;
Аватара пользователя
AbakAngelSoft
постоялец
 
Сообщения: 273
Зарегистрирован: 06.08.2008 19:28:26
Откуда: Краснодар

Re: Изучение ООП

Сообщение Александр Яшин » 15.04.2010 12:49:54

1. Если закрыть вторую форму кнопкой закрытия окна, то форма останется в памяти и будет окончательно уничтожена только после закрытия Form1?
2. Как ее сразу уничтожить при нажатии кнопки закрытия? Т.е. как вставить обработчик OnDestroy, ведь в инспекторе объектов свойств Form2 не видно.
Александр Яшин
новенький
 
Сообщения: 67
Зарегистрирован: 21.11.2009 09:31:01

Re: Изучение ООП

Сообщение Climber » 15.04.2010 13:13:30

Александр Яшин писал(а):1. Если закрыть вторую форму кнопкой закрытия окна, то форма останется в памяти и будет окончательно уничтожена только после закрытия Form1?
Да.
Александр Яшин писал(а):2. Как ее сразу уничтожить при нажатии кнопки закрытия? Т.е. как вставить обработчик OnDestroy, ведь в инспекторе объектов свойств Form2 не видно.

Точно не уверен, но вроде бы в обработчик OnClose надо вставить вызов то ли Release, то ли чего-то подобного...
Второй вариант - в Form1 сделать процедуру с единственным параметром Sender и написать примерно так:
Код: Выделить всё
procedure TForm1.FormDestroyer(Sender: TObject);
begin
  FreeAndNil(Form2);
end;
// где-нибудь типа обработчика TForm2.OnCreate написать:
OnClose:=@Form1.FormDestroyer;
За кошерность советов не ручаюсь, но у меня что-то типа такого работало ;)
Sergei I. Gorelkin писал(а):Это известная фраза, но означает она то, что эти среды навязывают определенный стиль кода, который соотносится и с ООП, и с правильным дизайном довольно-таки опосредованно.
Это многое объясняет!!! Меня давно терзали смутные сомнения, но теперь все встало на свои места. Я пытался изучать тру ООП и соотносить с тем, что я вижу в Delphi и меня не оставляло чувство смутного беспокойства, что либо что-то здесь не так, либо я чего-то не понимаю. Оказалось, что верно первое.
Стоит, однако, заметить, что "навязывают" не значит "запрещают делать иначе". Хотя в большинстве случаев (в том числе моем :oops: ) навязывание прошло успешно.
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Изучение ООП

Сообщение AbakAngelSoft » 15.04.2010 13:20:50

Александр Яшин писал(а):Как ее сразу уничтожить при нажатии кнопки закрытия? Т.е. как вставить обработчик OnDestroy, ведь в инспекторе объектов свойств Form2 не видно.


Код: Выделить всё
TForm2 = ...
protected
    procedure DoClose(var CloseAction: TCloseAction); override;
end;

procedure TForm2.DoClose(var CloseAction: TCloseAction);
begin
  inherited DoClose(CloseAction);
  CloseAction := caFree;
end;
Аватара пользователя
AbakAngelSoft
постоялец
 
Сообщения: 273
Зарегистрирован: 06.08.2008 19:28:26
Откуда: Краснодар

Re: Изучение ООП

Сообщение Александр Яшин » 15.04.2010 13:23:08

Climber писал(а):// где-нибудь типа обработчика TForm2.OnCreate написать:
OnClose:=@Form1.FormDestroyer;
[/code]


unit1.pas(54,14) Error: Incompatible types: got "<procedure variable type of procedure(TObject) of object;Register>" expected "<procedure variable type of procedure(TObject,var TCloseAction) of object;Register>"
Александр Яшин
новенький
 
Сообщения: 67
Зарегистрирован: 21.11.2009 09:31:01

Re: Изучение ООП

Сообщение AbakAngelSoft » 15.04.2010 13:28:17

еще желательно в той форме где хранится ссылка контролировать самоуничтожение дочерней формы наиболее правильно это будет делать так:
при создании формы:
Код: Выделить всё
  Form2 := TForm.Create(Application);
  Form2.FreeNotification(Self);

а самой форме - хозяине:
Код: Выделить всё
TForm1 = ...
protected
  procedure Notification(AComponent: TComponent; Operation: TOperation); override;
end;

procedure TForm1.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and (AComponent = Form2) then Form2 := nil;
end;


Добавлено спустя 2 минуты 34 секунды:
Да и еще не забываем случай если Form1 будет уничтожена до Form2:

Код: Выделить всё
  TForm1 = ...
  public
    destructor Destroy; override;
  end;

destructor TForm1.Destroy;
begin
  if Assigned(Form2) then Form2.RemoveFreeNotification(Self);
  inherited Destroy;
end;
Аватара пользователя
AbakAngelSoft
постоялец
 
Сообщения: 273
Зарегистрирован: 06.08.2008 19:28:26
Откуда: Краснодар

Re: Изучение ООП

Сообщение Александр Яшин » 15.04.2010 13:35:30

AbakAngelSoft писал(а):
Код: Выделить всё
TForm2 = ...
protected
    procedure DoClose(var CloseAction: TCloseAction); override;
end;

procedure TForm2.DoClose(var CloseAction: TCloseAction);
begin
  inherited DoClose(CloseAction);
  CloseAction := caFree;
end;


В примере рассматривается случай динамического создания формы, т.е. без предварительного создания класса формы TForm2.
Александр Яшин
новенький
 
Сообщения: 67
Зарегистрирован: 21.11.2009 09:31:01

Re: Изучение ООП

Сообщение AbakAngelSoft » 15.04.2010 13:45:08

Александр Яшин писал(а):без предварительного создания класса формы TForm2.

не кошерно, но собственно ничего не меняеться и в этом случае:
Код: Выделить всё
  Form2 := TForm.Create(Application);
  Form2.FreeNotification(Self);
  Form2.OnClose := @Form2Close;

procedure TForm1.Form2Close(Sender: TObject; var CloseAction: TCloseAction);
begin
  CloseAction := caFree;
end;


Добавлено спустя 56 секунд:
Кстати класс формы можно создать и без дизайнера, а как обычный класс ручками - если загвоздка в этом!
Аватара пользователя
AbakAngelSoft
постоялец
 
Сообщения: 273
Зарегистрирован: 06.08.2008 19:28:26
Откуда: Краснодар

Re: Изучение ООП

Сообщение Александр Яшин » 15.04.2010 14:09:06

Нет, не в этом. Мне нужно написать программу в которой пользователь может воспользоваться функцией поиска. Но, может случиться так, что пользователь этой функцией и не воспользуется. В таком случае не хотелось заранее "зря" создавать вторую форму. Поэтому возникла идея создавать эту форму динамически, лишь когда это необходимо.
Предложенный тобой код работает. Спасибо!
Кстати, посмотри весь пример.Вторая форма создается "ручками".
Александр Яшин
новенький
 
Сообщения: 67
Зарегистрирован: 21.11.2009 09:31:01

Re: Изучение ООП

Сообщение AbakAngelSoft » 15.04.2010 14:15:59

Я про это и говорил:
класс можно создать руками без дизайнера, тогда форма не будет создаваться при старте программы.
И даже используя дизайнер форму можно выкинуть из списка автосоздаваемых.
"Проект" > "Параметры проекта" > "Формы"
Все что в левом списке будет создано при старте, а то что в правом надо создавать во время выполнения.
Аватара пользователя
AbakAngelSoft
постоялец
 
Сообщения: 273
Зарегистрирован: 06.08.2008 19:28:26
Откуда: Краснодар

Re: Изучение ООП

Сообщение VirtUX » 07.06.2010 22:26:46

У меня такой вопрос: Если компоненты создаются по принципу
Код: Выделить всё
NewComponent  := TNewComponent.Create(ParentPanel);
NewComponent.Parent := ParentPanel;
, то при
Код: Выделить всё
FreeAndNil(ParentPanel);
все NewComponent тоже корректно уничтожатся или нужно их вручную уничтожать?
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Изучение ООП

Сообщение скалогрыз » 07.06.2010 23:08:07

VirtUX писал(а):У меня такой вопрос: Если компоненты создаются по принципу
Код: Выделить всё
NewComponent  := TNewComponent.Create(ParentPanel);
NewComponent.Parent := ParentPanel;
, то при
Код: Выделить всё
FreeAndNil(ParentPanel);
все NewComponent тоже корректно уничтожатся или нужно их вручную уничтожать?

y TComponent нет свойства Parent, у них есть свойство Owner.
свойство Parent есть только у TControl-ов

так вот, все компоненты, которым ParentPanel приходиться Owner-ом - будут уничтожены.
но контролы, которым, ParentPanel приходиться Parent-ом НЕ БУДУТ уничтожены, зато их Parent обратится в nil!

грубо говоря так:
Owner-отвечает за "период жизни"
Parent-отвечает за глазуальный порядок (порядок отрисовки, переключения фокуса, видимость, доступность (enabled))
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Изучение ООП

Сообщение VirtUX » 07.06.2010 23:16:00

скалогрыз писал(а):y TComponent нету свойства Parent, у них есть свойство Owner.
свойство Parent есть только у TControl-ов

Это я образно.
скалогрыз писал(а):так вот, все компоненты, которым ParentPanel приходиться Owner-ом - будут уничтожены.
но контролы, которым, ParentPanel приходиться Owner-ом НЕ БУДУТ уничтожены, зато их Parent обратится в nil!

Жаль. А было б удобно иметь свойство ClearPredDestroy: boolean;, где TRUE - очищать перед деструкцией все TWinControl созданные с Parent равным этому объекту (Self).
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Изучение ООП

Сообщение скалогрыз » 07.06.2010 23:20:26

VirtUX писал(а):Жаль. А было б удобно иметь свойство ClearPredDestroy: boolean;, где TRUE - очищать перед деструкцией все TWinControl созданные с Parent равным этому объекту (Self).

если я не ошибаюсь, то при загрузке компонентов с формы, Owner и Parent у каждого загруженного объекта одинаковые.

однако, что мешает?
Код: Выделить всё
procedure SetChildsOwnerToSelf(AControl: TWinControl);
var
  i : integer;
begin
  if not Assigned(AControl) then Exit;
  for i:=0 to AControl.ContolCount-1 do
    AControl.Controls[i].Owner:=AControl;
end;
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Пред.След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 38

Рейтинг@Mail.ru