Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 10-04-2008
Avatar de Black_Ocean
Black_Ocean Black_Ocean is offline
Miembro
 
Registrado: nov 2006
Posts: 128
Poder: 18
Black_Ocean Va por buen camino
Ayuda: Necesito refrescar la aplicación MIENTRAS se copian archivos muy grandes

Hola estimados colegas de ClubDelphi,

Necesito que me echen una pequeña ayuda,

Pasa que las funciones CopyFile y SHFileOperation solo me refrescan el formulario después de haber terminado el copiado de un archivo, es decir:

Código Delphi [-]
  CopyFile(PChar('C:\Ejemplo_fuente.exe'), PChar('C:\Ejemplo_destino.exe'), False);
  Application.ProcessMessages;

Esta función es muy pobre y no sirve, puesto que MIENTRAS el copiado está en progreso, el formulario igual es inaccesible e innoperable (por ejemplo, con archivos muy grandes que toman más tiempo en copiarse).

En el caso con SHFileOperation, se refresca la UI de la API de Windows (el diálogo que se muestra cuando el flag es especificado), pero yo no quiero mostrar un diálogo de copiado de esa API, sino que un formulario que yo mismo hice para mostrar el progreso (esto es el progreso en bytes), pero, el problema es que MIENTRAS se está copiando un archivo grande (por ejemplo, de 300 MB). La aplicación queda congelada y el usuario no puede mover el formulario. Sólo cuando termina de copiar se refresca por la especificación de Application.ProcessMessages en la siguiente línea, pero cuando comienza a copiar otro archivo grande, nuevamente hay que esperar a que termine el copiado para que el formulario reaccione.

¿Cómo se puede solucionar este problema en forma eficiente, sin componentes, etc?

Saludos y de antemano gracias amigos como siempre.

Última edición por Black_Ocean fecha: 10-04-2008 a las 03:44:23.
Responder Con Cita
  #2  
Antiguo 10-04-2008
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Hola amigo

Lo que pasa es que el ProcessMessage esta sin efecto ya que eso se usa para rutinas de loop, yo creo que se podria hacer algo como leer por bloques y copiarlos al otro archivo y en ese loop si tendría efecto el ProcessMessage.

Salud OS
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #3  
Antiguo 10-04-2008
Avatar de Black_Ocean
Black_Ocean Black_Ocean is offline
Miembro
 
Registrado: nov 2006
Posts: 128
Poder: 18
Black_Ocean Va por buen camino
Cita:
Empezado por egostar Ver Mensaje
Hola amigo

Lo que pasa es que el ProcessMessage esta sin efecto ya que eso se usa para rutinas de loop, yo creo que se podria hacer algo como leer por bloques y copiarlos al otro archivo y en ese loop si tendría efecto el ProcessMessage.

Salud OS
Gracias por tu respuesta,

Si me pudieras explicar y enseñar un poco aquello que me dices te lo agradecería bastante.

De antemano, gracias.

Última edición por Black_Ocean fecha: 10-04-2008 a las 03:54:34.
Responder Con Cita
  #4  
Antiguo 10-04-2008
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Bueno en la ayuda de delphi viene este ejemplo

Código Delphi [-]
var
  FromF, ToF: file;
  NumRead, NumWritten: Integer;
  Buf: array[1..2048] of Char;
begin
  if OpenDialog1.Execute then                               { Display Open dialog box }
  begin
    AssignFile(FromF, OpenDialog1.FileName);
    Reset(FromF, 1);  { Record size = 1 }
    if SaveDialog1.Execute then                              { Display Save dialog box}
    begin
      AssignFile(ToF, SaveDialog1.FileName);  { Open output file }

      Rewrite(ToF, 1);  { Record size = 1 }
      Canvas.TextOut(10, 10, 'Copying ' + IntToStr(FileSize(FromF))
        + ' bytes...');
      repeat
        BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
        BlockWrite(ToF, Buf, NumRead, NumWritten);
        Application.ProcessMessages; //Aquí lo pondría yo 
      until (NumRead = 0) or (NumWritten <> NumRead);
        CloseFile(FromF);
        CloseFile(ToF);
    end;
  end;
end;

Lo que no se es como se comportaria en tiempo de copiado, es cosa de que lo pruebes.

Salud OS
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #5  
Antiguo 10-04-2008
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
La solución mas natural, me parece, es el uso de CopyFileEx, que permite introducir una función CallBack, que será llamada constantemente de vuelta por la rutina de copia a través de la que el proceso que llama (tu aplicación) es notificada del avance de la copia.

Entonces, podrías actualizar la interfaz de usuario para reportar el progreso de la copia.

Por otro lado, si lo que querés es que la aplicación siga utilizándose mientras la copia se realiza, podes lanzarla en otro hilo.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #6  
Antiguo 10-04-2008
Khronos Khronos is offline
Miembro
 
Registrado: abr 2007
Posts: 298
Poder: 18
Khronos Va por buen camino
Yo creo que se puede solucionar mucho mejor con un thread.

Código Delphi [-]
type
   TCopyThread = class (TThread)
       protected
        procedure execute; override;
   end;
 
var
Copiar: TCopyThread;
 
implementation
 
procedure TCopyThread.execute;
begin
Copiar.FreeOnTerminate:=true;
 
CopyFile(PChar('C:\Ejemplo_fuente.exe'), PChar('C:\Ejemplo_destino.exe'), False);
end;
Añades esto en tu formulario. Para ejecutarlo:

Código Delphi [-]
begin
Copiar:= TCopyThread.create(true);
Copiar.execute;
end;

Salu2 espero que te sirva.
Responder Con Cita
  #7  
Antiguo 10-04-2008
Avatar de cHackAll
[cHackAll] cHackAll is offline
Baneado?
 
Registrado: oct 2006
Posts: 2.159
Poder: 20
cHackAll Va por buen camino
Código Delphi [-]
function Thread(hWnd: Cardinal): Cardinal; stdcall;
begin
 CopyFile('C:\Ejemplo_fuente.exe', 'C:\Ejemplo_destino.exe', False);
 SendMessage(hWnd, WM_USER, 0, 0);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
 CreateThread(nil, 0, @Thread, Pointer(Handle), 0, PDWORD(0)^);
end;

Tu aplicación recivirá el mensaje WM_USER cuando la copia finalice (ejemplo).

Quien dá mas??

Saludos
Responder Con Cita
  #8  
Antiguo 10-04-2008
Avatar de Black_Ocean
Black_Ocean Black_Ocean is offline
Miembro
 
Registrado: nov 2006
Posts: 128
Poder: 18
Black_Ocean Va por buen camino
Gracias a todos por su ayuda. Probaré los métodos que me han señalado.

Saludos y como siempre muy amables
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Necesito ayuda para recuperar unos archivos ddd_ddd Varios 2 24-10-2007 15:49:26
Necesito ayuda con indices .ndx para archivos dbf dinover7 Conexión con bases de datos 1 21-05-2007 21:41:34
Necesito crear una aplicacion.... ayuda please Enable Varios 8 10-09-2006 17:51:01
Necesito ayuda para manerjar archivos meosre Varios 2 08-09-2005 18:37:34
Hola Es mi primer mensaje en este Foro y necesito ayuda para archivos XML Juan_Carlos_P Gráficos 2 08-08-2005 19:11:17


La franja horaria es GMT +2. Ahora son las 13:05:41.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi