Корректное завершение работы

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

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

Корректное завершение работы

Сообщение VirtUX » 20.07.2010 15:58:18

Корректное завершение работы
По некоторому событию (нажатие кнопки, исключительная ситуация и т.п.) нужно завершить работу проги игнорируя все на свете кроме одной проверки. Проверка реализована в процедуре. Во время проверки возможно выполнение некоторых действий.
Я вижу это все так:
- наступило событие - выполняем экстренное завершение работы программы (Что-то типа Application.Terminate;);
- во время завершения выполняем проверку (Что-то типа Application.OnDestroy := @ProcedureClose;).
Но вот как это корректно организовать?
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Корректное завершение работы

Сообщение Maxizar » 20.07.2010 18:36:20

OnDestroy событие которое происходит после обработки события OnClose, т.е. мы не сможем уже остановить разрушение приложения.
При уничтожении формы, события генерируются в следующем порядке:
... 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
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: Корректное завершение работы

Сообщение VirtUX » 21.07.2010 09:23:26

Maxizar писал(а):проверка как раз и дает нам ответ можно ли закрыть прогу или нет

Прога должна закрыться в любом случае, независимо ни от чего! Но во время закрытия(деструкции или еще какого этапа) нужно произвести проверку и, возможно, выполнить некоторые действия. НО! Прога все-равно должна закрыться после проверки, независимо что там произошло при проверке. НО! Проверка обязательно должна завершить все свои действия.
Я попробывал вставить проверку в Application.OnDestroy;, но у меня вызвалась ошибка про какой-то Click (Видать тот, во время которого был вызван Application.Terminate).
Form.OnClose не катит, так как форма может быть уже закрыта и прога весеть в систрее.
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Корректное завершение работы

Сообщение Maxizar » 21.07.2010 10:16:31

Хм..
1. Если вы говорите что форма может быть закрыта значит она не главная, т. к. при закрытии главной формы идет завершение программы. Или все таки не закрыта а СКРЫТА методом Hide.
2. Если же вы очень хитро намутили с формами типа форма из Dll и т.п. То ошибка как раз и может вылетать из-за того, что формы то уже нет.. а вы обращаетесь к ее компонентам...
3. Кстати на счет железного закрытия я не уверен, что Application.Terminate не будет ждать зовершение запущенных потоков. (тут я не уверен нуна почитать).
4. Очень сложно что либо сказать без кода, хотябы того, в котором идет присвоение (Что-то типа Application.OnDestroy := @ProcedureClose;). и самой процедуры ProcedureClose.
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: Корректное завершение работы

Сообщение Timid » 21.07.2010 17:03:20

Почитайте про события.

Подсказка:
Пошлите главному окну своего приложения WM_Close в обработчике кнопки.
Timid
постоялец
 
Сообщения: 290
Зарегистрирован: 21.11.2007 21:33:15


Вернуться в Lazarus

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

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

Рейтинг@Mail.ru