Корректное завершение работы
По некоторому событию (нажатие кнопки, исключительная ситуация и т.п.) нужно завершить работу проги игнорируя все на свете кроме одной проверки. Проверка реализована в процедуре. Во время проверки возможно выполнение некоторых действий.
Я вижу это все так:
- наступило событие - выполняем экстренное завершение работы программы (Что-то типа Application.Terminate;);
- во время завершения выполняем проверку (Что-то типа Application.OnDestroy := @ProcedureClose;).
Но вот как это корректно организовать?
Корректное завершение работы
Модератор: Модераторы
OnDestroy событие которое происходит после обработки события OnClose, т.е. мы не сможем уже остановить разрушение приложения.
При уничтожении формы, события генерируются в следующем порядке:
... OnCloseQuery -> OnClose -> OnDeactivate -> OnHide -> OnDestroy
Т.е. обрабатывать событие OnDestroy бессмысленно приложение все равно уничтожится.
Т.е. если я правильно понял, что проверка как раз и дает нам ответ можно ли закрыть прогу или нет.. Если да, то вот привожу банальную форму с чекбоксом при клике на кнопку выходим из приложения (закрываем главную форму) ловим событие OnClose в котором проверяем через процедуру Cl можно ли закрыть форму (приложение) или нет. Вот код:
Если скажем просто в зависимости от логики нужно выполнить ту или иную операцию и именно в событии OnDestroy то просто готовим нужные процедуры и от логики программы присваиваем нужный вариант работы:
При уничтожении формы, события генерируются в следующем порядке:
... OnCloseQuery -> OnClose -> OnDeactivate -> OnHide -> OnDestroy
Т.е. обрабатывать событие OnDestroy бессмысленно приложение все равно уничтожится.
Т.е. если я правильно понял, что проверка как раз и дает нам ответ можно ли закрыть прогу или нет.. Если да, то вот привожу банальную форму с чекбоксом при клике на кнопку выходим из приложения (закрываем главную форму) ловим событие OnClose в котором проверяем через процедуру Cl можно ли закрыть форму (приложение) или нет. Вот код:
Код: Выделить всё
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
CheckBox1: TCheckBox;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
private
{ private declarations }
public
Function Cl:Boolean;
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
Close; //закрываем глав форму тобишь убиваем программу
end;
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
if Cl then
CloseAction:=caNone; //ну нельзя закрывать и баста
end;
function TForm1.Cl:Boolean;
begin
if CheckBox1.Checked then
begin
//делаем то что нам нужно....
Caption:='On';
Result:=True;
end
else
begin
Caption:='Off';
Result:=False;
end;
end;
end.
Если скажем просто в зависимости от логики нужно выполнить ту или иную операцию и именно в событии OnDestroy то просто готовим нужные процедуры и от логики программы присваиваем нужный вариант работы:
Код: Выделить всё
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
procedure FreeFull(Sender: TObject);
procedure FreeNoFull(Sender: TObject);
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
Application.OnDestroy:=@FreeFull;//короче будем бибикать при закрытии форму :)
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Application.OnDestroy:=@FreeNoFull;
end;
procedure TForm1.FreeFull(Sender: TObject);
begin
Beep;
end;
procedure TForm1.FreeNoFull(Sender: TObject);
begin
//А тут ничего делать не будем :)
end;
end.
Maxizar писал(а):проверка как раз и дает нам ответ можно ли закрыть прогу или нет
Прога должна закрыться в любом случае, независимо ни от чего! Но во время закрытия(деструкции или еще какого этапа) нужно произвести проверку и, возможно, выполнить некоторые действия. НО! Прога все-равно должна закрыться после проверки, независимо что там произошло при проверке. НО! Проверка обязательно должна завершить все свои действия.
Я попробывал вставить проверку в Application.OnDestroy;, но у меня вызвалась ошибка про какой-то Click (Видать тот, во время которого был вызван Application.Terminate).
Form.OnClose не катит, так как форма может быть уже закрыта и прога весеть в систрее.
Хм..
1. Если вы говорите что форма может быть закрыта значит она не главная, т. к. при закрытии главной формы идет завершение программы. Или все таки не закрыта а СКРЫТА методом Hide.
2. Если же вы очень хитро намутили с формами типа форма из Dll и т.п. То ошибка как раз и может вылетать из-за того, что формы то уже нет.. а вы обращаетесь к ее компонентам...
3. Кстати на счет железного закрытия я не уверен, что Application.Terminate не будет ждать зовершение запущенных потоков. (тут я не уверен нуна почитать).
4. Очень сложно что либо сказать без кода, хотябы того, в котором идет присвоение (Что-то типа Application.OnDestroy := @ProcedureClose;). и самой процедуры ProcedureClose.
1. Если вы говорите что форма может быть закрыта значит она не главная, т. к. при закрытии главной формы идет завершение программы. Или все таки не закрыта а СКРЫТА методом Hide.
2. Если же вы очень хитро намутили с формами типа форма из Dll и т.п. То ошибка как раз и может вылетать из-за того, что формы то уже нет.. а вы обращаетесь к ее компонентам...
3. Кстати на счет железного закрытия я не уверен, что Application.Terminate не будет ждать зовершение запущенных потоков. (тут я не уверен нуна почитать).
4. Очень сложно что либо сказать без кода, хотябы того, в котором идет присвоение (Что-то типа Application.OnDestroy := @ProcedureClose;). и самой процедуры ProcedureClose.
Почитайте про события.
Подсказка:
Пошлите главному окну своего приложения WM_Close в обработчике кнопки.
Подсказка:
Пошлите главному окну своего приложения WM_Close в обработчике кнопки.
