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