Avatar billede michael-schou Novice
19. august 2008 - 13:08 Der er 6 kommentarer og
1 løsning

Ang. ProgressBar - kroning (Fejl i eksempel).

Hej Igen - Spøgsmål rettet mest til kroning.

--------------------------------------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ProgressBar1: TProgressBar;
    ProgressBar2: TProgressBar;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure CopyFolder(src, dest : string );
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function CopyProgressRoutine(
    TotalFileSize : Int64;    // total file size, in bytes
    TotalBytesTransferred : Int64;    // total number of bytes transferred
    StreamSize : Int64;    // total number of bytes for this stream
    StreamBytesTransferred : Int64;    // total number of bytes transferred for this stream
    dwStreamNumber : DWORD;    // the current stream
    dwCallbackReason : DWORD;    // reason for callback
    hSourceFile : THandle;    // handle to the source file
    hDestinationFile : THandle;    // handle to the destination file
    lpData : pointer) : DWORD; stdcall; // passed by CopyFileEx
begin
  with Form1 do
  begin
    ProgressBar1.Max:=TotalFileSize;
    ProgressBar1.Position:=TotalBytesTransferred;
    ProgressBar1.Update;
    ProgressBar2.Position:=integer(lpData);
    ProgressBar2.Update;
    Label2.Caption:='Fil '+IntToStr(round((TotalBytesTransferred/TotalFileSize)*100));
    Label2.Update;
  end;
end;

procedure TForm1.CopyFolder(src, dest : string );
var
  fl : TStringList;
  i : integer;

procedure MakeList(src, dest : string);
var
  sts : Integer ;
  SR: TSearchRec;
begin
  sts := FindFirst(src + '*.*' , faAnyFile , SR );
  while sts = 0 do
  begin
    if ( SR.Name <> '.' ) and ( SR.Name <> '..' ) then
    begin
      if Pos('.', SR.Name) = 0 then
      begin
        {$I-}MkDir( dest + SR.Name );{$I+}
        MakeList( src + SR.Name + '\', dest + SR.Name+ '\' ) ;
      end
      else
        fl.Add(src + SR.Name+'='+dest + sr.name);
    end;
    sts:=FindNext( SR );
  end;
  FindClose( SR ) ;
end;

begin
  fl:=TStringList.Create;
  MakeList(src, dest);
  ProgressBar2.Max:=fl.Count;
  ProgressBar2.Position:=0;
  for i:=0 to fl.Count-1 do
  begin
    Label1.Caption:='Kopierer '+fl.Names[i]+' til '+fl.ValueFromIndex[i];
    Label1.Update;
    Label3.Caption:='Samlet '+IntToStr(Round(((i+1)/fl.Count)*100));
    Label3.Update;
    CopyfileEx(PChar(fl.Names[i]), pchar(fl.ValueFromIndex[i]), @CopyProgressRoutine, pointer(i), nil, 0);
  end;
  fl.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CopyFolder('C:\Temp\', 'D:\Temp\');
end;

end.

--------------------------------------------


Sidste gang jeg testede dit eksempel kroning så det ud til at virke som det skulle, men det gjorde det ikke alligvel :-)

Ville kopiere en mappe fra en disk til en anden ca. 8,5 GB (mange filer) når jeg gør dette opstår der 2 fejl :

1. Hvis disse linjer er slået til :
Form2.Label2.Caption := (IntToStr(round((TotalBytesTransferred/TotalFileSize)*100)));
Form2.Label2.Update;

Så får jeg fejlen : Exeception calss EInvalidOp with message "invalid floating point operation" - denne fejl opstår når jeg når til 55% i OverAll PrgressBar (ProgressBar2)

2. Når jeg slår de 2 linjer fra som den melder fejl i oppe i nr. 1 så ser det ud som om den kopiere det hele det gør den ikke desværre, det er ligesom om den springer noget over .. lidt øv.

Jeg har prøvet at rode med det men kan ikke lige hitte ud af hvad der sker - Hjælp :-)

