这是我的示例代码,我使用Waitfor
等待线程完成
TCPThread = class(TThread)
protected
procedure Execute; override;
public
Source, Dest: String;
FHandle:THandle;
constructor Create(Source1, Dest1: string; TFHandle1: THandle);
end;
............
constructor TCPThread.Create(Source1, Dest1: string; TFHandle1: THandle);
begin
inherited Create(False);
Source:=Source1;
Dest:=Dest1;
FHandle:=TFHandle1;
end;
procedure TCPThread.Execute;
var
Cancel : PBool;
begin
Cancel := PBOOL(False);
CopyFileEx(PChar(Source), PChar(Dest), @CopyFileProgress, Pointer(FHandle), Cancel, 0);
end;
进度条运行良好,但我无法点击任何按钮和任何地方,例如取消按钮。
我需要等待文件被复制,或者必要时可以取消它并清理
CPThread := TCPThread.Create('D:\test.iso', 'D:\test2.iso',FHandle);
CPThread.WaitFor;
CPThread.Destroy;
答案 0 :(得分:7)
TThread.WaitFor()
阻塞调用线程,直到线程终止。在主UI线程的上下文中调用时,WaitFor()
不会处理挂起的窗口消息(但会处理挂起的TThread.Synchronize()
和TThread.Queue()
请求)。这就是为什么你不能点击任何东西。
对于您尝试做的事情,请不要等待线程。让它在将控制权返回到主UI消息循环时正常运行,并让线程告诉您何时完成其工作。
此外,您滥用pbCancel
的{{1}}参数。
尝试更像这样的事情:
CopyFileEx()
type
TCPThread = class(TThread)
private
Cancel : BOOL;
Source, Dest: String;
FHandle: THandle;
protected
procedure Execute; override;
procedure TerminatedSet; override;
public
constructor Create(Source1, Dest1: string; TFHandle1: THandle);
end;
constructor TCPThread.Create(Source1, Dest1: string; TFHandle1: THandle);
begin
inherited Create(True);
FreeOnTerminate := True;
Source := Source1;
Dest := Dest1;
FHandle := TFHandle1;
end;
procedure TCPThread.Execute;
begin
if not CopyFileEx(PChar(Source), PChar(Dest), @CopyFileProgress, Pointer(FHandle), @Cancel, 0) then
ReturnValue := GetLastError;
end;
procedure TCPThread.TerminatedSet;
begin
Cancel := True;
end;