Discussion:
Console App with Indy10 FTP client - event handlers
(too old to reply)
millerb
2008-06-19 20:24:28 UTC
Permalink
Hi Folks,

'Fraid I'm out of my depth here . . .

Need to build a console app to run invisibly using Indy's TIdFTP - to
download a file. (Got it working in a Form app)

I'd like to make use of the TIdFTP event handlers but don't know how to
set it up in a formless app. Here's the gist of it:

***************************
program AutoDownload;

//{$APPTYPE CONSOLE}

uses
SysUtils, IdFTP;

var
FTP: TIdFTP;
strm: TStringStream;

procedure FTPAfterClientLogin;
procedure FTPAfterGet;

procedure Main;
begin

FTP := TIdFTP.Create(nil);

FTP.OnAfterClientLogin := FTPAfterClientLogin;
FTP.OnAfterGet := FTPAfterGet;

FTP.Connect;

end;

procedure FTPAfterClientLogin;
var logNam;
begin
logNam := ...
...
try
strm := TStringStream.Create(s);
FTP.Get(logNam,strm,true);
finally
strm.Free;
end;
...
end;

procedure FTPAfterGet;
begin
...
end;

***************************

With the above code I'm getting this message:

E2009 Incompatible types: 'method pointer and regular procedure'

I've seen the stuff in Delphi 2005 Help on method pointers but haven't
been able to figure it out.

Suggestions/Examples appreciated.

Barry
Remy Lebeau (TeamB)
2008-06-19 21:06:54 UTC
Permalink
Post by millerb
I'd like to make use of the TIdFTP event handlers but don't
know how to set it up in a formless app.
VCL event handlers have to be members of a class. You have two options to
make this work in a console project:

1) (the easy way) define a class to hold the desired handlers, ie:

type
TFTPEvents = class
public
procedure FTPAfterClientLogin(ASender: TObject);
procedure FTPAfterGet(ASender: TObject; AStream: TStream);
end;

var
FTP: TIdFTP;

FTPEvent: TFTPEvents;
...

procedure Main;
begin
FTPEvents := TFTPEvents.Create;
FTP := TIdFTP.Create(nil);

FTP.OnAfterClientLogin := FTPEvents.FTPAfterClientLogin;
FTP.OnAfterGet := FTPEvents.FTPAfterGet;

...
end;

procedure TFTPEvents.FTPAfterClientLogin(ASender: TObject);
begin
...
end;

procedure TFTPEvents.FTPAfterGet(ASender: TObject; AStream: TStream);
begin
...
end;


2) (dirty hack) use TMethod to force non-class functions to act like class
methods, ie:

var
FTP: TIdFTP;
...

// notice the extra parameter in front...
procedure FTPAfterClientLogin(AFTP: TIdFTP; ASender: TObject);
procedure FTPAfterGet(AFTP: TIdFTP; ASender: TObject; AStream: TStream);

procedure Main;
var
M: TMethod;
begin
FTP := TIdFTP.Create(nil);

M.Code := @FTPAfterClientLogin;
M.Data := FTP;
FTP.OnAfterClientLogin := TOnAfterClientLogin(M);
// alternatively:
// Typinfo.SetMethodProp(FTP, 'OnAfterClientLogin', M);

M.Code := @FTPAfterClientLogin;
M.Data := FTP;
FTP.OnAfterGet := TIdFtpAfterGet(M);
// alternatively:
// Typinfo.SetMethodProp(FTP, 'OnAfterGet', M);

...
end;

procedure FTPAfterClientLogin(AFTP: TIdFTP; ASender: TObject);
begin
...
end;


procedure FTPAfterGet(AFTP: TIdFTP; ASender: TObject; AStream: TStream);
begin
...
end;


Gambit
Hannes Gouws
2008-06-19 21:10:09 UTC
Permalink
Hi Barry

You can do it with a normal form application, just set
Application.ShowMainForm := False; in your project source (.dpr) just before
the call to Application.Run
Post by millerb
Hi Folks,
'Fraid I'm out of my depth here . . .
Need to build a console app to run invisibly using Indy's TIdFTP - to
download a file. (Got it working in a Form app)
I'd like to make use of the TIdFTP event handlers but don't know how to
***************************
program AutoDownload;
//{$APPTYPE CONSOLE}
uses
SysUtils, IdFTP;
var
FTP: TIdFTP;
strm: TStringStream;
procedure FTPAfterClientLogin;
procedure FTPAfterGet;
procedure Main;
begin
FTP := TIdFTP.Create(nil);
FTP.OnAfterClientLogin := FTPAfterClientLogin;
FTP.OnAfterGet := FTPAfterGet;
FTP.Connect;
end;
procedure FTPAfterClientLogin;
var logNam;
begin
logNam := ...
...
try
strm := TStringStream.Create(s);
FTP.Get(logNam,strm,true);
finally
strm.Free;
end;
...
end;
procedure FTPAfterGet;
begin
...
end;
***************************
E2009 Incompatible types: 'method pointer and regular procedure'
I've seen the stuff in Delphi 2005 Help on method pointers but haven't
been able to figure it out.
Suggestions/Examples appreciated.
Barry
Loading...