Alguem saber pq o form nao fecha se fizer isso?

Delphi

02/10/2008

ola
Alguem saber pq o form nao fecha se fizer isso?

Façam o teste

Form1
=======================
Coloque um Timmer
Set a propriedade do Timer1.Enabled = False
No evento OnTimer coloque o codigo

var i : integer;
begin
Timer1.Enabled := False;
i := 1;
while i > 0 do
begin
Application.ProcessMessages;
end;
end;

Form2
=======================
Faca a chamada do Timer1 atraves do clique e um botao
form1.Timer1.Enabled := true;

Tente Fechar o Form2...
Ele nao fehca. se vc colocar um envento no OnClose do Form ele é disparado.. parece ser alguma coisa no envendo OnCloseQuery do form2.


Colerapunk

Colerapunk

Curtidas 0

Respostas

Emerson Nascimento

Emerson Nascimento

02/10/2008

não analisei profundamente nem fiz testes, mas creio que ele não fecha porque não consegue sair do loop.


GOSTEI 0
Wdrocha

Wdrocha

02/10/2008

Se o form2 fizer parte do projeto e o form1 for o form principal....

o form só fechará qdo ele sair do loop...assim como disse o amigo Emerson.en....é o loop q está impedindo o fechamento do form...


qualquer outra ação só será executada qdo o loop terminar....pq está é síncrona...


GOSTEI 0
Colerapunk

Colerapunk

02/10/2008

bom.. pelo q eu vi acho q o problema nao é p Loop..
pois no form2 as acoes ocorrem normalmente.
Tipo coloquei mais um botao com a acao de inserir linhas em um memo..
O loop esta em acao no form1 e cada vez q eu clico no botao no form2 ele insere a linha no Memo

Memo1.Lines.Add(´Inserindo linha´);

fiz outros testes tb.. tudo normal..
so o form q nao fecha


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

02/10/2008

agora fiz o teste seguindo o exemplo que você passou. o form2 fechou normalmente.

mas não tenho nada nos eventos OnClose e OnCloseQuery.


GOSTEI 0
Colerapunk

Colerapunk

02/10/2008

tb nao tenho nada em OnClose e OnCloseQuery
aki nao fechou..
Estou usando o Delphi7...


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

02/10/2008

o que não fecha é o form1, justamente por estar ´trancado´ no loop.

fiz o seguinte pra ilustrar isso...
criei a variável private i (ela não é mais local no OnTimer).
coloquei um botão no form1, que chama o form2, e outro que zera a variável (pra poder sair do loop).
no form2 coloquei um botão que liga o timer do form1, assim como você exemplificou.

ficou assim:
[size=18:5db7996556]- form1[/size:5db7996556]
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Button1: TButton; {caption: ´Abre Form2´} 
    Button2: TButton; {caption: ´i = 0´} 
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
    i: integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  form2.show;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  i := 0;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := False;
  i := 1;
  while i > 0 do
    Application.ProcessMessages;
end;


[size=18:5db7996556]- form2[/size:5db7996556]
type
  TForm2 = class(TForm)
    Button1: TButton; {caption: Habilita o timer}
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

uses Unit1;

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  Form1.Timer1.Enabled := true;
end;


clique no botão que abre o form2. depois, no form2, clique no botão que inicia o timer; feche o form2. deve fechar normalmente.

agora, no form1, clique no ´x´ para fechar o form. você notará que ele não fecha, justamente por estar esperando o loop finalizar. agora pressione o botão que zera a variável i. o form1 será fechado.

note que o form1 é o form principal da aplicação teste.


GOSTEI 0
Colerapunk

Colerapunk

02/10/2008

E ai emerson.en

Primeiro valeu por fazer os testes.
Parece coisa boba mas vou precisar disso em uma aplicacao q estou fazendo. Intao valeu pela dedicacao.

do jeito q vc fez esta ok..
Apenas faça a chamada do form2 com showmodal ou inves do Show

form2.showModal;

Ai q ta a diferença


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

02/10/2008

o resultado foi o mesmo com show ou com showmodal.


GOSTEI 0
Colerapunk

Colerapunk

02/10/2008

Nao pode ser rsss
de qualquer forma no meu Delphi7 o Form2 nao fecha com o Timer executando

bom.. vou deixar os fontes ´simples para caramba´
para quem quiser dar uma olhada e ver

http://rapidshare.com/files/150337896/teste_fecha_form.rar.html

Valew


GOSTEI 0
Paullsoftware

Paullsoftware

02/10/2008

Nao pode ser rsss de qualquer forma no meu Delphi7 o Form2 nao fecha com o Timer executando bom.. vou deixar os fontes ´simples para caramba´ para quem quiser dar uma olhada e ver http://rapidshare.com/files/150337896/teste_fecha_form.rar.html Valew
acho que para poder o seu laço parar você deve fazer um pequeno teste e dar um [b:5c7ec3d74b]break[/b:5c7ec3d74b] caso venha alguma interrupção, tipo

var i : integer;
begin
Timer1.Enabled := False;
i := 1;
while i > 0 do
begin
Application.ProcessMessages;
//variavel global ´Parar´ do tipo char...
if Parar = ´S´ then
Break;
end;
end;
acho que assim vai funcionar perfeitamente :wink:


GOSTEI 0
Colerapunk

Colerapunk

02/10/2008

Sim dessa forma vai funcionar..

Na verdade esse exemplo é uma parte do meu sistema de backup automatico funciona em minha aplicacao..

Dependendo de como o bkp é configurado o sistema dispara sua execucao em determinado dia e horario..
Neste loop eu fico monitorando a quantidade de conexões existentes com a base de dados..

Ex: O sistema ira executar o bkp automatico da base de dados. FDB.
No momento em que é disparado uma mensagem aparece na tela de todas as estacoes que estao com o programa aberto informando que o bkp será realizado e q o sitema sera fechado em 1 minuto.. Assim terão tempo para salvar o seu trabalho. Depois de 1 minuto o sistema fecha automaticamente. Isso pq algum usuario pode ter deixado o sistema aberto e foi almoçar rss

loge apos disporar a mensagem de 1 minuto para fechar entra no loop


while Dados.IB_Conexao.Users.Count > 1 do
begin
Application.ProcessMessages;
end;


dessa forma verifico qtos usuarios estao conetados na base.
Qdo tiver apenas 1 conexao (q seria ele proprio) o sistema desconecta da base. compacta o FDB. e volta a conexao..

O lance é se se o bkp for disparado e a aplicacao que disparou estiver em uma tela.. por exemplo de cadastro de cliente ele nao consegue fechar a tela.. por causa do loop..
O loop é disparado no form principal atraves de um Timer programado.

A grande questao é essa.. O loop foi disparado e o usuario estava na tela de cadastro de cliente.. ele nao consegue fechar a tela de cadasto de clientes...
Tudo isso acontece somente na maquina q diparou a execucao do bkp..
So queria q ele conseguisse fechar o form em que estivesse e voltar para a tela principal do sistema..

Estou tentando achar outras alternativas...

é isso ai..

att


GOSTEI 0
POSTAR