Hallo,
folgendes wird wohl eher eine Verständnisfrage für mich persönlich. Eventuell ist sie sogar so trivial, dass ich hier gleich gesteinigt werde.
Ich bin ein Laie in Sachen Delphi-Programmierung und soll gerade mit Delphi XE2 ein bestehendes Programm "erweitern". Aus Gründen der Übersicht habe ich dazu eine neue Form erstellt (die Hauptform ist mit Labels, Edits und Images für meinen Geschmack schon ziemlich überladen). Das Programm soll auf beiden Formularen sicher beendet werden können. Im Hauptformular (das bereits existierte) wird das wohl so realisiert:
Delphi-Quellcode:
Function TFrm_Form1.Beenden():Boolean;
begin
if Application.MessageBox('Wirklich beenden?','Berechnung',52) = 6 then
begin
...
Application.Terminate;
result:=True;
end else result:=false;
end; //TFrm_Form1.Beenden
...
procedure TFrm_Form1.Beenden1Click(Sender: TObject);
begin
Beenden;
end;
...
procedure TFrm_Form1.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
begin
CanClose:=Beenden;
end;
Mit der Prozedur "Beenden1Click" wird das Beenden mittels Button abgearbeitet. Ich gehe davon aus, dass Beenden mittels Rechtsklick in der Symbolleiste, Alt+F4, [X]-Button etc. über die FormCloseQuery-Prozedur abgearbeitet wird.
Nun gleich zu einer ersten Zwischenfrage zum persönlichen Verständnis:
(1) Wofür stehen die Konstanten bei Application.Messagebox? (52 und 6)
Hab auf die schnelle nur diese
Übersicht gefunden. Die ist wohl aber etwas veraltet, da ich die Konstanten unter MessageBox nicht wiedergefunden habe.
Ich tippe jetzt einfach mal auf 52 = /!\ und 6 = MB_OK
Weiter im Text: Den Wechsel zwischen den Formularen realisiere ich wie folgt:
Delphi-Quellcode:
procedure TFrm_Form1.B_WechselZuForm2Click(Sender: TObject);
begin
Frm_Form2.Top := Frm_Form1.Top;
Frm_Form2.Left := Frm_Form1.Left;
Frm_Form2.Height := Frm_Form1.Height;
Frm_Form2.Width := Frm_Form1.Width;
Frm_Form2.Show;
Frm_Form1.Hide;
end;
Der Wechsel von Form2 zu Form1 ist analog aufgebaut.
Jetzt zum eigentlichen Problem: Das schließen dieser zweiten Form. Anfangs habe ich gedacht es würde reichen, wenn ich auf die Beenden-Prozedur von Form1 verweise, also quasi:
Delphi-Quellcode:
//////////Beenden via "Beenden"-Button
procedure TFrm_Form2.B_Form2BeendenClick(Sender: TObject);
begin
Frm_Form1.Beenden;
end;
...
procedure TFrm_Form2.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
begin
CanClose:=Frm_Form1.Beenden;
end;
Das würde für das Beenden über den entsprechenden Button auch funktionieren. Allerdings wird damit nicht das Beenden via Rechtsklick, Alt+F4, [X]-Button usw. abgefangen. Vermutlich wird das FormCloseQuery garnicht angelaufen (habe ich mittels Breakpoints untersucht). Hab gelesen, dass das wohl nur bei modalem Aufruf ginge oder so. Da ich die Formulare aber nicht schließen möchte wenn ich das jeweils andere Formular anzeigen will (in die Edits eingetragene/geänderte Werte sollen nicht verloren gehen), was ich wohl müsste wenn ich mit ShowModal arbeite, hab ich den Formularwechsel via Show und Hide realisiert (siehe oben).
Auch eine eigene Funktion Beenden für Form2 (im Prinzip exakt die gleiche wie für Form1) hat das Problem nicht behoben.
Im Internet bin ich dann auf
diese Möglichkeit gestoßen so ziemlich alle Varianten des Programm beendens (außer via Button) abzufangen. Der Rohquelltext sieht so aus:
Delphi-Quellcode:
procedure WMSysCommand(var MSG: TWMSysCommand); message WM_SYSCOMMAND;
...
procedure TForm1.WMSYSCommand(var MSG: TWMSysCommand);
begin
if MSG.CmdType = SC_CLOSE then
begin
//Closing from border icon
end;
inherited;
end;
Nun habe ich mir Gedanken gemacht, wie ich da noch die Abfrage (Wirklich Beenden?) dazwischenbekomme und auf ein Nein als Antwort reagiere. Dabei bin ich auf folgende Lösungen gestoßen:
Delphi-Quellcode:
Function TFrm_Form2.Beenden():Boolean;
begin
if Application.MessageBox('Wirklich beenden?','Berechnung',52) = 6 then
begin
...
Application.Terminate;
result:=True;
end else result:=false;
end;
...
procedure TFrm_Form2.WMSysCommand(var MSG: TWMSysCommand);
begin
if MSG.CmdType = SC_CLOSE then
begin
if Frm_Form2.Beenden = False then
begin
MSG.Result := 0;
Exit;
// MSG.CmdType := SC_DEFAULT;
end;
end;
inherited;
end;
Das letzte Stück Quelltext durchschaue ich noch nicht ganz, darum jetzt zur eigentlichen Thematik:
Als mögliche Werte für Msg:CmdType bin ich unter anderem auf SC_DEFAULT gestoßen (leider keine Ahnung mehr wo). Das war auch mein erster Lösungsansatz (siehe auskommentierte Zeile), der auch (scheinbar?) funktioniert hat. Jedoch bin ich mir nicht sicher, ob man MSG.CmdType einfach so einen neuen Wert zuweisen kann/sollte und ob SC_DEFAULT nicht vielleicht auch irgendwas anderes "auslöscht".
Die zweite Möglichkeit
(
MSG.Result := 0;
Exit;
)
habe ich zu einer anderen Thematik gefunden (irgendwas von wegen Maximieren, Minimieren verhindern oder so).
Nach ein wenig rumprobieren habe ich gemerkt, dass Exit allein auch funktioniert.
Nun (endlich
) zu meinen Hauptfragen:
(2) Möglichkeit 1: Richte ich mit der Zuweisung von SC_DEFAULT ungewollt und unbewussten Schaden an? Oder anders gefragt: Würde das so funktionieren?
(3) Möglichkeit 2: Wenn Exit allein funktioniert, wozu dann MSG.Result := 0;? Und was bedeutet das?
Vielen Dank im Voraus!
PS: Wie eingangs erwähnt bin ich ein absoluter Laie auf dem Gebiet Delphi-Programmierung (eigentlich auch allgemein auf dem Gebiet der Programmierung). Die einzigen Kenntnisse die ich habe liegen schon ein paar Jährchen zurück und waren recht simpel gehalten (ein oder ein halbes Jahr Informatikunterricht). Deshalb hab ich für mich persönlich bei der Fragestellung einfach beim Urschleim angefangen. Zum einen in der Hoffnung auf grobe Fehler hingewiesen zu werden
und zum anderen um Fragen so gut es geht vorzubeugen.
Bei Fehlern bei der Fragestellung und Themeneröffnung bitte ich mich darauf hinzuweisen und sie mir nachzusehen