createthread(nil,0,@ThreadProc,nil,0,ThreadID);中的nil和0各是什么作用的啊?(20分)

  • 主题发起人 主题发起人 07idea
  • 开始时间 开始时间
0

07idea

Unregistered / Unconfirmed
GUEST, unregistred user!
能否给我说说?
 
nil是传递给ThreadProc的参数
0是表示创建后立即运行,如果为CREATE_SUSPENDED则为挂起状态,要调用ResumeThread才会运行
用DELPHI的TThread类就可以了,没必要用这个
 
nil是传递给ThreadProc的参数
是哪个nil?如果有多个参数呢?
 
參數是一個指針,有多個參數就定義一個結構:
type
TSendParam = Record
Param1 : Integer;
Param2 : Integer;
...
end;
var
SendParam : TSendParam;
createthread(nil,0,@ThreadProc,@SendParam,0,ThreadID);

 
function CopyProgress(FileSize, Transferred: Int64;
StreamSize, StreamTransferred: Int64;
StreamNumber, CallbackReason: DWORD;
SourceFile, DestFile: THandle;
Data: Pointer): DWORD;
stdcall;
var
Form: TForm1;
begin
Form := Data;
Form.Gauge1.Maxvalue := FileSize;
Form.Gauge1.Progress := Transferred;
Result := PROGRESS_CONTINUE;
Application.ProcessMessages;
end;

CopyFileEx(pchar(edit2.Text), pchar(edit3.Text), @CopyProgress,
Self, nil, COPY_FILE_FAIL_IF_EXISTS);
那这个可以改成多线程吗?
 
老实说可以参看API参考啊,
建立一个线程,至少应该有参数,是否创建时立即启动选项以及安全属性等设置的,Windows SDK 帮助 C++ Builder 5里头都有啊??
 
參考一下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, CommCtrl;
type
TCopyFileData = Record
Source: string;
Destination: string;
pCancel : Pointer;
hProgress : THandle;
end;

TCopyFile = Class
private
IsStop : BOOL;
FHandle : THandle;
ThreadId: LongWord;
CopyFileData : TCopyFileData;
public
constructor Create(const Source: string;
const Destination: string;
Progress : Thandle);
destructor Destroy;
override;
procedure Start;
procedure Cancel;
procedure WaitFor;
end;

TForm1 = class(TForm)
Button1: TButton;
ProgressBar1: TProgressBar;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
CopyFile : TCopyFile;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
{ TCopyFile }
function CopyProgressRoutine(
TotalFileSize : LARGE_INTEGER;
TotalBytesTransferred : LARGE_INTEGER;
StreamSize : LARGE_INTEGER;
StreamBytesTransferred : LARGE_INTEGER;
dwStreamNumber : DWORD;
dwCallbackReason : DWORD;
hSourceFile : THandle;
hDestinationFile : THandle;
lpData : Pointer) : DWORD;
stdcall;
begin
with TCopyFileData(lpData^)do
begin
SendMessage(hProgress, PBM_SETRANGE32, 0, TotalFileSize.QuadPart);
SendMessage(hProgress, PBM_SETPOS, TotalBytesTransferred.QuadPart, 0);
Result := PROGRESS_CONTINUE;
end;
end;

function ThreadFunc(Parameter: Pointer): BOOL;
begin
with TCopyFileData(Parameter^)do
begin
Result := CopyFileEx(PChar(Source),PChar(Destination),
@CopyProgressRoutine, Parameter, pCancel, COPY_FILE_RESTARTABLE);
end;
end;

procedure TCopyFile.Start;
begin
if FHandle = 0 then
begin
IsStop := False;
FHandle := begin
Thread(nil,0,@ThreadFunc,@CopyFileData, CREATE_SUSPENDED,ThreadId);
ResumeThread(FHandle);
end;
end;

procedure TCopyFile.WaitFor;
var
WaitResult: Cardinal;
Msg: TMsg;
begin
if GetCurrentThreadID = MainThreadID then
begin
WaitResult := 0;
repeat
if WaitResult = WAIT_OBJECT_0 + 1 then
PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE);
Sleep(0);
CheckSynchronize;
WaitResult := MsgWaitForMultipleObjects(1, FHandle, False, 0, QS_SENDMESSAGE);
until WaitResult = WAIT_OBJECT_0;
end else
WaitForSingleObject(FHandle, INFINITE);
end;

constructor TCopyFile.Create(const Source, Destination: string;
Progress : Thandle);
begin
IsStop := False;
CopyFileData.Source := Source;
CopyFileData.Destination := Destination;
CopyFileData.pCancel := @IsStop;
CopyFileData.hProgress := Progress;
end;

