Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Event: Form über Schließen-Kreuz beenden (https://www.delphipraxis.net/100593-event-form-ueber-schliessen-kreuz-beenden.html)

Reinhardtinho 1. Okt 2007 08:18


Event: Form über Schließen-Kreuz beenden
 
Guten Morgen,

Gibt es ein Event, dass nur ausgelöst wird, wenn ich das Fenster über das "Schließen-Kreuz" beenden will?

Oder kann ich im OnCloseQuery abfragen, ob das Kreuz gedrückt wurde?

Vielen Dank und freundliche Grüße
Lorenz

Jens Schumann 1. Okt 2007 09:04

Re: Event: Form über Schließen-Kreuz beenden
 
Hallo,
der Source zeigt Dir wie das Drücken eines der drei Formbuttons abfangen kannst.
Evt hilft Dir das weiter.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
    FOldWndProc : TWndMethod;
    procedure MyWndProc(var Msg: TMessage);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Close;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose:=True;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FOldWndProc := Self.WindowProc; // alte Fensterproceure merken
  Self.WindowProc:= MyWndProc; // Fensterproceure auf eigene Fensterprocedure umbiegen

end;

procedure TForm1.MyWndProc(var Msg: TMessage);
begin
  If Msg.Msg = WM_NCLBUTTONDOWN then
    begin
    FOldWndProc(Msg);
    end
      else FOldWndProc(Msg); // alte Fensterproceure aufrufen
end;

end.

negaH 1. Okt 2007 09:15

Re: Event: Form über Schließen-Kreuz beenden
 
wm_SysCommand Message müsste das können, schau mal in der Hilfe bei der Kodierung des wParam's nach.

Gruß Hagen

Reinhardtinho 1. Okt 2007 10:19

Re: Event: Form über Schließen-Kreuz beenden
 
Hi,

ich danke euch beiden erst mal für die Tipps.

Allerdings habe ich noch weitere Fragen:

@Jens Schumann:

Was wird hier gemacht, im If und im Else-Fall wird doch der gleiche Code aufgerufen. Was passiert da genau?

Zitat:

Zitat von Jens Schumann
Delphi-Quellcode:
procedure TForm1.MyWndProc(var Msg: TMessage);
begin
  If Msg.Msg = WM_NCLBUTTONDOWN then
    begin
    FOldWndProc(Msg);
    end
      else FOldWndProc(Msg); // alte Fensterproceure aufrufen
end;

@negaH

Zitat:

Zitat von negaH
wm_SysCommand Message müsste das können, schau mal in der Hilfe bei der Kodierung des wParam's nach.

Ich habe wParam in der Hilfe nicht gefunden :stupid:, kann ich die Message auf wm_SysCommand überprüfen oder wie meintest du das? Ist wm_SysCommand das Schließen-Kreuz?


Vielen Dank und mit freundlichen Grüßen
Lorenz

Luckie 1. Okt 2007 10:40

Re: Event: Form über Schließen-Kreuz beenden
 
Warum das Umbiegen der fensterprozedur? Die Ereignisse OnClose und OnCloseQuery werden imnmer ausgelöst.

Progman 1. Okt 2007 10:44

Re: Event: Form über Schließen-Kreuz beenden
 
Und für Minimieren/Maximieren gibt es die ApplicationEvents OnMinimize und OnMaximize (soviel ich weiß, kanns nur grad nicht probieren)

Reinhardtinho 1. Okt 2007 10:54

Re: Event: Form über Schließen-Kreuz beenden
 
Das Ereignis wird doch auch ausgelöst, wenn ich Close aufrufe oder man Alt-F4 drückt. Ich muss aber den Fall abfangen, wenn man das Form über das Kreuz schließt.

OregonGhost 1. Okt 2007 11:01

Re: Event: Form über Schließen-Kreuz beenden
 
Darf ich interessehalber fragen, warum du das Schließen per X anders behandeln musst als das Schließen per Alt-F4? In vielen Fällen liegt in so einer Situation ein Design-Fehler vor.

Edit: Beispiel aus der Interface Hall of Shame

s-off 1. Okt 2007 11:54

Re: Event: Form über Schließen-Kreuz beenden
 
Du kannst auch in der WM_NCHITTEST auf HTCLOSE prüfen.
Damit hättest Du schonmal das Event, sobald sich der Mauszeiger über dem Close-Button befindet.

Wenn Du dann noch den Status der linken Maustaste mit GetKeyState prüfst, sollte das eigentlich funktionieren.

Reinhardtinho 1. Okt 2007 12:12

Re: Event: Form über Schließen-Kreuz beenden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,

Zitat:

Zitat von OregonGhost
Darf ich interessehalber fragen, warum du das Schließen per X anders behandeln musst als das Schließen per Alt-F4? In vielen Fällen liegt in so einer Situation ein Design-Fehler vor.

Also in meinem Fall sollte Alt-F4 und das Schließen per X das selbe sein, ich wollte oben nur allgemein andeuten, dass es ja verschiedene Wege gibt, ein Form zu schließen. :wink:



Ich hänge mal ein Screenshot von meiner Form an, vielleicht wird es dann etwas deutlicher.

Der Benutzer kann den Vorgang abbrechen, wenn er auf Abbrechen klickt oder auf das Kreuz, will ernich abbrechen, so soll die Form normal geschlossen werden, wenn eine bestimmte Prozedur bearbeitet wurde (dort rufe ich einfach nur Close auf).

Beim Abbruch kommt noch eine Abfrage, ob der Benutzer wirklich abbrechen will, das heißt, wenn er Nein sagt, geht der Vorgang normal weiter.


MFG
Lorenz

SirThornberry 1. Okt 2007 12:53

Re: Event: Form über Schließen-Kreuz beenden
 
was für wege gibt es denn noch die anders behandelt werden müssen als Alt+F4 und das Schließenkreuz? Du kannst ja auch anders herum an die sache ran gehen. Nicht heraus finden ob Alt+F4 gedrückt wurde sondern überprüfen ob es auf andere Art und Weise geschlossen wurde (da wäre eben die Frage welche anderen Arten du meinst welche dir nicht zusagen)

Reinhardtinho 1. Okt 2007 13:06

Re: Event: Form über Schließen-Kreuz beenden
 
Es gibt im Prinzip 2 Arten, wie dieses Form geschlossen wird.

1.) Die Bearbeitungsprozedur läuft normal ab und es wird Close im Quelltext aufgerufen.
2.) Der Anwender bricht die Prozedur ab, in dem er entweder auf "Abbrechen" klickt, Alt-F4 drückt oder eben das [x], dann wird die Prozedur nicht komplett abgearbeitet.