Michael.
Avatar billede kroning Nybegynder
19. august 2008 - 13:51 #1
Mht. fejlen så er det nok fordi du har nogle filer på 0 bytes, brug dette:

if TotalFileSize>0 then
  Label2.Caption:='Fil '+IntToStr(round((TotalBytesTransferred/TotalFileSize)*100));

Mht. filer der mangler så kan det muligvis have noget at gøre med fil navnet, prøv at poster nogle navne på de filer der springes over.
Avatar billede michael-schou Novice
19. august 2008 - 13:54 #2
Jeg ser lige på det når jeg kommer hjem :-)
Avatar billede kroning Nybegynder
19. august 2008 - 14:24 #3
Jeg kan også se et problem med denne linie:
if Pos('.', SR.Name) = 0 then

der kan jo godt findes filer uden . og her vil der blive oprettet en mappe i stedet.
Avatar billede michael-schou Novice
20. august 2008 - 09:08 #4
Det hjalp med IF sætningen før Label2 så nu virker det, men den kopiere stadig ikke ikke alt over fra Dest1 til Dest2.

Denne her som du har lavet den virker helt fint :

---------------------------------

procedure ListFiles(var IniPath : string; st : TStringList);

procedure Start(Path : string);
var
    Rec    : TSearchRec;
  FR    : integer;
begin
    FR:=FindFirst(IniPath+Path+'*.*',faAnyFile    ,Rec);
    while FR=0 do
    begin
    if (Rec.Name<>'.') and (Rec.Name<>'..') then
    begin
          if ((Rec.Attr and faDirectory)=faDirectory) then
          Start(Path+Rec.Name+'\')
      else
        st.Add(Path+Rec.Name);
    end;
    FR:=FindNext(Rec);
    end;
    FindClose(Rec);
end;

begin
  IniPath:=IncludeTrailingPathDelimiter(IniPath);
    Start('');
end;

function CopyProgressRoutine(
    TotalFileSize : Int64;    // total file size, in bytes
    TotalBytesTransferred : Int64;    // total number of bytes transferred
    StreamSize : Int64;    // total number of bytes for this stream
    StreamBytesTransferred : Int64;    // total number of bytes transferred for this stream
    dwStreamNumber : DWORD;    // the current stream
    dwCallbackReason : DWORD;    // reason for callback
    hSourceFile : THandle;    // handle to the source file
    hDestinationFile : THandle;    // handle to the destination file
    lpData : pointer) : DWORD; stdcall; // passed by CopyFileEx
begin
  TProgressBar(lpData).Max:=TotalFileSize;
  TProgressBar(lpData).Position:=TotalBytesTransferred;
  TProgressBar(lpData).Update;
  Result:=PROGRESS_CONTINUE;
end;

procedure SyncFolders(Folder1, Folder2 : string;InfoLabel : TLabel;ProgressBar : TProgressBar);

procedure SyncFolder(F1, F2 : string; s1, s2 : TStringList);

function CopyFile(FromName, ToName : string) : boolean;
var
  pbCancel : BOOL;
begin
  pbCancel:=false;
  Result:=CopyFileEx(PChar(FromName),PChar(ToName),@CopyProgressRoutine,ProgressBar,@pbCancel,0);
end;

var
  i : integer;
  Path : string;
begin
  for i:=0 to s1.Count-1 do
    if s2.IndexOf(s1[i])=-1 then
    begin
      InfoLabel.Caption:=F1+s1[i];
      Application.ProcessMessages;
      if not CopyFile(F1+s1[i],F2+s1[i]) then
      begin
        Path:=ExtractFilePath(s1[i]);
        ForceDirectories(F2+Path);
        if not CopyFile(F1+s1[i],F2+s1[i]) then
          showmessage('Kan ikke kopiere '+s1[i]);
      end;
    end;
end;

var
  s1,s2 : TStringList;
begin
  s1:=TStringLIst.Create;
  s2:=TStringLIst.Create;

  ListFiles(Folder1, s1);
  ListFiles(Folder2, s2);

  SyncFolder(Folder1,Folder2,s1,s2);
  SyncFolder(Folder2,Folder1,s2,s1);

  s1.Free;
  s2.Free;
  InfoLabel.Caption:='Sync. afslutter';
end;


Smid en TLabel og en TProgressBar på din form og kald den således:

SyncFolders('c:\hk\test1','c:\hk\test2',Label1,ProgressBar1);

---------------------------------

Har prøvet at se om jeg selv kunne sætte en overAll progressbar (ProgressBar2) ind i dette eksempel - men det er ikke gået så godt :-)
Avatar billede kroning Nybegynder
20. august 2008 - 21:16 #5
Så burde det virke:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    ProgressBar1: TProgressBar;
    ProgressBar2: TProgressBar;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure CopyFolder(src, dest : string );
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function CopyProgressRoutine(
    TotalFileSize : Int64;    // total file size, in bytes
    TotalBytesTransferred : Int64;    // total number of bytes transferred
    StreamSize : Int64;    // total number of bytes for this stream
    StreamBytesTransferred : Int64;    // total number of bytes transferred for this stream
    dwStreamNumber : DWORD;    // the current stream
    dwCallbackReason : DWORD;    // reason for callback
    hSourceFile : THandle;    // handle to the source file
    hDestinationFile : THandle;    // handle to the destination file
    lpData : pointer) : DWORD; stdcall; // passed by CopyFileEx
