Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Abfragemenü (https://www.delphipraxis.net/159954-abfragemenue.html)

Dunkelbunt27 20. Apr 2011 10:24

Abfragemenü
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Delphi-PRAXIS,

ich möchte so eine Abfrage für mein Programm, wie bei Programmen wie Word, welche aufgerufen wird wenn man das Programm schließt.
Bei Word fragt diese z.B. ob man die Änderungen speichern möchte.

Muss man dazu eine eigene Form einbinden oder gibt es eine andere Möglichkeit von Delphi aus?

FG Dunkelbunt

s.h.a.r.k 20. Apr 2011 10:26

AW: Abfragemenü
 
Delphi-Quellcode:
var
  MR : TModalResult;
begin
  MR := MessageDlg('Möchten Sie die Änderungen im Dokument1 speichern?', mtInformation, [mbYes, mbNo, mbCancel], 0);
  case MR of
    mrYes : ;
    mrNo : ;
    mrCancel : ;
  end;
end;
Du kannst mit einem fünfsten Parameter einen Default-Button definiere, der dann den Fokus nach dem Anzeigen des Dialogs hat, z.B.:
Delphi-Quellcode:
MessageDlg('Möchten Sie die Änderungen im Dokument1 speichern?', mtInformation, [mbYes, mbNo, mbCancel], 0, mbYes);
Zudem würde ich das ganze mit der Format-Funktion kombinieren, sodass der Message-Text flexibler wird.

SirTwist 20. Apr 2011 10:29

AW: Abfragemenü
 
Dein MainForm hat ein Ereignis OnCanClose. Hier schreibst Du eine Abfrage rein in der Form
Delphi-Quellcode:
procedure TForm1.FormCanClose(Sender: TObject; var CanClose: Boolean);
var rc: Integer;
begin
  rc:= MessageDlg('Möchten Sie die Änderungen speichern?',
                   mtConfirmation, [mbYes, mbNo, mbCancel], 0);
  case rc of
    mrCancel: begin CanClose := False; exit; end;
    mrYes: SaveData;
  end;
end;
(Alles ungetestet aus dem Gedächtnis runtergetippt!)

Dunkelbunt27 20. Apr 2011 10:30

AW: Abfragemenü
 
Danke.

s.h.a.r.k 20. Apr 2011 10:30

AW: Abfragemenü
 
Evtl. sollte man noch dazu sagen, dass die Methode MessageDlg() nicht threadsafe ist und man diese in der Unit Dialogs findet.

Dunkelbunt27 20. Apr 2011 10:36

AW: Abfragemenü
 
FormCanClose ist ja nicht als Ereignis vordefiniert (bei mir zumindest nicht)
reicht es also aus die Procedure anzulegen
Delphi-Quellcode:
procedure TForm1.FormCanClose(Sender: TObject; var CanClose: Boolean);;
und in type zu definieren?

EDIT:
Es gibt ein OnCloseQuery, procedure TForm1.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
Das ist identisch.

Dunkelbunt27 20. Apr 2011 11:05

AW: Abfragemenü
 
Wie kann ich es machen, dass wenn ich erst auf JA klicke (also ich möchte speichern)
und dann im Speicherdialog abbreche, sich das Programm nicht schließt?

ich hab es jetzt so:
Delphi-Quellcode:
  case MR of
    mrYes  : begin
               CanClose := False;
               if not FileExists(Filename) then
               begin
                 SpeicherDialog := TSaveDialog.Create(self);
                 Speichern_mit_Dialog;
                  //if SpeicherDialog.Execute = False //Falsch, da so der Dialog erneut aufgerufen wird.
                  //   CanClose := False;
               end
               else
                begin
                  Speichern(Filename);
                  CanClose := True;
                  Exit;
                end;
              end;
    mrNo   : begin
              //leer
              end;
    mrCancel: begin
               CanClose := False;
               exit;
              end;
  end;
<Edit> Doppelpost -.- </Edit>

SirTwist 20. Apr 2011 11:09

AW: Abfragemenü
 
Sorry, natürlich heißt das Event CloseQuery....

am einfachsten definierst Du Deine Speichern()-Routine als Funktion, die einen Boolean zurückliefert, und zwar True genau dann, wenn alles gut gegangen ist.

Dann hättest Du nur noch mrYes: CanClose := Speichern();

Wobei natürlich die File-Auswahlbox in der Speichern()-Routine aufgerufen werden muss.

Dunkelbunt27 20. Apr 2011 11:13

AW: Abfragemenü
 
Okay,
Danke.

s.h.a.r.k 20. Apr 2011 11:17

AW: Abfragemenü
 
Delphi-Quellcode:
procedure TForm1.OnCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := True;
  case MR of
    mrYes : begin
      SD := TSaveDialog.Create();
      try
        // Set dialog properties
        // ...
 
        if (SD.Execute) then
        begin
          // Save document
        end
        else begin
          // Do NOT close application because user cancelled
          // SaveDialog.
          CanClose := False;
        end;
      finally
        SD.Free();
      end;
    end;
   
    // Nothing to do here
    mrNo : ;
 
    // Application should NOT be closed
    mrCancel : CanClose := False;
  end;
end;
Sinnvoller wäre es den Teil unter mrYes in eine eigene Methode auszulagern, allein schon wegen der Übersichtlichkeit, aber eben auch aufgrund der möglichen Wiederverwendbarkeit -- vorausgesetzt du schreibst diese Save()-Methode ausreichend allgemein.

Dunkelbunt27 20. Apr 2011 11:31

AW: Abfragemenü
 
Zitat:

Sinnvoller wäre es den Teil unter mrYes in eine eigene Methode auszulagern
Ja, das hab ich auch so gemacht, sonst ist es unübersichtlich.

Frage am Rande, wie kann man in einer eigenen procedure oder function einen SaveDialog erstellen?
Er meckert immer über den Parameter self,
Delphi-Quellcode:
SpeicherDialog := TSaveDialog.Create(self);
.

Luckie 20. Apr 2011 11:41

AW: Abfragemenü
 
Warum willst du ihn selber erstellen? Zieh die Komponente auf das Formular und rufe ihn auf.

Dunkelbunt27 20. Apr 2011 11:46

AW: Abfragemenü
 
Hm, ja stimmt... das sollte ich tun.
Aber wie würde es trotzdem gehen? Geht es überhaupt?

Luckie 20. Apr 2011 11:50

AW: Abfragemenü
 
Zitat:

Zitat von Dunkelbunt27 (Beitrag 1096179)
Er meckert immer über den Parameter self,

Tja, clever wäre es, wenn du uns jetzt noch die Fehlermeldung mitteilen würdest. :roll:

Dunkelbunt27 20. Apr 2011 11:53

AW: Abfragemenü
 
Also bei Speicherdialog := TSaveDialog.Create(self) erkennt er das self als undeklarierten Bezeichner und bei
Speicherdialog := TSaveDialog.Create; fehlen ihm Parameter.

(Es handelt sich hierbei um eine eigene Procedure und kein Ereignis)

s.h.a.r.k 20. Apr 2011 12:06

AW: Abfragemenü
 
Du kannst auch anstatt Self einfach nil einsetzen, solltest dich dann aber um die Freigabe selbst kümmern! Denn dann wird der SaveDialog nicht mehr automatisch freigegeben, wenn die Form beendet wird. Mein try-finally-Block von oben ist eben genau dafür da ;)

