Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Minimieren statt Beenden (https://www.delphipraxis.net/5282-minimieren-statt-beenden.html)

Mat 31. Mai 2003 05:37


Minimieren statt Beenden
 
Hallo, ich bin's wieder :)


ich moechte in meinem Programm dem User die Moeglichkeit geben, wenn er auf den Beenden-Button des Fensters ([X]-Button rechts oben) klickt, das Fenster nur minimiert wird.


Ich hab es jetzt soweit, das das Programm nur beendet werden kann, wenn ein bestimmter Button im Fenster gedrueckt wird.

Nebeneffekt ist, das z.B. 'Alt-F4', Beenden im Systemmenu ebenfalls nur zum Minimieren fuehren.. das find ich persoenlich nicht so schlimm, aber was passiert, wenn Windows das Programm schliessen will?

Ich hab's bei mir (WinXP) probiert, bei nem Neustart gab's keine Probleme und ueber den Task-Manager abschiessen kann man das Programm auch..


Kann die Funktion so bleiben, oder gibt's da auch was eleganteres?

Wenn alles super ist, dann hab ich eben nur ein Beispiel geposted.. :D


Exit-Button (der richtige Button im Fenster) OnClick-Event:
Delphi-Quellcode:
procedure TForm_Main.Button_ExitClick(Sender: TObject);
begin

  ExitButtonWasClicked := True; // globale Variable (ist bei Programmstart auf False)
  Close;

end;
der OnCloseQuery_Event vom Hauptfenster
Delphi-Quellcode:
procedure TForm_Main.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
      msg: Integer;
     text: String;
  askexit: Boolean;
begin

  askexit := True;
  if (reg_minonx = True) and (ExitButtonWasClicked = False) then askexit := False;

  if askexit then
    begin
      text := 'Wollen Sie wirklich beenden?';
      msg := Application.MessageBox(Pointer(text), 'Beenden', MB_YESNO + MB_DEFBUTTON2 + MB_ICONQUESTION);

      // wenn YES gewählt, dann ist msg = 6
      if msg = 6 then
        CanClose := True
      else
        CanClose := False;
    end
  else
      CanClose := False;



  if (reg_minonx) and (not CanClose) and (not ExitButtonWasClicked) then
      Application.Minimize;

  ExitButtonWasClicked := False;

end;
(minonx ist True, wenn nur minimiert werden soll)


Mat

Luckie 31. Mai 2003 06:52

Ich halte es grundsätzlich für sehr unglücklich das standard Verhalten von Windows der art drastisch zu beeinflussen / zu verändern. Wenn ich auf "schließen" in der Titelleiste klicke, dann erwarte ich auch, dass das Fenster zu geht.
Schick es mit den "Minimieren"-Button in die TNA und beeden es ganz normal mit dem "Schließen"-Button. Damit machst du dir wesentlich mehr Freunde, als mit der Konstruktion, die du da jetzt gebastelt hast.
Damit spartst dir auch die Option, ob der Benutzer die Funktionsweise des "Schließen"-Buttons so drastisch verändern will.

MathiasSimmack 31. Mai 2003 07:03

Re: Minimieren statt Beenden
 
Als Ergänzung möchte ich sagen, dass ich dies (bei allem Respekt) für Schwachsinn halte:
Zitat:

Zitat von Mat
Delphi-Quellcode:
msg := Application.MessageBox(Pointer(text), 'Beenden', MB_YESNO + MB_DEFBUTTON2 + MB_ICONQUESTION);

// wenn YES gewählt, dann ist msg = 6
if msg = 6 then
  { ... }

Spricht irgendwas gegen IDYES anstelle der schnöden 6? Ich meine, lesbarer ist es auf jeden Fall (auch nach Monaten noch) und man spart sich den Kommentar:
Delphi-Quellcode:
if msg = IDYES then
Leider wird es wahrscheinlich nie passieren, aber ich würde mir mal wünschen, dass Microsoft diese Konstanten ändert. Borland wäre dann gezwungen, neue Bibliotheken mit den neuen Werten zu veröffentlichen. Ich bräuchte meine Programme nur neu kompilieren, und sie würden wieder funktionieren. Du dagegen müsstest deine Quellcodes durchsuchen und die numerischen Werte von Hand ändern. - Denk mal darüber nach. :)

Mat 31. Mai 2003 14:42

Hi Leute,


