Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 03.02.2011, 14:42
vikk vikk вне форума
Начинающий
 
Регистрация: 01.10.2010
Сообщения: 132
Репутация: 10
По умолчанию Разрушение формы

Скажите мне, умные люди, ВСЕГДА ли при разрушении формы случается событие OnDestroy для этой формы? У меня оно как-то не случается, если форма разрушается косвенно(при разрушении формы-владельца).
Подробнее это выглядит так: На главной форме есть кнопка, при нажатии на которую создаётся другая форма, собственником которой является главная, т.е.
Код:
1
Form2 := TForm2.Create(self)
На протяжении жизни этой второй формы в ней производятся изменения данных, которые нужно сохранить в файле. Сохранение прописано в обработчике события TForm2.FormDestroy (раньше было даже в OnClose).
И вот какая засада - если пользователь закрывает приложение (стандартным крестиком на главной форме), не закрыв перед этим Form2(ведь таких неаккуратных - пруд пруди!), то событие TForm2.FormDestroy не наступает А какое событие второй формы наступает, если закрывается только форма, которая ею владеет? Куда запихнуть сохранение данных?
Ответить с цитированием
  #2  
Старый 03.02.2011, 14:47
Аватар для EvilRussian
EvilRussian EvilRussian вне форума
Начинающий
 
Регистрация: 21.12.2010
Адрес: Россия, Красноярский край
Сообщения: 177
Репутация: 22
По умолчанию

Ничё не понял.
Если я таки понял тебя, то просто при "косвенном" закрытии вызови событие Form2.Destroy или как там оно называется.
И будет тебе счастье.

Если неправильно я понял, то поясни ещё раз.
__________________
Если не ты, то кто?
(с) Терри Пратчетт

Не забывайте ставить плюсы и говорить спасибо!
Ответить с цитированием
  #3  
Старый 03.02.2011, 15:02
vikk vikk вне форума
Начинающий
 
Регистрация: 01.10.2010
Сообщения: 132
Репутация: 10
По умолчанию

ни разу не вызывала событие принудительно. Ты не покажешь, как это сделать? Нижеприведенный вариант, наверное, совсем того ?
Код:
1
2
3
4
5
procedure TMainForm.FormDestroy(Sender: TObject);
begin
 Form2.FormDestroy(Sender); 
{большие сомнения касательно того, что  пихать в качестве параметра обработчика}
end;
Ответить с цитированием
  #4  
Старый 04.02.2011, 10:18
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
uses Unit2;
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  with TForm2.Create(Application) do
  begin
    Show;
  end;
end;
 
end.

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
unit Unit2;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;
 
