Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi: CopyFileEx and Thread

I have a thread and a Progress Routine (a function) inside it (in my thread class).

I try to do this inside the thread:

CopyFileEx(pchar(ListToCopy.Strings[Loop]),pchar(TN+ExtractFileName(ListToCopy.Strings[Loop])), @ProgressRoutine, nil, nil, 0);

But I get an error: "Variable required" (the error is in this: @ProgressRoutine). If to make the function ProgressRoutine outside the thread then all will be normal.

How to use that function inside thread?

Thanks.

like image 748
maxfax Avatar asked Aug 09 '11 00:08

maxfax


1 Answers

When you say "outside the thread" and "inside the thread", do you mean "as a standalone function" and "as a member of the thread object"? Because if a function is a member of an object, its signature is different, so it doesn't match what the compiler is expecting.

The way you can resolve this is to pass Self to CopyFileEx as the lpData parameter. This gives it a pointer that it will pass back to the callback. Write your callback as a standalone function that interprets the lpData parameter as a thread object reference and uses that to call the method on your thread object with the same parameters.

EDIT: Simple example. Let's say that the callback only has two parameters, called "value" and "lpData":

procedure ProgressRoutine(value: integer; lpData: pointer); stdcall;
var
  thread: TMyThreadClass;
begin
  thread := lpData;
  thread.ProgressRoutine(value);
end;

procedure TMyThreadClass.ProgressRoutine(value: integer);
begin
  //do something with the value here
end;

procedure TMyThreadClass.Execute;
begin
  CopyFileEx(pchar(ListToCopy.Strings[Loop]),pchar(TN+ExtractFileName(ListToCopy.Strings[Loop])), @ProgressRoutine, Self, nil, 0);
  //passing Self to lpData; it will get passed back to the callback
end;
like image 80
Mason Wheeler Avatar answered Nov 07 '22 06:11

Mason Wheeler