Pessoal, estou desenvolvendo um sistema que possui a seguinte situação:

Opções do menu carregam uma DLL que se encarrega de criar um
formulário dinâmicamente. Logo após tenho um objeto em uma outra unit
que possui funções para gerar os objetos visuais nesse
formulário.(tudo dinâmicamente)
Nesse formulário é criado um dbgrid onde é aberto uma tabela(de acordo
com a opção do menu principal) onde assim os dados são exibidos.
Algumas telas ficam lentas até carregar todos os dados da tabela, pois
algumas possuem milhares de registros, assim achamos melhor usar uma
thread para carregar essa tabela, assim o usuário abrir outro processo
no programa. 
Eu estou conseguindo abrir certinho na thread, mas não estou
conseguindo  atulizar alguns dados da tela como componentes que
mostram que os dados estão carrengando, e também não consigo verificar
quando a thread termina, pois quando ela passa la no evento
Syncronize(minhafuncaoexemplo) ele simplesmente para de executar a
thread e não passa pelo método (onTerminate). Exemplo abaixo:

função na DLL:


procedure ShowForm(NewApplication, NewScreen : Pointer; FormName :
String; Params : TStringList);

...

   oForm      := TForm.Create(Application.MainForm);
   oForm.Name := FormName;

   oMontaTela := Tmontar_tela.Create(oForm);
   oMontaTela._Montar_GRID(oDM.oSQLConnection,
Params.ValueFromIndex[viIdxCodTab],
Params.ValueFromIndex[viIdxMat],oForm);

...
end;



na unit que existe a classe Tmontar_tela

    TConsultaThread = class(TThread)
    private
      SessaoCritica: TCriticalSection;

    protected
      procedure Execute; override;
      procedure Atualiza;
    public
      oDataSource : TDataSource;
      Priority    : TThreadPriority;
      oQuery : TSQLQuery;
      oCDS : TClientDataSet;
      oMontatela : Tmontar_tela;
      I : integer;
    end;

...
...
...

    Tmontar_tela = class(TObject)
    private
      oThread : TConsultaThread;
      ...
    public
       function  RunThread(Query : TSQLQuery; CDS : TClientDataSet; DS
: TDataSource; MontaTela : Tmontar_Tela) : TConsultaThread;
       procedure ThreadTerminate(Sender: TObject);

procedure Tmontar_tela._ShowForm(Sender: TObject); //procedure
atribuída manualmente (onShow)
begin
   oThread := RunThread(SQLQ_DB2, CDS_DB2, DS_DB2, Self);

//   if not oThread.Terminated then begin
//     oThread.WaitFor;
//   end;

end;

...

function Tmontar_tela.RunThread(Query : TSQLQuery; CDS :
TClientDataSet; DS : TDataSource;                            
MontaTela : Tmontar_Tela) : TConsultaThread;
var
  oConsThread : TConsultaThread;
begin
  oConsThread                 := TConsultaThread.Create(True);
  oConsThread.FreeOnTerminate := True;
  oConsThread.Priority        := tpHigher;
  oConsThread.OnTerminate     := ThreadTerminate;
  oConsThread.oQuery          := Query;
  oConsThread.oCDS            := CDS;
  oConsThread.oDataSource     := DS;
  oConsThread.oMontatela      := MontaTela;
  oConsThread.Resume;

  Result := oConsThread;
end;


procedure TConsultaThread.Execute;
var
  oConn   : TSQLConnection;
begin
  oConn :=  nil;
  oConn  := TSQLConnection.Create(nil);

  with oConn do begin
      ... parâmetros de conexão
  end;

  oConn.Connected       := True;
  oQuery.SQLConnection  := oConn;

  Synchronize(Atualiza);
  oCDS.Close;
  oCDS.Open;
  Sleep(20);

end;

procedure TConsultaThread.Atualiza;
begin
  oMontatela._PainelStatus.Caption := 'carregando...';
end;

procedure Tmontar_tela.ThreadTerminate(Sender: TObject);
begin
  _PainelStatus.Caption := 'Pronto!...';
  Sleep(20);
  _PainelStatus.Visible := False;
  Application.ProcessMessages;
  Sender := nil;
end;


Desculpem a quantidade  código...

obrigado

Ricardo

Responder a