En tu caso, tu código:
Código Delphi
[-]
procedure TThread1.Execute;
var
begin
...
form1.button4.enabled:= true;
...
end;
Debe quedar similas a este:
Código Delphi
[-]
...
procedure TThread1.UpdateEdit();
var
begin
...
form1.button4.enabled:= true;
...
end;
procedure TThread1.Execute;
var
begin
...
Synchronize(UpdateEdit);
...
end;
Esto significa que ese código (UpdateEdit) se ejecutará de forma excluyente, para que no de problemas.
CONCLUSIÓN: Si utilizamos muchos Synchronize dentro de un thread es malo, porque continuamente estamos utilizando código "excluyente", por lo que la "gracia" del thread se pierde. De ahí que el Synchronize deba utilizarse para las cosas imprescindibles.