Und bzgl. dem Fehler bei deinem Self: du wirst sehr wahrscheinlich wohl keine Methode der TForm1 (oder wie deine Klasse sonst heißt) aufrufen, sondern eine, die mit keiner Klasse was zu tun hat. Daher ist auch das Self nicht definiert -- was sollte denn Self in der Methode darstellen, nachdem es nicht innerhalb eines Klasse-Kontexts implementiert ist?
Delphi-Quellcode:
type
TForm1 = class(TForm)
public
  procedure Foo();
  procedure Bar();
end;

procedure DoSomething();
begin
  // Hier kann es kein Self geben, da es keine Klassemethode
  // ist. Du müsstest dann einen Parameter Self definieren,
  // der eben dann diese Rolle übernimmt.
end;

procedure TForm1.Foo();
begin
  DoSomething();
end;

procedure TForm1.Bar();
begin
  // Hier gibt es Self, da es eine Methode einer Klasse ist
  Self.Foo();
end;
PS: Wenn du eine Klassenmethode Foo() hast, denn erzeugt der Compiler diese so, dass es einen versteckten Parameter Self gibt, d.h. Foo(Self: TObject) (bzw. evtl. TForm anstatt TObject), wovon du aber gar nichts mitbekommst. Daher kannst du dort auch ohne Probleme Self verwenden.

Dunkelbunt27 20. Apr 2011 12:21

AW: Abfragemenü
 
Aha, gut zu wissen.
Ich hab jetzt aber einfach die Dialoge aufs Formular gezogen, wie Luckie gesagt hat, und damit haufenweise Quelltext gespart ;)

Danke für deine Mühe.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:34 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