6

スレッドから CopyFileEx と CopyCallback/ProgressRoutine 関数 (ProgressBar.Position が同期されます) を呼び出すことは可能ですか?

スレッドで CopyCallback/ProgressRoutine 関数を宣言できますか? @ProgressRoutine の CopyFileEx で Error: "Variable required" が発生します。

4

1 に答える 1

12

もちろん可能です。コールバック関数は、 を呼び出すスレッドのコンテキストで呼び出されますCopyFileEx。一部の UI コマンドを同期する必要がある場合は、Delphi の通常のTThread.Synchronize、または必要なその他のスレッド間同期技術を使用します。

コールバック関数をスレッド クラスのメソッドにすることはできません。API によって指定された署名と一致する必要があるため、スタンドアロン関数である必要があります。@正しく宣言すると、に渡すときに演算子を使用する必要がなくなりますCopyFileEx

function CopyProgressRoutine(TotalFileSize, TotalBytesTransferred: Int64;
  StreamSize, StreamBytesTransferred: Int64;
  dwStreamNumber, dwCallbackReason: DWord;
  hSourceFile, hDestinationFile: THandle;
  lpData: Pointer): DWord; stdcall;

パラメータを使用して、関連付けられたスレッド オブジェクトへのアクセスをコールバック関数に与えることができlpDataます。を呼び出すときに、そのパラメーターのスレッド オブジェクトへの参照を渡しますCopyFileEx

procedure TCopyThread.Execute;
begin
  ...
  CopyResult := CopyFileEx(CurrentName, NewName, CopyProgressRoutine, Self,
    @Cancel, CopyFlags);
  ...
end;

スレッド オブジェクトにアクセスすると、独自の進捗ルーチンを含むそのオブジェクトのメソッドを呼び出すことができるため、次のコードでスタンドアロン関数全体を構成できます。他のすべてをオブジェクトのメソッドに委任できます。ここでは、メソッドにはスタンドアロン関数と同じパラメーターがすべて含まれていると想定していますが、パラメーターlpDataとして暗黙的に渡されるため、パラメーターが省略されていSelfます。

function CopyProgressRoutine;
var
  CopyThread: TCopyThread;
begin
  CopyThread := lpData;
  Result := CopyThread.ProgressRoutine(TotalSize, TotalBytesTransferred,
    StreamSize, StreamBytesTransferred, dwStreamNumber,
    dwCallbackReason, hSourceFile, hDestinationFile);
end;
于 2011-06-16T04:28:35.727 に答える