type
  TForm2 = class(TForm)
    procedure FormDestroy(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form2: TForm2;
 
implementation
 
{$R *.dfm}
 
procedure TForm2.FormDestroy(Sender: TObject);
begin
  Windows.Beep(1000, 100);
end;
 
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action:=caFree;
end;
 
end.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #5  
Старый 04.02.2011, 10:35
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 663
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

В качестве параметра пихай тот объект, который должен вызвать событие. В данном случае ты ждешь ОнДестрой от Форм2. Ну вот и пихай вместо Сендер твой Форм2.
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.
Ответить с цитированием
  #6  
Старый 07.02.2011, 10:58
vikk vikk вне форума
Начинающий
 
Регистрация: 01.10.2010
Сообщения: 132
Репутация: 10
По умолчанию

Спасибо, запихнула. Работает!
Попутно вопрос - у меня в последнее время уже при закрытии Delphi часто возникает "Access violation at adress... in dcc70.dll///", причём нервный такой - многократно повторяющийся - множащийся окошками. И его никак, кроме как перезагрузившись, не успокоить. Подозреваю, что это может происходить из-за неправильной организации работы с формами. Может кто сталкивался с такой штукой и даст совет - хотя бы как проверить?
У меня в приложении 4 формы с обычным шоу и три - с модальным. Те, которые с модальным, организованы по стандартному(где-то здесь вычитанному) шаблону:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
if Form1 = nil then
      Form1 := TForm1.Create(nil);
    try
      Form1.onAddNewExam := OnAddNewExam;//присвоение конкретной процедуры свойству
 
      if Form1.WindowState = wsMinimized then
        Form1.WindowState := wsNormal;
      if Form1.ShowModal = mrCancel then
        exit; {  может здесь собака зарыта? - она ж в этом случае   остаётся висеть, так? хотя я по этой ветке и не ходила ещё ((, а ошибка лезет }
    finally
      Form1.Free;
      Form1 := nil;
    end;

Формы, которые с обычным Show, создаются через TFormCreate(self), где self - это вышеупомянутая Form1. В каждой форме есть свойство типа TNotifyEvent, которое вызывается в CloseForm и сообщает форме-собственнику (ну, той самой Form1), что можно вызываемую рушить (а просто использовать Release в самой процедуре закрытия каждой формы вместо всех этих наворотов нельзя? ).
Может непонятно объясняю, лучше код выкладывать? Но он такой... длинновастенький
Ответить с цитированием
  #7  
Старый 07.02.2011, 16:04
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

Код:
1
2
3
4
5
6
7
8
...
<font color="Red">   if Form1.ShowModal = mrCancel then
        exit; </font>
 finally
   Form1.Free;
   Form1 := nil;
 end;
 ...

Последний раз редактировалось Asinkrit, 02.04.2011 в 20:22.
Ответить с цитированием
  #8  
Старый 07.02.2011, 16:05
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

Код:
1
2
3
4
5
6
7
8
...
<font color="Red">   if Form1.ShowModal = mrCancel then
        exit; </font>
 finally
   Form1.Free;
   Form1 := nil;
 end;
 ...

Последний раз редактировалось Asinkrit, 02.04.2011 в 20:22.
Ответить с цитированием
  #9  
Старый 08.02.2011, 10:54
vikk vikk вне форума
Начинающий
 
Регистрация: 01.10.2010
Сообщения: 132
Репутация: 10
По умолчанию

Да, очень доступно. Спасибо за подсказку! Попробую так поймать.
А многократное создание форм одного и того же типа при условии их корректного уничтожения - это нормально? Или лучше форму каждого типа создать один раз и потом открывать-закрывать?
Ещё хочу уточнить по поводу бессмысленного кода (красного): при такой организации текста он НИКОГДА не выполнится или просто сначала будет выполнен блок Finally, а потом всё-таки exit сработает? Дело в том, что у меня-то там дальше в этой процедуре ещё кусок кода, который нужно выполнить только в случае закрытия формы с mrOK.
Ответить с цитированием
  #10  
Старый 08.02.2011, 16:17
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

1234567890

Последний раз редактировалось Asinkrit, 02.04.2011 в 20:22.
Ответить с цитированием
  #11  
Старый 09.02.2011, 16:25
vikk vikk вне форума
Начинающий
 
Регистрация: 01.10.2010
Сообщения: 132
Репутация: 10
По умолчанию

Выкладываю (и нервно курю в сторонке) :
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{На главной форме есть бар с меню, состоящем из кнопок с названиями директорий, содержащих данные для конкретного процесса. Данные будут загружаться в зависимости от выбранной директории :}
procedure TMainForm.BtnExClick(Sender: TObject);
begin
with Sender as TdxBarButton do
    FocusedDir := Caption;
 
{если пользователь хочет создать новый процесс, то загружается спецформочка, в которой задаётся название нового процесса и пр. инфа для создания директории нового процесса :}
if FocusedDir = 'Новый' then
  begin
    if FormAddExam = nil then
      FormAddExam := TFormAddExam.Create(nil);
    try
      FormAddExam.onAddNewExam := OnAddNewExam; {Это свойство типа TNotifyEvent, сообщающее вызывающей форме введённое в спецформочке имя новой директории(чтоб создать новую кнопку меню на баре) }
 
      if FormAddExam.WindowState = wsMinimized then
        FormAddExam.WindowState := wsNormal;
 
      if FormAddExam.ShowModal = mrCancel then
        exit;
    finally
      FormAddExam.Free;
      FormAddExam := nil;
    end;
  end;
 
{если пользователь подтвердил создание нового процесса (форма закрылась с ModalResult = mrOK - там внутри возможны только 2 варианта ModalResult), то создаётся новая форма для осуществления толькочтосозданного процесса: }
  if FormExam <> nil then
    FormExam := nil;
  FormExam := TFormExam.Create(nil);
  FormExam.Top := Top + Height;
  FormExam.onCloseExam := OnCloseExam; {свойство типа TNotifyEvent, вызывающееся в FormExam.CloseForm(и там же после этого вызова Action := caFree) и сообщающее вызывающей форме, что эту форму можно разрушать (в теле процедуры OnCloseExam только один оператор: FormExam := nil ) : }
  FormExam.DefineFilesListForExam(FocusedDir);{инициация некоторых полей формы }
  if FormExam <> nil then
    begin
      if FormExam.WindowState = wsMinimized then
        FormExam.WindowState := wsNormal;
 
   FormExam.Show;
    end;
 
end;
//================

Ну вот, как-то так примерно Жду строгого разбора полётов.

Последний раз редактировалось vikk, 09.02.2011 в 16:28.
Ответить с цитированием
  #12  
Старый 09.02.2011, 19:59
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

try-finally ее не поймает.

Последний раз редактировалось Asinkrit, 02.04.2011 в 20:22.
Ответить с цитированием
  #13  
Старый 10.02.2011, 10:28
vikk vikk вне форума
Начинающий
 
Регистрация: 01.10.2010
Сообщения: 132
Репутация: 10
По умолчанию

Спасибо за разбор моих каракулей. С MDI-формами не работаю - не могу найти достаточное количество информации, чтоб хоть попробовать, как оно это делается. Скажем, можно ли только ЧАСТЬ форм проекта сделать дочерними к какой-то ещё форме проекта или уж если такая организация, то всего проекта в целом? И особенности организации, кроме как установка FormStyle главной - в MDIForm, а других - в MDIChild что-то не встретила.
Про то, что форму не создавать всякий раз новую, а использовать одну и ту же - это я подумаю, может быть перестрою мышление . До сих пор я всегда освобождла форму в её FormClose через Action := caFree, а обнуляла - в вызывающей, по свойству типа OnClose:TNotifyEvent, т.е. общая схема действий была такая:

Unit1:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type TForm1 = class(TForm)
...
 private
  Form2: TForm2;
...
 end;
procedure TForm1.BtnCreateForm2Click(SEnder: TObject);
begin
 ...
 Form2 := TForm2.Create(self);
 Form2.OnClose := OnCloseForm2;
...
 
end;
 
procedure TForm1.OnCloseForm2(SEnder: TObject);
begin
 Form2 := nil;
end;
Unit2:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
type
TForm2 = class(TForm)
...
 
private
fonClose:TNotifyEvent: TNotifyEvent read fonClose write fonClose;
public
property onClose:
...
end;
 
TForm2.FormClose(SEnder: TObject; Action: TCloseAction);
begin
...
 
if assigned (fonClose) then
 fonClose(self);
 
Action := caFree;
end;

А каким образом можно не выносить обработчик события с вызываемой формы, если в теле этого обработчика производятся манипуляции над ВЫЗЫВАЮЩЕЙ формой(в данном, например, случае надо в меню вызывающей формы создать новую кнопку с именем процесса, введенным пользователем в поле вызываемой формы) ? Другими словами, каковы должны быть действия в случае необходимости передать параметры из вызываемой формы - в вызывающую (гм, я здесь уже такую темку открывала). Можно попросить у Вас общую схему - как действовать в таких случаях?

Про признак я не очень поняла. Плохость такого стиля в чём заключается - в том, что в качестве условия используется Caption или в том, что напрямую в коде прописывается кирилловая строка, которая может не совпасть по кодировке на каком-то другом компе ? Ведь если у я введу булевский признак IsNew, то ему же всё равно надо будет присваивать значение в соответствии с тем, нажата ли кнопка с названием 'Новый' или другая. А можно тогда через тэг кнопки эту проблему решить(чтоб не кирильничать в коде?) :
Код:
1
2
if  TdxBarButton(Sender).Tag = <значение тэга кнопки "Новый">  then
  ...

Или это тоже нехорошо?

Буду оооочень благодарна за любые наставления, указания, советы и пр.

Последний раз редактировалось vikk, 11.02.2011 в 10:05.
Ответить с цитированием
  #14  
Старый 10.02.2011, 14:22
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

Я не зря про MDI

Последний раз редактировалось Asinkrit, 02.04.2011 в 20:23.
Ответить с цитированием
  #15  
Старый 11.02.2011, 09:54
vikk vikk вне форума
Начинающий
 
Регистрация: 01.10.2010
Сообщения: 132
Репутация: 10
По умолчанию

Вау! Вот это я понимаю - объяснение. Осталось только проглотить Спасибо огромное!!!
Увы, совсем непохоже на то, что писано мной . Ладно, пошла "перетрахивать" свой код. Надеюсь, больному станет легче.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 00:31.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025