Ver Mensaje Individual
  #8  
Antiguo 05-12-2014
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.331
Reputación: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por danielmj Ver Mensaje
Código Delphi [-]
procedure TThread1.Execute;
var
begin
...
form1.button4.enabled:= true;
...
end;
Bueno, viendo esa línea te diría que es normal el error.
Hay que tener claro que la VCL de por sí, no es "Thread-safe". Eso se traduce en que desde dentro de un hilo no puedes acceder "alegremente" a componentes y código que tengas fuera de él.

Es decir, desde dentro del hilo, NO PUEDES llamar "directamente" a un botón del formulario (Form1.Button4.Enabled).

Lo ideal es que los hilos se utilicen para relizar procesos que no inviolucren elementos visuales, como son formularios, componentes,...
Está claro que en algunos casos debemos modificarlos, por ejemplo, una barra de progreso para indicar el estado, labels, o si es el caso, el botón4 del form1.
Si esto es necesario, está contemplado y para ello está el método Synchronize.

Como te he dicho la VCL no es "thread-safe" por lo tanto tenemos que asegurarnos que cuendo accedemos desde el thread a "elementos externos" lo hagamos de forma exclusiva. Para eso sirve el Synchronize.

Aquí tienes algún ejemplo:

Y aquí en mi página un par más:
http://neftali.clubdelphi.com/?p=146
http://neftali.clubdelphi.com/?p=149

Me centro en estos ultimos para explicarte lo que más arriba apunto.

En el primero de los ejemplo, hay varios componentes del fiormulario que se deben modificar (similar a lo que haces tú con el edit).
Verás que en el thread NO SE LLAMA directamente a este código:

Código Delphi [-]
  // Incrementar un progressbar del formulario
  pb.Position := (pb.Position + FStep) MOD 100;

O a este otro:

Código Delphi [-]
  // Cambiar el color de un panel del formulario
  FColor := RGB(Random(255), Random(255), Random(255));
  pnb.Color := FColor;

Hay que colocarlos en un procedimiento y llamarlos con el método anterior; Así el código resultante es algo así:

Código Delphi [-]
procedure TPanelColorThread.ChangeColor;
begin
  FColor := RGB(Random(255), Random(255), Random(255));
  pnb.Color := FColor;
end;

...

  // La llamada
  while true do begin
    Synchronize(ChangeColor);
  end;

Y en el caso del progressbar, es algo similar.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita