Hallo zusammen!
Ich möchte unter Delphi 6 mit
Indy 10 einen kleinen
FTP-Client programmieren.
Das "Grundgerüst" mit der Finktionalität steht schon. Nun habe ich ein paar kleine Probleme.
Das Programm "schläft" bei einer
FTP-Übertragung ein. Um genauer zu sein, die Oberfläche in einem zu großen Intervall aktuallisiert. Nämlich immer wenn das
TOnWork
Event von IdFTP eintritt. Und das ist bei großen Dateien und langsamen Verbindungen einfach zu langsam. Außerdem kann man den Verbindungsversuch nicht abbrechen, da
Indy den Hauptthread "blockiert". Das sind nur ein paar Schwierigkeiten.
AntiFrezze bringt nichts, da ich die Oberfläche und die Programmligik komplett von einander getrennt habe. Die Infos werden per
Procedure of Object
ausgetauscht. In anderen Forenbeiträgen wird auch da von berichtet, dass AntiFrezze in manchen Fällen nicht funktioniert.
Nun habe ich mir gedacht, dann mache ich das eben in einem eingenen Thread. Das habe ich in diveren Beiträgen auch schon gelesen. Und ich habe mir auch das Tutorial von Luckie durchgelesen.
Gesagt getan, nicht von TObject abgeleitet sondern von TThread, also meine
FTP-Klasse die "Wrapper" für die IdFTP-Klasse dient. Die Methode
Execute
überschrieben...
Delphi-Quellcode:
procedure TFTPHandle.Execute;
begin
inherited;
while not Terminated do
begin
WaitFor;
end;
OutputDebugString(PChar('Terminated = ' + PChar(BoolToStr(Terminated, True))));
end;
Und nun kommen wir zu meinem Problem. Ich möchte den Thread über Windows-Messages steuern.
Also habe ich mir ein paar Nachichten deklariert:
Delphi-Quellcode:
WM_FTPBase = WM_USER + 1;
WM_FTPConnectToServer = WM_FTPBase + 1;
WM_FTPErrorHappend = WM_FTPBase + 2;
WM_FTPCommandSuccessful = WM_FTPBase + 3;
WM_FTPUploadFileList = WM_FTPBase + 4;
WM_FTPDownloadFileList = WM_FTPBase + 5;
(...)
(Ja, ich weiß man kann den Nachrichten auch Parameter anhängen, dann hätte ich mir ein paar sparen können)
Nun weiß ich nicht wie der Thread auf die Nachrichte reagieren soll.
Ich habe diesen ersten Ansatz:
Delphi-Quellcode:
procedure WMFTPConnectToServer(var Message: TMessage); message WM_FTPConnectToServer;
procedure WMFTPCancelCurrentAction(var Message: TMessage); message WM_FTPCancelCurrentAction;
Diese Methoden werden aber nie aufgerufen, da schon das
PostThreadMessage(FTPInstance.ThreadID, WM_EAEFTPConnectToServer, 0, 0)
fehl schlägt, d.h. es wird False zurückgegeben. Also GetLastError aufgerufen und was ist darin? Eine "0"...
Noch eine kleine Zusatzinfo, das Objekt FTPIntance wird im initialization-Abschnitt einer anderen
Unit erzeugt.
So sieht der constructor aus:
Delphi-Quellcode:
inherited Create(False);
FreeOnTerminate := True;
(...)
Dann gibt es noch ein kleines Problem beim Beenden der Anwendung, wenn ich Terminate aufrufe. Dann ist der Thread auch weg, das kann habe ich mit dem
Process Explorer von
Sysinternals kontrolliert. Nur leider "hängt" dann der Hauptthread fest.
Noch ein paar kleine Hardware- und Softwareinfos:
Windows XP Pro (SP2)
Delphi 6 Ent mit Update Pack 2
Pentium 4 mit HT
Wäre schön, wenn ihr mir helfen könntet.
MfG
naujo
// Nachtrag:
Den Hänger beim Beenden konnte ich beseitigen.
Im finalization-Abschnitt war noch ein Free vorhanden, dass hab ich jetzt rausgenommen.
Da beim Create ja schon
FreeOnTerminate := True
festgelegt wurde.