Zitat:
ich habe keine Lust,
DEC, KAZIP und
ZLIB für application.terminated
was auch ziemlich dämlich wäre da du damit diese Source abhängig machst von einer rießigen
VCL. Der Zugriff auf Application bindet
unit Forms ein und damit defakto die halbe
VCL. Die Entwickler dieser Bibliotheken wissen warum sie das nicht gemacht haben.
Normalerweise wird ein Programmierer eben nicht über Application.ProcessMessages eine parallele Abarbeitung des Messagesques anstoßen und deshalb ist der Aufruf von Application.Terminated meistens auch überflüssig. Du musst halt bedenken, Application.ProcessMessages ist es die in deinem TForm beim Button1.Click die OnClick() Methode aufruft. Wird darin nun selber in einer Schleife Application.ProcesssMessages aufgerufen dann hast du defakto sowas wie ein fast fertige "Endlosrekursion" programmiert. Nur ist diese nicht so offensichtlich da hier
VCL+Events+Messages von Windows involviert sind. Hast du zb. eben nicht deinen Button disabled so kann der Benutzer diese erneut drücken und damit landet man wieder im OnClick() obwohl du noch im OnClick() in der .ProcessMessages Loop drinnen bist. Es ist nicht reentrant in diesem Moment und das hat arge Seiteneffekte. Zb. du greifts in deiner OnClick() + .Processmessages Loop auch auf Objecte des TForms zu. Nun, wenn .ProcessMessages aufgerufen wird un der Benutzer drückt den Close-Button des Fensters in der Titelleiste dann wird das TForm zerstört. Aber der Programcounter ist immer noch in deiner Schleife die auf Daten dieses Forms zugreift, bumms
Exception.
Das was du also vorhast ist im Grunde schlecht, aber relativ gesehen noch Bedienersicher zu bekommen.
1.) eine OnClick() muß reentrant werden, zb. durch Disablen des Buttons oder durch ein Locking
2.) OnCloseQuery des Form benutzen und dort erst dann TRUE zurückliefern wenn deine Berechnungsfunktion/Loop beendet wurde.
die beste Methode wären aber Threads und solche Callbacks wie in meinem
DEC. Man startet einen Thread und alle längerdauernen Operationen rufen eine Callback wie im
DEC auf. In dieser wird überprüft ob der Thread terminiert werden soll, also Self.Terminated, und wenn ja dann wird eine stille
Exception EAbort ausgelösst. Im Mainpart des Threads wurde alles per try except gekapselt.
Die
ZLib, KAZIP Methoden die per TStream Descants arbeiten kannst du ohne Änderungen am Originalsource mit einer solchen Callback versehen. Dazu gibts hier im Forum einen TStreamProgressAdapter oä. Dieser wird quasi zwischen den eigentlichen Stream zu deinen Dateien zwischen-geschaltet und als Parameter diesen Bibliotheken übergeben. Beim
DEC geht das auch ist aber nicht notwendig.
http://www.delphipraxis.net/internal...tream+progress
Gruß Hagen