Punkt 1 ist schon gelöst und das "Abbrechen"-Klicken in Punkt 2 auch, nur das mit Alt-F4 und [x] machen mir noch Probleme.

SirThornberry 1. Okt 2007 13:14

Re: Event: Form über Schließen-Kreuz beenden
 
ich verstehe jetzt dein Problem nicht. Wenn du per Quelltext "Close" aufrufst kannst du eine Variable setzen und wenn diese gesetzt ist weißt du das so geschlossen wurde. Wenn auf "abbrechen" geklickt wurde kannst du ebenfalls eine Variable setzen. Alle anderen Varianten wäre dann eben ein schließen durch den Anwender per Alt+F4, Klick auf Kreuz, Per Message von anderem Programm etc. Welche andere Variante es ist braucht dich ja nicht interessieren oder sehe ich das falsch?

Progman 1. Okt 2007 13:42

Re: Event: Form über Schließen-Kreuz beenden
 
schreib doch einfach ins FormCloseQuery:
Delphi-Quellcode:
  if MessageDlg('Vorgang Abbrechen?',....) = mrYes then CanClose := True else CanClose := False;

Reinhardtinho 1. Okt 2007 13:45

Re: Event: Form über Schließen-Kreuz beenden
 
Ich befürchte, ich habe ein paar Infos vergessen.

Meine Bearbeitungsprozedur wird immer ausgeführt, egal ob sie komplett abgearbeitet wird oder der Benutzer "Abbrechen" drückt.
Da die Bearbeitungsprozedur nicht zu der Form gehört, wo die Abbruchroutine sein soll (Sprich Button & Alt-F4 & [x]), steuere ich das ganze über eigene Events.

Nachdem die Bearbeitungsprozedur verlassen wird, wird Close aufgerufen.

Beim Klick auf "Abbrechen" kommt erst eine Abfrage, ob der Benutzer dies auch wirklich will, ansonsten wird die Prozedur sachgemäß abgearbeitet. Will der Benutzer nun wirklich abbrechen, wird ein weiteres Event ausgelöst, was eine Boolschen Wert setzt. Dieser Wert wird in der Bearbeitungsprozedur regelmäßig abgefragt, die dann entscheidet, ob sie weitermacht oder abbricht.


