Конечно, это возможно. Функция обратного вызова будет вызываться в контексте потока, вызывающего CopyFileEx
. Если вам нужно синхронизировать некоторые команды пользовательского интерфейса, используйте обычную TThread.Synchronize
Delphi или любую другую технику синхронизации между потоками, которую вы хотите.
Функция обратного вызова не может быть методом класса потока. Он должен соответствовать подписи, продиктованной 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;
person
Rob Kennedy
schedule
16.06.2011