Einzelnen Beitrag anzeigen

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