Das heißt, wenn der Benutzer abbrechen möchte, wird noch nicht wirklich abgebrochen, sondern der Bearbeitungsprozedur mitgeteilt, dass sie ab jetzt eine andere Arbeit leisten muss.

Wenn ich also vor dem Close eine Variable setzen würde, die abhänig von der Bearbeitungsroutine Wahr oder Falsch ist und ich dann z.B. im OnCloseQuery eine Abfrage mache, ob diese Variable gesetzt ist, wird es zu spät sein, wenn der Anwender sagen will, "doch kein Abbruch --> Weitermachen".


Klingt kompliziert, ist auch so. :mrgreen:


MFG
Lorenz

OregonGhost 1. Okt 2007 14:57

Re: Event: Form über Schließen-Kreuz beenden
 
Ach so, jetzt verstehe ich langsam. Also geht es dir sonstwo vorbei, ob der Benutzer nun Alt+F4 oder X gedrückt hat, du willst nur wissen, ob das der Fall war oder dein Abbrechen-Button, der im Endeffekt die Prozedur abbricht, die aber wiederum das Schließen vornimmt. Kann man das ungefähr so zusammenfassen:
Delphi-Quellcode:
begin
  while not CancelClicked do begin
    DoSomething;
  end;
  Close;
end;

procedure TMyForm.CancelButtonClick(...);
begin
  if MessageDlg(...) = mbYes then begin
    CancelClicked := true;
  end;
end;
?

Wenn ja, entzieht sich meiner Kenntnis, warum OnCloseQuery nicht so aussieht:
Delphi-Quellcode:
procedure TMyForm.FormCloseQuery(...);
begin
  CanClose := true;
  if not CancelClicked and not Done then begin
    if MessageDlg(...) = mbYes then begin
      CancelClicked = true;
      CanClose := false;
    end
  end
end;
Done müsste dann natürlich noch am Ende der Bearbeitung (aber vor dem Close) auf true gesetzt werden. Oder hab ich da einen Denkfehler? :stupid:

Reinhardtinho 1. Okt 2007 15:14

Re: Event: Form über Schließen-Kreuz beenden
 
Hi,

Zitat:

Zitat von OregonGhost
Ach so, jetzt verstehe ich langsam. Also geht es dir sonstwo vorbei, ob der Benutzer nun Alt+F4 oder X gedrückt hat, du willst nur wissen, ob das der Fall war oder dein Abbrechen-Button, der im Endeffekt die Prozedur abbricht, die aber wiederum das Schließen vornimmt. Kann man das ungefähr so zusammenfassen:
Delphi-Quellcode:
begin
  while not CancelClicked do begin
    DoSomething;
  end;
  Close;
end;

procedure TMyForm.CancelButtonClick(...);
begin
  if MessageDlg(...) = mbYes then begin
    CancelClicked := true;
  end;
end;

Das ist schon mal absolut richtig. So sehen meine Schleife und meine Abbruchbedingung auch in etwa aus (bei mir über Event-Steuerung).

Aber ich kann nicht darauf warten, dass meine Prozedur (wie die while-schleife) fertig ist und danach im FormCloseQuery auf eine Variable zugreift, die erst nach Beenden dieser Prozedur gesetzt wird.

Wenn ich dort bei der CloseQuery abfragen wollte, ob abgebrochen werden soll und der Benutzer mit Nein antwortet, kann ich nicht in der Bearbeitungsprozedur weitermachen, die ist ja schon beendet.

Im Prinzip müsste das, was ob in CancelButtonClick steht aufgerufen werden, wenn ich das [x] (oder Alt+F4) drücke.

MFG
Lorenz

Reinhardtinho 1. Okt 2007 15:54

Re: Event: Form über Schließen-Kreuz beenden
 
So, ich mach mal einen neuen Post auf, weil sich das Problem anscheinend aufgelöst hat. :thumb:

Wenn ich das [x] drücke oder Alt+F4, dann wird gar kein Ereignis ausgelöst, weil das Programm noch in der anderen Prozedur befindet, allerdings wird dann das CancelClick ausgeführt, auch wenn ich noch in der Prozedur bin.

In diesem Fall ist das natürlich optimal für mich, da somit alles fertig ist und ich keine weiteren Fälle abfangen muss.


Ich danke nochmals allen, die sich mit mir zusammen dem Problem gestellt haben und wünsche einen schönen Feierabend
Lorenz


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:42 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz