是否有可能从一个线程调用CopyFileEx和CopyCallback / ProgressRoutine函数(ProgressBar.Position将同步)?
我可以在线程中声明CopyCallback / ProgressRoutine函数吗?我在@ProgressRoutine上的CopyFileEx中收到错误:“需要变量”。
答案 0 :(得分: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;
参数隐式传递。
{{1}}