FTPのイベントの関連付けを行うには?

解決


えみ  2004-11-05 23:57:14  No: 11650

Delphi7にてFTPを使ってダウンロードを行う処理を作成しています。
TIdFTPにOnWork、OnWorkBegin、OnWorkEndのイベントを関連付けようとしていますが、
コンパイルエラーとなってしまいます。
どのように解決すればよろしいでしょうか?
プログラムとエラーは以下のようになります。

==========

type
 TLikeList = Class
   a   : string;
   b   : string;
 end;

procedure FtpCreate;
procedure ftpFtpWork(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCount: Integer);
procedure ftpFtpWorkBegin(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCountMax: Integer);
procedure ftpFtpWorkEnd(Sender: TObject; AWorkMode: TWorkMode);

procedure FtpCreate;
begin
  //FTPのCreate
  ftpFTP := TIdFtp.Create(nil);

  //FTPイベントの結びつけ
  ftpFTP.OnWork      := ftpFtpWork;
  ftpFTP.OnWorkBegin := ftpFtpWorkBegin;
  ftpFTP.OnWorkEnd   := ftpFtpWorkEnd;
end;

procedure ftpFtpWork(Sender: TObject; AWorkMode: TWorkMode;
 const AWorkCount: Integer);
begin
  //プログレスバーの制御
end;

procedure ftpFtpWorkBegin(Sender: TObject; AWorkMode: TWorkMode;
 const AWorkCountMax: Integer);
bgein
  //プログレスバーの制御
end;

procedure ftpFtpWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
  //プログレスバーの制御
end;

==========

上記プログラムでコンパイルすると
「型に互換性がありません: メソッドポインタと通常の手続き」
というエラーが表示されてしまいます。

これが作成されているパスにはフォームは存在しません。

解決方法など教えてください。
よろしくお願いします。


りりか  2004-11-06 00:57:00  No: 11651

たとえば TButton の OnClick についてヘルプを見ると

property OnClick: TNotifyEvent;

というふうに TNotifyEvent 型のプロパティーになっています。ですから 
TNotifyEvent 型のメソッドポインタを代入できるプロパティーですね。で

type TNotifyEvent = procedure (Sender: TObject) of object;

です。末尾の of object はクラスのメソッドであることを示しています。
したがって、たとえば

procedure ButtonClick(Sender: TObject);
begin

end;

のようにして

Form1.Button1.OnClick := ButtonClick;

とするとコンパイルできません。ButtonClick は単なる手続きでクラスのメソッド
ではないからです。えみさんの場合も代入できるのはクラスのメソッドで型があっている
ものだけです。TForm1 かなにかのメソッドにしてください。


りりか  2004-11-06 01:03:27  No: 11652

>パスにはフォームは存在しません。

フォームでなくてもなにかクラスのインスタンスをつかってませんか?
そのクラスの派生クラスを作ってメソッドにする必要があります。
コンソールアプリのようにクラスをひとつも使わないのでしたら、
自作する必要があります。

type
TMethodHolder = class(TOnject)
public
  procedure ftpFtpWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
  ......
end;

てして最初にこのインスタンスを作成してください。


えみ  2004-11-06 01:24:33  No: 11653

りりかさん、ありがとうございます。

教えていただいたように以下のようにTMethodHolderを作成しましたが、
またもやエラーとなってしまいました。

===========
type
  TMethodHolder = class(TObject)
  public
    procedure ftpFtpWork(Sender: TObject; AWorkMode: TWorkMode;
          const AWorkCount: Integer);
    procedure ftpFtpWorkBegin(Sender: TObject; AWorkMode: TWorkMode;
          const AWorkCountMax: Integer);
    procedure ftpFtpWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
  end;

procedure FtpCreate;
begin
  //FTPのCreate
  ftpFTP := TIdFtp.Create(nil);

  //FTPイベントの結びつけ
  ftpFTP.OnWork      := TMethodHolder.ftpFtpWork;
  ftpFTP.OnWorkBegin := TMethodHolder.ftpFtpWorkBegin;
  ftpFTP.OnWorkEnd   := TMethodHolder.ftpFtpWorkEnd;
end;

procedure TMethodHolder.ftpFtpWork(Sender: TObject; AWorkMode: TWorkMode;
 const AWorkCount: Integer);

(残り2つの関数も同じようにTMethodHolderを追加しました)

===========

上記でコンパイルすると
「'TWorkEvent'と'Procedure'には互換性がありません」
というエラーになってしまいました。

>ftpFTP.OnWork      := TMethodHolder.ftpFtpWork;

ここの部分を

ftpFTP.OnWork      := MethodHolder.ftpFtpWork;

とすると、未定義の識別子のエラーになってしまいます。

どこか記述が間違っているのでしょうか?


えみ  2004-11-06 01:30:39  No: 11654

すみません・・・。
初歩的なミスをしてしまいました。

TMethodHolderもCreateしなければいけませんね。
FTPのCreateの下に以下の1文を追加したら通りました。

MethodHolder := MethodHolder.Create;

ありがとうございました!


りりか  2004-11-06 01:32:06  No: 11655

var
  MethodHolder:TMethodHolder;

と宣言しておいて

MethodHolder := TMethodHolder.Create;

とインスタンスをつくってから

ftpFTP.OnWork      := MethodHolder.ftpFtpWork;

と代入します。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加