Jak wyłapać moment zamykania aplikacji?

0

Cześć, pytanie wydaje się prostackie, ale jakoś nie znalazłem odpowiedzi ani w necie, ani we własnych próbach. W jaki sposób da się wykryć, czy aplikacja jest zamykana? Chodzi o to, że mam aplikację MDI. I otwartą formę MDIChild. Teraz, podczas zamykania tej MDIChild ma się wykonać jakiś kod (w OnClose). Ale, jeśli zamykanie okna jest spowodowane zamknięciem aplikacji (a nie tylko tego okna), to ma się wykonać inny kod. Jak coś takiego osiągnąć?

0

wg mnie ten inny kod wpisujesz w onclose mdiform

0

Tyle to ja też wiem. Tylko nie wiem, jak rozpoznać, czy zamknięcie formy jest spowodowane zamknięciem aplikacji. Jeśli próbuję wyłapywać komunikaty albo OnClose formy głównej, to nic mi to nie daje, bo OnClose tej mojej MDIForm jest wywoływany zawsze jako pierwszy.

1

Nie rozumiem w czym problem skoro zamykana jest aplikacje to zamykana jest główna forma a więc wywoływane jest jej OnClose to można po prostu:

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
var
  i: Integer;
begin
  for i:= MainForm.MDIChildCount -1 downto 0 do
  begin
    MainForm.MDIChildren[i].Tag:= 1; //ustawiamy tag na 1 bedzie to sluzylo do sprawdzenia czy wzamykana jest aplikacja
    MainForm.MDIChildren[i].Close; //ponieważ gdy zamykana jest aplikacja "normalnie" nie jest wywolywane OnClose dla form MDI trzeba je "ręcznie" zamknąć
  end;
end;

i w MDI już proste:

procedure TMDIChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if Tag = 1 then
  begin
    //zamykana jest cala aplikacja
  end
  else
  begin
    //zamykasz tylko okno MDI
  end;
  Action := caFree;
end;

EDIT:
Jak OnClose formy MDIFormy wywoływany jest pierwszy u mnie "normalnie" w ogóle nie jest (przy zamykaniu aplikacji) jaka wersja Delphi?

0

Nie ma tu niczego nadzwyczajnego:

var
  f: TDocumentForm;
begin
  f:=TDocumentForm.Create(Application.MainForm);
  f.Show();
end;

Podczas zamykania aplikacji, najpierw wywołuje się OnClose z MDIForm, a potem z MainForm.

0

@Juhas po kiego ci ta zmienna? Wystarczy:

TDocumentForm.Create(Application.MainForm).Show();
5

No to nic nie rozumiem jak u mnie ten sam kod może działać inaczej? Tak jak pisałem normalnie gdy zamykam aplikację OnClose dla MDIChild w ogóle nie jest wywoływane. Jak ktoś ma chwilę sprawdźcie jak Wy macie bo ja już zgłupiałem :/
Oczywiście rozumiem że pamiętałeś o nadaniu stylu dla form odpowiednio fsMDIForm i fsMDIChild?

EDIT:
@Juhas patrząc od strony WinApi aby okno dostało WM_CLOSE (a więc zostanie wywołane OnClose w VCL) trzeba nacisnąć X lub musi zostać wywołane polecenie Zamknij z menu okna więc logiczne jest że MDIChild (czy w ogóle inne okno) NIE dostanie WM_CLOSE jeżeli tego nie zrobisz (nie naciśniesz przycisku X lub "ręcznie" nie wyślesz do niego WM_CLOSE) więc raczej coś chrzanisz z takim zachowaniem o którym piszesz.

EDIT2:
Jak chcesz wiedzieć już OnCloseQuery MDIChild czy zamykana jest aplikacja to podobnie można posłużyć się właściwością Tag form MDIChild z tym że trzeba w MDIForm przechwycić komunikat WM_SYSCOMMAND z komendą SC_CLOSE czyli:

  TForm1 = class(TForm)
  private
    { Private declarations }
    procedure WMSysCommand(var Message: TWMSysCommand); message WM_SYSCOMMAND;
//...
procedure TForm1.WMSysCommand(var Message: TWMSysCommand);
var
  i: Integer;
begin
  if  Message.CmdType = SC_CLOSE then
  begin
    for i:= Application.MainForm.MDIChildCount -1 downto 0 do
      Application.MainForm.MDIChildren[i].Tag:= 1;
  end;
  inherited;
end;

Teraz w OnCloseQuery MDIChild możesz sprawdzając wartość Tag wykryć czy zamykana jest aplikacja.

0

To jest właśnie to, czego potrzebowałem. Dzięki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1