首先我申明,等了很久前面都没有人关注,现在无奈急着要完成任务就又开了一贴.(我把问题写得具体一些了.)
程序是由idhttp来下载东西,原来的程序是用idhttp控件,现在我想把原来的代码改成多线程的(大致代码如下):
我把我的代码都贴上来,希望你们帮忙一下!谢谢..线程单元主要代码如下:constructor TThreadHttp.create(myurl: string);
begin
inherited Create(false);
aURL:=myurl;
end;procedure TThreadHttp.Execute;
var
tStream: TFileStream;
aFile : string;
IdHTTP1 : TIdHttp; //定义
begin
FreeOnTerminate:=true;
IdHTTP1:=TIdHTTP.Create(nil); //动态创建idhttp1
aFile:=GetURLFileName(aURL); //得到url最后文件名:如:如:http://localhost/aa/bb.exe,得到bb.exe
if FileExists(aFile) then tStream := TFileStream.Create(aFile, fmOpenWrite)
else tStream := TFileStream.Create(aFile, fmCreate);
IdHTTP1.Request.ContentRangeStart := 0;
try
IdHTTP1.Get(aURL, tStream);
except
showmessage('请检查网络!');
tStream.Free;
IdHTTP1.Disconnect;
Exit;
end;
tStream.Free;
IdHTTP1.Disconnect;
end;主窗体单元主要代码如下:
procedure TUpdatefrm.sbnstartClick(Sender: TObject); //下载按钮事件
var
XMLDocument :IXMLDocument;
XMLNode :IXMLNode;
i,j:integer;
Node_name:string;
ThreadDown1: TThreadHttp; //定义
begin
XMLDocument:=TXMLDocument.Create('http://aaa/aa/newversion.xml');
XMLDocument.Active;
XMLNode := XMLDocument.DocumentElement;
for i:=0 to XMLNode.ChildNodes.Count-1 do //循环得到要下载的值并下载(这里的关于xml循环的代码我觉得写不好.)
begin
XMLNode := XMLDocument.DocumentElement;
XMLNode:=XMLNode.ChildNodes.Nodes[i];
if strtoint(XMLNode.Attributes['date'])>strtoint(nowversion_date) then //如果有新版本则下载
begin
Node_name:=XMLNode.NodeValue;
ThreadDown1:=TThreadHttp.Create('http://aaa/aa/Down_Data/'+Node_name);
end;
end;
end;以上代码可以行的通,但是下面的代码是原来没有加线程之前写的,现在要怎么改?
主窗体里有个progressbar,在没有弄成多线程时的代码如下:
procedure TUpdatefrm.IdHTTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
ProgressBar1.Position:=ProgressBar1.Max;
end;procedure TUpdatefrm.IdHTTP1Status(ASender: TObject;const AStatusText: String);
begin
Memo_Update.Lines.Add(AStatusText);
end;procedure TUpdatefrm.IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
begin
ProgressBar1.Position:=AWorkCount;
end; procedure TUpdatefrm.IdHTTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCountMax: Integer);
begin
ProgressBar1.Max:=AWorkCountMax;
ProgressBar1.Min:=0;
ProgressBar1.Position:=0;
end;
其中newversion.xml的文件如下:
<version ver="5.5.5.5">
<Item1 date="20061205">a.exe</Item1>
<Item2 date="20061205">b.xml</Item2>
<Item3 date="20061205">c.txt</Item3>
</version>改成了多线程后,我要把上面关于进度条的代码改一起用起来.应该怎么改?
程序是由idhttp来下载东西,原来的程序是用idhttp控件,现在我想把原来的代码改成多线程的(大致代码如下):
我把我的代码都贴上来,希望你们帮忙一下!谢谢..线程单元主要代码如下:constructor TThreadHttp.create(myurl: string);
begin
inherited Create(false);
aURL:=myurl;
end;procedure TThreadHttp.Execute;
var
tStream: TFileStream;
aFile : string;
IdHTTP1 : TIdHttp; //定义
begin
FreeOnTerminate:=true;
IdHTTP1:=TIdHTTP.Create(nil); //动态创建idhttp1
aFile:=GetURLFileName(aURL); //得到url最后文件名:如:如:http://localhost/aa/bb.exe,得到bb.exe
if FileExists(aFile) then tStream := TFileStream.Create(aFile, fmOpenWrite)
else tStream := TFileStream.Create(aFile, fmCreate);
IdHTTP1.Request.ContentRangeStart := 0;
try
IdHTTP1.Get(aURL, tStream);
except
showmessage('请检查网络!');
tStream.Free;
IdHTTP1.Disconnect;
Exit;
end;
tStream.Free;
IdHTTP1.Disconnect;
end;主窗体单元主要代码如下:
procedure TUpdatefrm.sbnstartClick(Sender: TObject); //下载按钮事件
var
XMLDocument :IXMLDocument;
XMLNode :IXMLNode;
i,j:integer;
Node_name:string;
ThreadDown1: TThreadHttp; //定义
begin
XMLDocument:=TXMLDocument.Create('http://aaa/aa/newversion.xml');
XMLDocument.Active;
XMLNode := XMLDocument.DocumentElement;
for i:=0 to XMLNode.ChildNodes.Count-1 do //循环得到要下载的值并下载(这里的关于xml循环的代码我觉得写不好.)
begin
XMLNode := XMLDocument.DocumentElement;
XMLNode:=XMLNode.ChildNodes.Nodes[i];
if strtoint(XMLNode.Attributes['date'])>strtoint(nowversion_date) then //如果有新版本则下载
begin
Node_name:=XMLNode.NodeValue;
ThreadDown1:=TThreadHttp.Create('http://aaa/aa/Down_Data/'+Node_name);
end;
end;
end;以上代码可以行的通,但是下面的代码是原来没有加线程之前写的,现在要怎么改?
主窗体里有个progressbar,在没有弄成多线程时的代码如下:
procedure TUpdatefrm.IdHTTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
ProgressBar1.Position:=ProgressBar1.Max;
end;procedure TUpdatefrm.IdHTTP1Status(ASender: TObject;const AStatusText: String);
begin
Memo_Update.Lines.Add(AStatusText);
end;procedure TUpdatefrm.IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
begin
ProgressBar1.Position:=AWorkCount;
end; procedure TUpdatefrm.IdHTTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCountMax: Integer);
begin
ProgressBar1.Max:=AWorkCountMax;
ProgressBar1.Min:=0;
ProgressBar1.Position:=0;
end;
其中newversion.xml的文件如下:
<version ver="5.5.5.5">
<Item1 date="20061205">a.exe</Item1>
<Item2 date="20061205">b.xml</Item2>
<Item3 date="20061205">c.txt</Item3>
</version>改成了多线程后,我要把上面关于进度条的代码改一起用起来.应该怎么改?
uses Forms, Messages,...const
WM_WorkBegin = WM_User+1;
WM_Work = WM_User+2;
WM_WorkEnd = WM_User+3;
WM_Status = WM_User+4;type
TStatus = packed record
Text: string[255]
end;
PTStatus = ^TStatus; TThreadHttp = class(TThread)
private
......
procedure WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer);
procedure Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
procedure WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
procedure TThreadHttp.Status(ASender: TObject;const AStatusText: String);
......
protected
public
end;implement procedure TThreadHttp.WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
PostMessage(Application.MainForm.Handle, WM_WorkEnd, 0, 0);
end;procedure TThreadHttp.Work(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
begin
PostMessage(Application.MainForm.Handle, WM_Work, AWorkCount, 0);
end;procedure TThreadHttp.WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCountMax: Integer);
begin
PostMessage(Application.MainForm.Handle, WM_WorkBegin, AWorkCountMax, 0);
end; procedure TThreadHttp.Status(ASender: TObject;const AStatusText: String);
var
Status: PTStatus;
begin
New(Status);
Status^.Text := AStatusText;
PostMessage(Application.MainForm.Handle, WM_Status, Integer(Status), 0);
end;procedure TThreadHttp.Execute;
var
tStream: TFileStream;
aFile : string;
IdHTTP1 : TIdHttp; //定义
begin
FreeOnTerminate:=true;
IdHTTP1:=TIdHTTP.Create(nil);
..................加入代码
IdHTTP1.OnWorkBegin := WorkBegin;
IdHTTP1.OnWork := Work;
IdHTTP1.OnWorkEnd := WorkEnd;
IdHTTP1.OnStatus := Status;
........................
................主窗体加入代码
uses 线程单元 procedure WMWorkBegin(var Message: TMessage); Message WM_WorkBegin;
procedure WMWork(var Message: TMessage); Message WM_Work;
procedure WMWorkEnd(var Message: TMessage); Message WM_WorkEnd;
procedure WMStatus(var Message: TMessage); Message WM_Status;.............................
procedure WMWorkBegin(var Message: TMessage); Message WM_WorkBegin;
begin
ProgressBar1.Max := Message.WParam;
ProgressBar1.Min := 0;
ProgressBar1.Position := 0;
end; procedure WMWork(var Message: TMessage); Message WM_Work;
begin
ProgressBar1.Position := Message.WParam;
end; procedure WMWorkEnd(var Message: TMessage);
begin
ProgressBar1.Position:=ProgressBar1.Max;
end; procedure WMStatus(var Message: TMessage); Message WM_Status;
begin
Memo_Update.Lines.Add(PTStatus(Message.WParam)^.Text);
end;
..........PS: 尽量不要用Synchronize去同步,效率很低
但是我按你的方法做了,主窗体的"Message"有错误,编绎时提示:Unknown directive :'Message'是不是哪里没有定义?在线等..