destructor TCopyFile.Destroy;
begin
if not IsStop then
Cancel;
inherited Destroy;
end;

procedure TCopyFile.Cancel;
begin
IsStop := True;
WaitFor;
CloseHandle(FHandle);
FHandle := 0;
end;

{TFrom1}
procedure TForm1.Button1Click(Sender: TObject);
begin
CopyFile.Start;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
CopyFile.Cancel;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
CopyFile := TCopyFile.Create('E:/Vickwa/databak/20040230.bak',
'd:/20040230.bak',ProgressBar1.Handle);
end;

end.
 
谢谢amli,
你的代码完全可以用,但是在复制文件时,取消了复制,刚复制未完成的文件就会被删除,如何做个button,让文件停止copy,并保留这复制的部分?
还有,怎么判断文件已复制完?除了用文件大小来判断。
等解决这个问题后,另开贴再送50分。。。
 
//修改了一下.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, CommCtrl;
type
TCopyFileData = Record
Source: string;
Destination: string;
pCancel : Pointer;
hProgress : THandle;
end;

TCopyFile = Class
private
IsStop : BOOL;
FHandle : THandle;
ThreadId: LongWord;
CopyFileData : TCopyFileData;
public
constructor Create(const Source: string;
const Destination: string;
Progress : Thandle);
destructor Destroy;
override;
procedure Start;
procedure Cancel;
function WaitFor : DWORD;
end;

TForm1 = class(TForm)
ProgressBar1: TProgressBar;
Button2: TButton;
Animate1: TAnimate;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
CopyFile : TCopyFile;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
{ TCopyFile }
function CopyProgressRoutine(
TotalFileSize : LARGE_INTEGER;
TotalBytesTransferred : LARGE_INTEGER;
StreamSize : LARGE_INTEGER;
StreamBytesTransferred : LARGE_INTEGER;
dwStreamNumber : DWORD;
dwCallbackReason : DWORD;
hSourceFile : THandle;
hDestinationFile : THandle;
lpData : Pointer) : DWORD;
stdcall;
begin
with TCopyFileData(lpData^)do
begin
SendMessage(hProgress, PBM_SETRANGE32, 0, TotalFileSize.QuadPart);
SendMessage(hProgress, PBM_SETPOS, TotalBytesTransferred.QuadPart, 0);
if BOOL(pCancel^) then
Result := PROGRESS_STOP
else
Result := PROGRESS_CONTINUE;
end;
end;

function ThreadFunc(Parameter: Pointer): BOOL;
begin
with TCopyFileData(Parameter^)do
begin
Result := CopyFileEx(PChar(Source),PChar(Destination),
@CopyProgressRoutine, Parameter, nil, COPY_FILE_RESTARTABLE);
end;
end;

procedure TCopyFile.Start;
begin
if FHandle = 0 then
begin
IsStop := False;
FHandle := begin
Thread(nil,0,@ThreadFunc,@CopyFileData, CREATE_SUSPENDED,ThreadId);
ResumeThread(FHandle);
end;
end;

function TCopyFile.WaitFor : DWORD;
var
Msg: TMsg;
H: THandle;
begin
H := FHandle;
if GetCurrentThreadID = MainThreadID then
while MsgWaitForMultipleObjects(1, H, False, INFINITE,
QS_SENDMESSAGE) = WAIT_OBJECT_0 + 1do
PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE)
else
WaitForSingleObject(H, INFINITE);
GetExitCodeThread(H, Result);
end;

constructor TCopyFile.Create(const Source, Destination: string;
Progress : Thandle);
begin
IsStop := False;
CopyFileData.Source := Source;
CopyFileData.Destination := Destination;
CopyFileData.pCancel := @IsStop;
CopyFileData.hProgress := Progress;
end;

destructor TCopyFile.Destroy;
begin
if not IsStop then
Cancel;
inherited Destroy;
end;

procedure TCopyFile.Cancel;
begin
IsStop := True;
//WaitFor;
CloseHandle(FHandle);
FHandle := 0;
end;

{TFrom1}
procedure TForm1.Button2Click(Sender: TObject);
begin
CopyFile.Destroy;
Close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
CopyFile := TCopyFile.Create('E:/Vickwa/databak/20040230.bak',
'd:/20040230.bak',ProgressBar1.Handle);
CopyFile.Start;
end;

end.
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2483025
amli,你的加分贴。
 
后退
顶部