als ich gestern meinen Recher ausmachen wollte, hat das doch tatsaechlich nicht funktioniert!!! :( scheinbar kann ich das doch nicht so machen.. (obwohl ich schwoeren kann, das es bei meinem Test-Neustart noch geklappt hat)

jemand eine andere idee?


@matthias

die rueckgabewerte (6,7, etc.) habe ich alle aus der Online-Hilfe.. hab nicht gewusst, dass das auch anders geht... 'IDYES' gefaellt mir auch besser :)

@luckie
also Aufwand sparen wuerde ich nicht, weil ja die Option schon eingebaut ist.. :)

ich find die Moeglichkeit super, zumal bei Programmen, die die ganze Zeit nur im Systray sitzen. Wenn ich dann das Hauptfenster mal auf habe und wieder weg haben will, klick ich immer auf das [X] (frag nich warum), obwohl ich es ja eigentlich nur minimieren will...
und da ja die Moeglichkeit besteht, die Funktion abzuschalten, halte ich das nicht fuer wild.

das was ich grad programmiere wird Version 3.0 sein, alle Vorgaenger hatten diese Option drin, da sollte man sich nicht umgewoehnen sollen, denke ich.



Mat

Christian Seehase 31. Mai 2003 14:49

Moin Mat,

Zitat:

Zitat von Mat
die rueckgabewerte (6,7, etc.) habe ich alle aus der Online-Hilfe..

ja, und links daneben stehen die zugehörigen Namen ;-)
(zumindest bei mir)

Mat 31. Mai 2003 15:04

Zitat:

Zitat von Christian Seehase
Moin Mat,

Zitat:

Zitat von Mat
die rueckgabewerte (6,7, etc.) habe ich alle aus der Online-Hilfe..

ja, und links daneben stehen die zugehörigen Namen ;-)
(zumindest bei mir)

tatsache!! bei mir auch :shock:

RomanK 31. Mai 2003 15:24

Hoi Mat,
schau dir mal diesen Beitrag an ... das sollte doch eigentlich helfen:
http://www.delphipraxis.net/viewtopic.php?t=5291

Stanlay Hanks 31. Mai 2003 15:52

Hallo. Ich weiß jetz nicht, ob du das so gemeint hast, aber ich hab das so verstanden: Wenn der Benutzer eine Checkbox markiert, soll bei einem Klick auf den [x] Button das Programm minimiert werden. Wenn der Benutzer die Checkbox wieder checked := false macht, soll das Prog beendet werden.

Warum machst du das dann nicht so

Delphi-Quellcode:
var Beenden : Boolean = true;

procedure TForm1.btnBeendenClick(Sender: TObject);
begin
Beenden := true;
Close;
end;

procedure TForm1.chbMinimierenClick(Sender: TObject);
begin
Beenden := not chbMinimieren.checked;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
IF Beenden = true
 THEN
  CanClose := true
 ELSE
  begin
  CanClose := false;
  Application.Minimize;
  end;
Beenden := false;
end;
Bevor das Programm beendet werden kann, wird abgefragt, ob die Variable Beenden auch true is, d.h ob das Programm tatsächlich beendet werden soll, oder nur minimiert.

RomanK 31. Mai 2003 16:06

Hoi Stanlay,
dein Code ist vom Prinzip her nichts anderes als der Code von Mat. Das Problem ist, dass das Programm dann auch nicht vom Betriebsystem beendet werden kann, also den Code von meinem Link mit einarbeiten ... dann sollte es funktionieren.

Stanlay Hanks 31. Mai 2003 16:11

Aber mein Code is sauberer geschrieben :mrgreen: Nö im Ernst: Also über den Taskmanager kann man es ohne weiteres Beenden, wenn du das meinst. Aber über das SystemMenü. Oder was meinst du genau?

RomanK 31. Mai 2003 16:34

Ich rede vom Herunterfahren des Betriebsystems ...
Zitat:

Zitat von Mat
als ich gestern meinen Recher ausmachen wollte, hat das doch tatsaechlich nicht funktioniert!!! scheinbar kann ich das doch nicht so machen.. (obwohl ich schwoeren kann, das es bei meinem Test-Neustart noch geklappt hat)

jemand eine andere idee?


Stanlay Hanks 31. Mai 2003 17:20

Aber im Normalfall sollte daoch ein Programm vor dem Ausschalten des Computers schon beendet sein, oder?

RomanK 31. Mai 2003 17:35

:wiejetzt: was meinst du damit ... dass es vor dem Herrunterfahren von Hand geschlossen werden soll?

Stanlay Hanks 31. Mai 2003 17:38

genau das...oder will er das nicht?

RomanK 31. Mai 2003 17:46

Hoi Stanlay,
er will, dass das Programm wenn man es mit [x] oder ALT+F4 schließt, nicht geschlossen wird sondern in die TNA minimiert wird, also muss er im OnCloseQuery CanClose auf False stellen. Aber wenn das Betriebsystem den Close-Aufruf sendet soll das Programm ja beendet werden. So wie der Code momentan ist muss er es jedes Mal von Hand schließen, sonst fährt das Betriebsystem nicht normal herrunter.

Stanlay Hanks 31. Mai 2003 17:48

Dann müsste er quasi die Message von Windows abfangen, damit CanClose auf true gesetzt werden kann, oder?

Stanlay Hanks 31. Mai 2003 19:56

Was mir grade noch einfällt. Ich weiß nicht ob das geht. Aber man könnte doch nach jedem Minimieren canClose wieder auf true setzen, dann dürfte es doch auch keine Probleme mit dem Herunterfahren geben.

Mat 31. Mai 2003 21:52

wenn ich nach dem minimieren CanClose auf True setze, wuerde das Programm sich erst minimieren und danach beenden...


im uebrigen soll das Programm ja die ganze Zeit laufen, wenn Windows an ist, daher wird es wohl keiner vorher ausmachen wollen..

ueber den taskmanager kann man das mit meiner variante schon noch schliessen, nur halt beim runterfahren bleibt das programm an (es minimiert sich eben nur) und windows faehrt nicht runter.

ich guck mir mal den Code in dem Post an.


Mat

RomanK 31. Mai 2003 22:16

Zitat:

Zitat von FuckRacism
Hoi Mat,
schau dir mal diesen Beitrag an ... das sollte doch eigentlich helfen:
http://www.delphipraxis.net/viewtopic.php?t=5291

@Stanlay und Mat ... schaut euch mal den Link an ... :roll: :wink: :thuimb:
@Mat, wenn du damit nicht weiterkommst melde dich nochmal ...

Mat 31. Mai 2003 23:17

mmh.. mit dem link hat's irgendwie nich gefunzt..


ich hab mir heute mal cooltrayicon angeschaut.. in der demo davon gab's auch diese funktion, die hab ich uebernommen und es funktioniert..
(versteh das zwar nich unbedingt, aber es geht. :)

Delphi-Quellcode:
  private
    SessionEnding: Boolean;
    procedure WMQueryEndSession(var Message: TMessage); message WM_QUERYENDSESSION;

procedure TForm_Main.WMQueryEndSession(var Message: TMessage);
begin
  SessionEnding := True;
  Message.Result := 1;
end;
meine OnCloseQuery-Funktion sieht dann so aus:
Delphi-Quellcode:
procedure TForm_Main.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
      msg: Integer;
     text: String;
  askexit: Boolean;
begin

  askexit := True;
  if reg_minonx and (not ExitButtonWasClicked) then
    askexit := False;

  if askexit then
    begin
      text := 'Wollen Sie wirklich beenden?';
      msg := Application.MessageBox(Pointer(text), 'Beenden', MB_YESNO + MB_DEFBUTTON2 + MB_ICONQUESTION);

      if msg = IDYES then
        CanClose := True
      else
        CanClose := False;
    end
  else
      CanClose := False;

  if reg_minonx and (not ExitButtonWasClicked) then
    Application.Minimize;


  ExitButtonWasClicked := False;

  if SessionEnding then
    CanClose := True;


end;
wenn ich jetzt windows beende, wird nicht das Programm einfach geschlossen, ohne Abfrage, einfach so. Genau wie ich es haben will :)



Mat

RomanK 31. Mai 2003 23:51

Genau das mit der Message wurde doch bei dem Link erklärt. :roll: :| :freak:

Mat 1. Jun 2003 00:00

ne, das ist schon klar, aber in dem beispiel ("der link") wird ja 'WM_ENDSESSION' abgefangen, bei dem von cooltray 'WM_QUERYENDSESSION'

vor allem wundert mich, das es mit dem ersten beispiel nicht ging, aber mit dem zweiten dann...


aber hauptsache eins von beiden geht :)



Mat


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:11 Uhr.

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