begin
  with Form1 do
  begin
    ProgressBar1.Max:=TotalFileSize;
    ProgressBar1.Position:=TotalBytesTransferred;
    ProgressBar1.Update;
    ProgressBar2.Position:=integer(lpData);
    ProgressBar2.Update;
    if TotalFileSize>0 then
      Label2.Caption:='Fil '+IntToStr(round((TotalBytesTransferred/TotalFileSize)*100));
    Label2.Update;
  end;
end;

procedure TForm1.CopyFolder(src, dest : string );
var
  fl : TStringList;
  i : integer;
  Path : string;

procedure MakeList(src, dest : string);
var
  sts : Integer ;
  SR: TSearchRec;
begin
  sts := FindFirst(src + '*.*' , faAnyFile , SR );
  while sts = 0 do
  begin
    if ( SR.Name <> '.' ) and ( SR.Name <> '..' ) then
    begin
      if ((SR.Attr and faDirectory)=faDirectory) then
        MakeList( src + SR.Name + '\', dest + SR.Name+ '\')
      else
        fl.Add(src + SR.Name+'='+dest + sr.name);
    end;
    sts:=FindNext( SR );
  end;
  FindClose( SR ) ;
end;

begin
  fl:=TStringList.Create;
  MakeList(src, dest);
  ProgressBar2.Max:=fl.Count;
  ProgressBar2.Position:=0;
  for i:=0 to fl.Count-1 do
  begin
    Label1.Caption:='Kopierer '+fl.Names[i]+' til '+fl.ValueFromIndex[i];
    Label1.Update;
    Label3.Caption:='Samlet '+IntToStr(Round(((i+1)/fl.Count)*100));
    Label3.Update;
    Path:=ExtractFilePath(fl.ValueFromIndex[i]);
    if not DirectoryExists(Path) then
      ForceDirectories(Path);
    CopyfileEx(PChar(fl.Names[i]), pchar(fl.ValueFromIndex[i]), @CopyProgressRoutine, pointer(i), nil, 0);
  end;
  fl.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CopyFolder('C:\Temp\', 'D:\Temp\');
end;

end.
Avatar billede michael-schou Novice
21. august 2008 - 11:47 #6
Takker kroning - sætter stor pris på din hjælp!

Det virker Perfekt nu :-)

Smid et svar.
Avatar billede kroning Nybegynder
21. august 2008 - 14:01 #7
Fint
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester