希望在数据库备份的同时显示一个进度条,当然进度条的步长是根据数据库的大小来确定的,所以不是那么贴切,但是比没有强。
  为了实现上面的功能,使用了一线程来更新进度条。可是,测试时发现,要等数据库备份完成后,这个线程才开始执行,并不是边备份,边更新进度条。是什么原因?代码:procedure TForm1.Button1Click(Sender: TObject);
var Thd: TestThd ;
begin
  Thd := TestThd.Create(false) ;
  adoCnn.Execute('BACKUP DATABASE Pubs TO  DISK =''C:\Test004.dat'' WITH INIT')  ;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
  adoCnn.Connected := true ;
end;end./////////////////////////////////////线程的代码,很简单测试用//////////////////////
unit Unit2;interfaceuses
  Classes,SysUtils,unit1;type
  TestThd = class(TThread)
  private
    { Private declarations }
    procedure UpdatePro ;
  protected
    procedure Execute; override;
  end;implementation{ TestThd }procedure TestThd.Execute;
begin
  FreeOnTerminate := true ;
  while Form1.ProgressBar1.Position <> Form1.ProgressBar1.Max   do
  begin
    Synchronize(UpdatePro)  ;
    Sleep(100) ;
  end ;
end;procedure TestThd.UpdatePro;
begin
  Form1.ProgressBar1.StepBy(5) ;
end;end.

