Array
(
)

copaindo arquivos e subpastas

Crcam
   - 20 mar 2006

boa tarde colegas

novamente estou com um dilema um tando dificil de resolver para uma operação simples...


eu fiz um programa que deve copiar todos os arquivos e subpastas de um determinado local p/ outro.( um backup so que sem compactar, é uma copia na integra)

e o processo é acompanhado por um gauge que informa a porcentagem decorrida

so que meu codigo está ignorando AS SUBPASTAS

alguem pode dar uma olhada e ver no que errei?

#Código


// copia public
procedure TForm1.BkpPublic(Sender: TObject);
var
DirPublicOrig,DirPublicDest:pchar;
a:integer;
begin

DirPublicOrig:=pchar(´C:\ORIGEM´);

DirPublicDest:=pchar(´E:\DESTINO);

for a:=0 to FileListBox_public.Items.Count do
begin
FileListBox_public.itemindex:=a;
Gauge_public.progress:=(a*100) div FileListBox_public.Items.Count;
copyfile(pchar(DirPublicOrig+´\´+ExtractFilename(FileListBox_public.FileName)),pchar(DirPublicDest+´\´+ExtractFilename(FileListBox_public.FileName)),true);
end;

end;
// fim copia public



Ipc$
   - 20 mar 2006

Utilize a função SHFileOperation que ela já coloca uma barra de progresso.


Martins
   - 20 mar 2006


Citação:
Utilize a função SHFileOperation que ela já coloca uma barra de progresso.


veja um exemplo:

#Código


uses ShellAPI;

procedure TForm1.Button1Click(Sender: TObject) ;
var
Fos : TSHFileOpStruct;
Buf : array[0..4096] of char;
p : pchar;
sDest : string;
begin
FillChar(Buf, sizeof(Buf), 0) ;
p := @buf;
p := StrECopy(p, ´C:\FirstFile.ext1´) + 1;
p := StrECopy(p, ´C:\SecondFile.ext2´) + 1;
StrECopy(p, ´C:\ThirdFile.ext3´) ;

sDest := ´e:\´;

FillChar(Fos, sizeof(Fos), 0) ;
with Fos do begin
Wnd := Handle;
{
FO_COPY
FO_DELETE
FO_MOVE
FO_RENAME
}
wFunc := FO_COPY;
pFrom := @Buf;
pTo := sDest;
fFlags := 0;
end;
if ((SHFileOperation(Fos) <> 0) or
(Fos.fAnyOperationsAborted <> false)) then
ShowMessage(´Cancelled´)
end;


Boa sorte Carlos


Martins
   - 20 mar 2006

Campos, olhe os códigos abaixo e estude-os.

#Código


uses
ShellApi;

function CopyDir(const fromDir, toDir: string): Boolean;
var
fos: TSHFileOpStruct;
begin
ZeroMemory(@fos, SizeOf(fos));
with fos do
begin
wFunc := FO_COPY;
fFlags := FOF_FILESONLY;
pFrom := PChar(fromDir + #0);
pTo := PChar(toDir)
end;
Result := (0 = ShFileOperation(fos));
end;


function MoveDir(const fromDir, toDir: string): Boolean;
var
fos: TSHFileOpStruct;
begin
ZeroMemory(@fos, SizeOf(fos));
with fos do
begin
wFunc := FO_MOVE;
fFlags := FOF_FILESONLY;
pFrom := PChar(fromDir + 0);
pTo := PChar(toDir)
end;
Result := (0 = ShFileOperation(fos));
end;

function DelDir(dir: string): Boolean;
var
fos: TSHFileOpStruct;
begin
ZeroMemory(@fos, SizeOf(fos));
with fos do
begin
wFunc := FO_DELETE;
fFlags := FOF_SILENT or FOF_NOCONFIRMATION;
pFrom := PChar(dir + #0);
end;
Result := (0 = ShFileOperation(fos));
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
if cCopyDir(´d:\download´, ´e:\´) = True then
ShowMessage(´Directory copied.´);
end;


Espero q possa te ajudar a implementar algo.

Boa sorte.


Crcam
   - 20 mar 2006

eu peço desculpa por não te me aprofundado nas normas de padronização

pois o metodo que vc indicou é semelhante com o uso de api

so que temos um padrão qualquer tipo de informação mesmo que seja o progresso de um processo deve estar alocado no form de onde foi gerada a operação
e o segundo fator negativo é se ele por algum motivo encontrar algum arquivo existente ele fica parado esperando uma ação do usuário só que não vai ter usuario monitorando isso


Ipc$
   - 20 mar 2006


Citação:
e o segundo fator negativo é se ele por algum motivo encontrar algum arquivo existente ele fica parado esperando uma ação do usuário só que não vai ter usuario monitorando isso
Isso vc pode resolver colocando em fFlags := FOF_NoConfirmation;

Não esqueça que pFrom é um array de strings e deve terminar com um #0 adicional. pTo também segue o mesmo.


Crcam
   - 20 mar 2006

mas sobre a janela fora do form?


Ipc$
   - 20 mar 2006


Citação:
hwnd
Handle of the dialog box to use to display information about the status of the operation.
Vc pode colocar o Handle do Form que a janela é exibida dentro dele.


Crcam
   - 20 mar 2006

não entendi bem o efeito final disso

vc tem algum demo p/ eu poder ver?


Crcam
   - 20 mar 2006

me corrija se esotu errado a outra opção que vc me falou seri auma janela flutuante so que centralizada no meu form.

isso?


Ipc$
   - 20 mar 2006

Isso mesmo, faça um teste:#Código

uses SehllApi;
procedure TForm1.Button1Click(Sender: TObject);
var SF:SHFILEOPSTRUCT;
begin
FillChar(SF, SizeOf(SF), 0);
SF.Wnd := Handle;
SF.wFunc := FO_Copy;
SF.pFrom := ´C:\Pasta_Origem\*.*´+#0;
SF.pTo := ´C:\Pasta_Destino´+0;
SF.fFlags := FOF_NoConfirmation;
SHFileOperation(SF);
end;



Ipc$
   - 20 mar 2006

Desculpe:#Código

uses ShellApi;



Crcam
   - 20 mar 2006

mas ai que está o problema isso é fora da padronização
não é que a janela esteja no centro ou não mas os recursos mesmo que seja o progressbar tem de pertencer ao form.


motivo pleo qual estou usando gauge pois em janelas apis ela vem com progress dis de onde vem p/ onde vai.


Crcam
   - 20 mar 2006

eu fiz o seu exemplo ele muito legal so que veja mais um problema imagine umas 30 pastas destintas...

como vai ficar esse form .

vc entende meu dilema não é que não tenho como fazer eu tenho codigos com api. o problema é como implmentar veja o codigo incial ele funcina será que eu não deixei nada fora por isso ele so pega arquivo e ignora subpastas....

ps: agradeço muito por estar tentando me ajudar pessoas como vc faz a diferença


Ipc$
   - 21 mar 2006

Acho que entendí; vc quer padronizar tendo seu objeto como Owner da operação e a função SHFileOperation não atende.
A função CopyFile só copia arquivos e não pastas. Eu não conheço, mas talvez alguém conheça outra função que copie pastas.

Até onde sei, utilizando o CopyFile, vc vai ter que criar uma função recursiva que varra as sub-pastas, criá-las no destino pelo CreateDir e depois utilizar o CopyFile para copiar os arquivos.

Espero que alguém tenha uma solução mais eficiente e possa lhe ajudar.