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;
==========
上記プログラムでコンパイルすると
「型に互換性がありません: メソッドポインタと通常の手続き」
というエラーが表示されてしまいます。
これが作成されているパスにはフォームは存在しません。
解決方法など教えてください。
よろしくお願いします。
たとえば 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 かなにかのメソッドにしてください。
>パスにはフォームは存在しません。
フォームでなくてもなにかクラスのインスタンスをつかってませんか?
そのクラスの派生クラスを作ってメソッドにする必要があります。
コンソールアプリのようにクラスをひとつも使わないのでしたら、
自作する必要があります。
type
TMethodHolder = class(TOnject)
public
procedure ftpFtpWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
......
end;
てして最初にこのインスタンスを作成してください。
りりかさん、ありがとうございます。
教えていただいたように以下のように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;
とすると、未定義の識別子のエラーになってしまいます。
どこか記述が間違っているのでしょうか?
すみません・・・。
初歩的なミスをしてしまいました。
TMethodHolderもCreateしなければいけませんね。
FTPのCreateの下に以下の1文を追加したら通りました。
MethodHolder := MethodHolder.Create;
ありがとうございました!
var
MethodHolder:TMethodHolder;
と宣言しておいて
MethodHolder := TMethodHolder.Create;
とインスタンスをつくってから
ftpFTP.OnWork := MethodHolder.ftpFtpWork;
と代入します。
ツイート | ![]() |