AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Wie das Blockieren beim Herunterfahren verhindern/umgehen?
Thema durchsuchen
Ansicht
Themen-Optionen

Wie das Blockieren beim Herunterfahren verhindern/umgehen?

Ein Thema von Schucki · begonnen am 16. Nov 2009 · letzter Beitrag vom 27. Nov 2009
Antwort Antwort
Seite 2 von 2     12   
Schucki

Registriert seit: 17. Jul 2004
158 Beiträge
 
Delphi 2010 Architect
 
#11

Re: Wie das Blockieren beim Herunterfahren verhindern/umgehe

  Alt 23. Nov 2009, 11:56
Hi!

Danke für Eure Antworten. Ich denke das geht in die richtige Richtung obwohl es noch nicht zu 100% läuft.
Ich kann die einzelnen Msg. filtern und dann darauf reagieren. Die ganzen OnClose und OnCloseQuery Events vom Hauptformular habe ich nun gelöscht. Entweder hier oder dort...

Das wird geschickt wenn man auf mbtClose drückt...

Delphi-Quellcode:
procedure TfrmMain.mbtnCloseClick(Sender: TObject);
begin
  SendMessage(frmMain.Handle,WM_CLOSE,0,0);
end;
... Msg abhandeln ...

Delphi-Quellcode:
procedure TfrmMain.WndProc(var Message: TMessage);
const
  LONGBOOL_FALSE : Cardinal = 0;
  LONGBOOL_TRUE : Cardinal = 1;
begin
  if (Message.Msg = WM_CLOSE) then begin
    Message.Result := LONGBOOL_FALSE;
    // ShowMessage('Schließen sollst du ;-)');
    if comUnit.PortOpen then begin
      if (not bolMainCanClose) and (not timClose.Enabled) then begin
        // ShowMessage('Jaja nur erst vom Gerät abmelden!');
        mbtnConnect.Click;
        timClose.Enabled:=True;
      end;
    end else begin
      ShowMessage('So, hab mich fein abgemeldet... close Ok!');
      bolMainCanClose:=True;;
    end;
    if bolMainCanClose then Close;
  end else

  if (Message.Msg = WM_QUERYENDSESSION) then begin
    bolShutDown:=True;
    if comPtc.PortOpen then begin
      ShowMessage('Jetzt noch nicht, hab was dagegen !');
      intSavW:=Message.WParam;
      intSavL:=Message.LParam;
      mbtnClose.Click;
    end else begin
      Message.Result := LONGBOOL_TRUE;
      ShowMessage('Jetzt schon, und Tschüss...');
    end;
  end else
// if (Message.Msg = WM_ENDSESSION) then begin
// Message.Result := LONGBOOL_FALSE;
// ShowMessage('Dann beende mal jetzt!');
// end else
  begin
    inherited WndProc(Message)
  end;
end;
... und der Timer sieht so aus...

Delphi-Quellcode:
procedure TfrmMain.timCloseTimer(Sender: TObject);
begin
  inc(intCanClose);
  if (intCanClose >= 10) or ((not bolDeiniRun) and (not bolForceDeini)) then begin
    timClose.Enabled:=False;
    bolMainCanClose:=True;
    if bolShutDown then SendMessage(frmMain.Handle, WM_QUERYENDSESSION, intSavW, intSavL);
    mbtnClose.Click;
  end;
end;
Nun es klappt noch nicht... ein Beantworten auf WM_QUERYENDSESSION mit TRUE sorgt dafür das die Anwendung sofort zugeht ohne das sie sich bei dem angeschlossenen Gerät abmeldet. Also muß ich min 1x mit FALSE antworten. Damit ist dann aber das Herunterfahren abgebrochen und müßte neu ausgelöst werden. Wäre auch nicht so schlimm denke ich wenn man den wüste was vorher von Windows bei der 1. WM_QUERYENDSESSION gefordert wurde. Stanby, Shutdown oder Logoff???

Die Info hab ich noch nicht... so dacht ich nun das ich die WM_QUERYENDSESSION das 1. mal einfach nicht beantworte und dann selber nochmal auslöse und diese dann mit TRUE beantworte. Das geht aber wohl auch nicht... Windows wertet wohl pro MSG an alle auch mit einer sofortigen Antwort. Und wenn die nicht kommt ist es FALSE?

Bei dem angeschlossenen Gerät muß ein bestimmtes Protokoll eingehalten werden, das geht nunmal nicht direkt mit 3 Zeilen die man ihm schickt. Das muß beim Beenden abgemeldet werden, das dauert ca. 3 Sekunden. Erst wenn das passiet ist, darf man das Prg Beenden.

Funktioniert 1A bei einem manuellen Click auf mbtnClose oder ALT+F$ aber das über Herunterfahren nicht. Was könnte man noch versuchen, gibt es noch einen anderen Lösungansatz von einem erfahrenen Entwickler als mich?

Danke, Gruß Frank
Frank
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#12

Re: Wie das Blockieren beim Herunterfahren verhindern/umgehe

  Alt 23. Nov 2009, 13:07
Als Ergänzung: Grundsätzlich ist die Vorgehensweise, dass du im ENDSESSION (nicht im QUERYENDSESSION) deine Verarbeitung zum Herunterfahren durchführst. QUERYENDSESSION dient eigentlich ausschließlich dazu, das Herunterfahren abzubrechen.

Wichtig ist, dass du einigermaßen schnell bist. Firefox hat beispielsweise früher grundsätzlich beim Herunterfahren nichts gemacht (Session ist in den AutoRecovery-Daten gespeichert), so dass die Daten beim nächsten Start wieder da waren. Das geht schnell, normales Beenden von Firefox ist sehr langsam (wenn viele Tabs offen sind). Wenn du langsam bist, kommt ab Vista relativ schnell ein abgedunkelter Bildschirm, auf dem deutlich zu sehen ist, dass DU den Start verzögerst. Der Benutzer kann dann eiskalt auf "Sofort herunterfahren" klicken und du hast keine Chance mehr, auf irgendwas zu reagieren. Aber deine ENDSESSION-Behandlung läuft immer noch weiter, auch wenn der Bildschirm abgedunkelt ist. Ab 7 hast du sogar die Möglichkeit, einen Text anzugeben, der vom abgedunkelten Bildschirm für deine Anwendung angezeigt wird (Beispiel: VMWare Workstation 7 zeigt an, dass es gerade eine VM runterfährt), so dass der Benutzer dich vielleicht noch nicht abwürgt. Sofern du immer noch schneller fertig bist als die letzten Programme, die geschlossen werden, funktioniert das eigentlich auch ganz gut. Insofern ist, meiner Meinung nach, die korrekte Vorgehensweise, einfach im ENDSESSION dein Ding durchzuziehen und zu hoffen, dass es reicht. Wenn es nicht reicht, hat der Benutzer ab Vista explizit dein Programm abgeschossen. Das kann er natürlich sowieso, auch ohne Herunterfahren.
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
Schucki

Registriert seit: 17. Jul 2004
158 Beiträge
 
Delphi 2010 Architect
 
#13

Re: Wie das Blockieren beim Herunterfahren verhindern/umgehe

  Alt 27. Nov 2009, 17:43
Komme erst heute Abend dazu damit weiter zu machen.
In den letzten Tagen war ich auf der Suche nach der Message die man abfangen muß wenn ein User die Anwendeung mit der rechten Maustatste aus der Taskleiste beenden möchte. Das ist mir noch nicht gelungen herauszubekommen.

Weiß einer von Euch wie die heist?

WM_CLOSE ist es nicht

Danke im Voraus!!!

Gru0 Frank
Frank
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.624 Beiträge
 
Delphi 12 Athens
 
#14

Re: Wie das Blockieren beim Herunterfahren verhindern/umgehe

  Alt 27. Nov 2009, 17:46
IIRC ist das WM_SYSCOMMAND mit SC_CLOSE.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Schucki

Registriert seit: 17. Jul 2004
158 Beiträge
 
Delphi 2010 Architect
 
#15

Re: Wie das Blockieren beim Herunterfahren verhindern/umgehe

  Alt 27. Nov 2009, 19:25
Tch es gelingt mir nicht die MSG zu bekommen... habe folgenes gemacht...

Delphi-Quellcode:
...
   private
     procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
...
Und dann...

Delphi-Quellcode:
procedure TfrmMain.WMSysCommand(var Msg: TWMSysCommand);
begin
  if Msg.CmdType = SC_CLOSE then begin
    if not bolMainCanClose then mbtnClose.Click;
    Msg.Result := 0;
  end;
  Inherited;
end;
Aber wenn ichnun einen BP bei "if Msg.CmdType = SC_CLOSE then begin" setze wird der nie angefahren, meine Anwendung geht einfach nur zu

Was hab ich da wohl übersehen?
Gruß Frank
Frank
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.624 Beiträge
 
Delphi 12 Athens
 
#16

Re: Wie das Blockieren beim Herunterfahren verhindern/umgehe

  Alt 27. Nov 2009, 20:11
Tja, weiß ich auch nicht. Kleiner Gegentest bei mir:
Delphi-Quellcode:
procedure TFormTest.WMSysCommand(var Msg: TWMSysCommand);
begin
  if Msg.CmdType = SC_CLOSE then
    ShowMessage('Tschüss');
  inherited;
end;
Über die Taskleiste, über das "X", über ALT-F4, immer sagt das Programm mir Tschüss wie erwartet (Win 7 Home Premium).
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:52 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