首先我申明,等了很久前面都没有人关注,现在无奈急着要完成任务就又开了一贴.(我把问题写得具体一些了.)
程序是由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>改成了多线程后,我要把上面关于进度条的代码改一起用起来.应该怎么改?  

解决方案 »

  1.   

    很好办的. ..........线程里面加入如下代码
    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去同步,效率很低
      

  2.   

    主窗体的消息处理过程全部放在private段
      

  3.   

    好厉害啊(要好好学习)!谢谢老冯!
    但是我按你的方法做了,主窗体的"Message"有错误,编绎时提示:Unknown directive :'Message'是不是哪里没有定义?在线等..
      

  4.   

    呵呵.奇怪的错误. Unknown directive :'Message'= 未知的编译指示器 'message'.  奇怪奇怪真奇怪.
      

  5.   

    哈哈哈哈,我模拟出来了.你在MESSAGE前面也就是过程后面没有加;号
      

  6.   

    老冯!要怎么改啊?我对Message一点也不懂啊!只想先完成任务再去掌握一下知识点.