解决方案 »

  1.   

    {数据备份、还原}
    unit WaitPas1;interfaceuses
      Classes, Windows, SysUtils, Dialogs, ADODB ;type
      WaitPas = class(TThread)
      Filename  : String;   //往线程中注入备份或还原的文件名
      Messages  : String;   //显示信息
      IDs       : Integer;   //识别应该执行什么样的操作
      ADOQ      : TADOQuery;
      //备份文件
      function BackUpData:Boolean;
      //还原文件
      function RevertData:Boolean;
      //关闭等待窗口
      procedure CloseWaitWindow;
      //更新等待窗口信息
      procedure PostMessgesToWaitWindow;
      private
        { Private declarations }
      protected
        procedure Execute; override;
      public
        constructor Create(CaseS: TADOQuery; FileNames:String;LoadID:integer);
      end;implementationuses Wait, Connect;{ WaitPas }function WaitPas.BackUpData:Boolean;
    begin
    Messages:='正在备份数据库,请稍候……';
    Synchronize(PostMessgesToWaitWindow);
    with ADOQ do try
       Close;
       SQL.Clear;
       SQL.Add('backup database 通迅录 to disk='+#39+FileName+#39+' WITH INIT');
       Prepared;
       Execsql;
       Result:=true;
    except
       Result:=false;
    end;end;procedure WaitPas.CloseWaitWindow;
    begin
    WaitForm.Close;
    end;constructor WaitPas.Create(CaseS: TADOQuery; FileNames: String; LoadID: Integer);
    begin
    //初始化进程
    IDs := LoadID;
    ADOQ := CaseS;
    FileName := FileNames;
    inherited Create(False);end;procedure WaitPas.Execute;
    var IsSucceed : Boolean;
    begin
    IsSucceed:=false;
    case IDs of
       1  :   IsSucceed := BackUpData; //备份
       2  :   IsSucceed := RevertData; //还原
    end;
      Synchronize(CloseWaitWindow);
      if IsSucceed then
         Messagebox(0,'数据库维护操作成功!','提示',MB_OK+MB_ICONINFORMATION+MB_TOPMOST)
      ELSE ShowMessage(ConnectForms.ShowError);
      { Place thread code here }
    end;procedure WaitPas.PostMessgesToWaitWindow;
    begin
    WaitForm.RzLabel1.Caption:=Messages;
    end;function WaitPas.RevertData: Boolean;
    begin
    Messages:='正在还原数据库,请稍候……';
    Synchronize(PostMessgesToWaitWindow);
    with ADOQ do try
       Close;
       SQL.Clear;
       sql.Add('use master');
       sql.Add('ALTER DATABASE 通迅录 SET OFFLINE WITH ROLLBACK IMMEDIATE');
       sql.Add('RESTORE DATABASE 通迅录 FROM DISK ='''+(FileName)+''' with FILE=1,RECOVERY,REPLACE');
       sql.Add('ALTER DATABASE 通迅录 SET ONLINE WITH ROLLBACK IMMEDIATE');
       SQL.Add('Use 通迅录');
       Prepared;
       execsql;
       Result:=true;
    except
       Result:=false;
    end;end;end.
      

  2.   

    unit OutToExcelUnit;interfaceuses
      Classes, windows, SysUtils;type
      OutToExcel = class(TThread)
      SentMsg : String;   //传递进程信息
      I1      : Integer;  //总数
      I2      : Integer;  //进度数
      procedure postMessages;  //传递信息
      procedure QueryMessage;  //显示过程
      procedure DoOutData;      //导出数据 
      private
        { Private declarations }
      protected
        procedure Execute; override;
      public
        constructor Create(Runing:Boolean);    
      end;implementationuses Progress, Comobj, DM;{ Important: Methods and properties of objects in visual components can only be
      used in a method called using Synchronize, for example,      Synchronize(UpdateCaption);  and UpdateCaption could look like,    procedure OutToExcel.UpdateCaption;
        begin
          Form1.Caption := 'Updated in a thread';
        end; }{ OutToExcel }constructor OutToExcel.Create(Runing: Boolean);
    begin
      SentMsg:='正在准备将数据导出到Excel,请稍候…………';
      Synchronize(postMessages);
      ProgressForm.RzProgressBar1.Percent:=0;
    inherited Create(Not Runing);
    end;procedure OutToExcel.DoOutData;
    var
       exls,sheet    : variant;
       fieldNum,I,j  : integer;
       S,S2          : String;
    begin
      try
        exls:=createoleobject('Excel.application');
        sheet:=createoleobject('excel.sheet');
      except
        Messagebox(handle,'未发现系统中安装了Microsoft Excel,在使用该功能前,请先将其安装!','错误',mb_ok+mb_iconwarning);
        Exit;
      end;
    try
       sheet:=exls.workBooks.add;
       Exls.worksheets[1].range['A1:L1'].Merge(True);
       Exls.Cells[1,1].value:='我的通迅录';
       Exls.Cells[1,1].Font.Size:=30;
       ExLs.worksheets[1].Range['A1:L1'].Font.Name := '楷体_GB2312';
       //第一行高39
       Exls.worksheets[1].Rows[1].RowHeight := 39;
       with DM1.ADODataSet1 do try
         DisableControls;
         I1:=RecordCount;
         FieldNum:=FieldCount;
         for i:=1 to FieldNum-2 do begin
            Exls.Cells[2,i].value:=FieldDefList.Strings[i-1];
            Exls.Cells[2,i].Font.Size:=9;
         end;
         Exls.Cells[2,1].ColumnWidth:=10;
         Exls.Cells[2,2].ColumnWidth:=12;
         Exls.Cells[2,3].ColumnWidth:=10;
         Exls.Cells[2,4].ColumnWidth:=10;
         Exls.Cells[2,5].ColumnWidth:=10;
         Exls.Cells[2,6].ColumnWidth:=23;
         Exls.Cells[2,7].ColumnWidth:=10;
         Exls.Cells[2,8].ColumnWidth:=23;
         Exls.Cells[2,9].ColumnWidth:=23;
         Exls.Cells[2,10].ColumnWidth:=18;
         Exls.Cells[2,11].ColumnWidth:=8;
         Exls.Cells[2,12].ColumnWidth:=40;
         First;
         SentMsg:='正在将数据导出到Excel,请稍候…………';
         Synchronize(postMessages);
         i:=3;
         while not eof do begin
           I2:=I-2;
           Synchronize(QueryMessage);
           for j:=1 to fieldNum-2 do  begin
             exls.Cells[i,j]:=fields[j-1].AsString;
             exls.Cells[i,j].Font.Size:=9;      //设置字体为小五
           end;
         next;
         i:=i+1;
         end;
         EnableControls ;
        //为表格加入边框
        S:='A2:L'+IntToStr(RecordCount+2);
        S2:='A2:L'+IntToStr(RecordCount+2);
        Exls.worksheets[1].Range[S].Borders.LineStyle := 1;
        //设置文字垂直、水平居中
        ExlS.worksheets[1].range[S2].HorizontalAlignment := $FFFFEFF4;
        ExlS.worksheets[1].range[S2].VerticalAlignment := $FFFFEFF4;     //加粗第1、2行文字
         Exls.Cells[1,1].Font.Bold:=true;
         Exls.worksheets[1].Rows[2].Font.bold:=true;
         //加入一行作者信息]
         S:='A'+IntToStr(RecordCount+4)+':L'+IntToStr(RecordCount+4);
         Exls.worksheets[1].range[S].Merge(True);
         Exls.Cells[(RecordCount+4),1].value:='“我的通迅录”,作者:李栋;E-Mail:[email protected]';
         Exls.Cells[(RecordCount+4),1].Font.Size:=9;
         Exls.Cells[RecordCount+4,1].Font.Bold:=true;
         //显示Excel
         exls.visible:=true;
       except
         Messagebox(handle,'数据导出到Excel时,发生意外失败。请稍候再试!','错误',MB_OK+MB_ICONERROR);
         Exit;
       end;
    except
       Messagebox(handle,'将数据导出到Excel失败!请稍候再试!','错误',mb_ok+mb_iconerror);
    end;
    end;procedure OutToExcel.Execute;
    begin
      { Place thread code here }
      try
         DoOutData;
      finally
         Progressform.Close;
      end;
    end;procedure OutToExcel.postMessages;
    begin
    ProgressForm.RzGroupBox1.Caption:=SentMSG;
    end;procedure OutToExcel.QueryMessage;
    begin
    progressForm.RzProgressBar1.Percent:=round(100*(i2/i1));
    end;end.//////以上是www.delphibox.com上别人的代码,自己参考一下吧....
      

  3.   

    gxgyj(杰克.逊):谢谢 !
    不过,我的目的是在执行下面的Sql语句的同时(因为备份、恢复可能需要较长时间)更新进度条,如果只需要显示 '正在备份数据库,请稍候……' 就不需要这么复杂了:)。
    SQL.Add('backup database 通迅录 to disk='+#39+FileName+#39+' WITH INIT');
      

  4.   

    解决了,建两个线程,进度条更新和数据库备份都在单独的进程中完成就可以了。
    谢谢 gxgyj(杰克.逊) 的启发!
      

  5.   

    Synchronize(UpdatePro)
    这个东东实际上是在主线程里执行的,而主线程都去backup了,自然没有CPU时间了