Log de Erro - Capturar nome do Formulário.
[b:4ac1a04776]Descrição do Problema:[/b:4ac1a04776]
Estou utilizando uma função para criar um arquivo texto sempre que ocorrer um erro(exceção) na aplicação.
Neste arquivo texto gravo o erro, a data e hora do erro, contudo não sei como capturar e escrever no arquivo texto [u:4ac1a04776]em qual formulário o erro aconteceu[/u:4ac1a04776] o que é de extrema importância na hora de realizar o ´reparo´ na aplicação.
Desde já agradeço a Atenção de Todos
Estou utilizando uma função para criar um arquivo texto sempre que ocorrer um erro(exceção) na aplicação.
Neste arquivo texto gravo o erro, a data e hora do erro, contudo não sei como capturar e escrever no arquivo texto [u:4ac1a04776]em qual formulário o erro aconteceu[/u:4ac1a04776] o que é de extrema importância na hora de realizar o ´reparo´ na aplicação.
Desde já agradeço a Atenção de Todos
Lnunes
Curtidas 0
Respostas
Facc
25/10/2005
vc tentou com Nome_Formulário.Caption?
GOSTEI 0
Lnunes
25/10/2005
Facc agradeço primeiramente a sua atenção mas o problema é que esta função fica em um evento do componente application event no formulário principal destinado a capturar qualquer execeção que ocorra no sistema sendo assim se eu utiliza-se o Nome_Formulário.Caption iria sempre capturar o nome do formulário principal e não do formulário onde realmente o erro aconteceu.
GOSTEI 0
Facc
25/10/2005
esse código que vc criou, ´varre´ o código de todos os formulários? Se sim, não seria o caso de vc criar uma váriavel que receba o nome do formulário?
GOSTEI 0
Martins
25/10/2005
Facc agradeço primeiramente a sua atenção mas o problema é que esta função fica em um evento do componente application event no formulário principal destinado a capturar qualquer execeção que ocorra no sistema sendo assim se eu utiliza-se o Nome_Formulário.Caption iria sempre capturar o nome do formulário principal e não do formulário onde realmente o erro aconteceu.
Desculpe lhe perguntar isso mas, como essa rotina tá pegando esses exceptions, e vc não poderia capturar o nome do objeto (Form)?
Nunca fiz nada igual, apenas uma idéia!!
Boa Sorte
GOSTEI 0
Lnunes
25/10/2005
A ideia é justamente esta criar uma variável string e carrega-la com o nome do formulário que apresentou o erro mas eu não tenho ideia de como carrega-la.
GOSTEI 0
Facc
25/10/2005
A ideia é justamente esta criar uma variável string e carrega-la com o nome do formulário que apresentou o erro mas eu não tenho ideia de como carrega-la.
tente criar ela no Form Principal na parte de Public, daí nos demais Forms vc colocaria (veja o local mais apropriado) pra receber o nome do form
FPrincipal.VForm := NomeFormulario.Caption
e na rotina onde grava os erros, vc passaria a variável
nunca fiz isso, é uma idéia
GOSTEI 0
Lnunes
25/10/2005
Facc obrigado pela a dica vou tentar agora e mais tarde posto uma resposta informado se o código funcionou ou não.
Desde já agradeço a atenção de todos.
Desde já agradeço a atenção de todos.
GOSTEI 0
Lnunes
25/10/2005
A utilização da variável neste caso funciona mas acaba dando muito trabalho.
descobrir que a solução mas adequada é utilizar o getactivewindow(não sei se escrevi corretamente) para capturar o nome do formulário.
Obrigado a todos pela ajuda.
descobrir que a solução mas adequada é utilizar o getactivewindow(não sei se escrevi corretamente) para capturar o nome do formulário.
Obrigado a todos pela ajuda.
GOSTEI 0
Facc
25/10/2005
A utilização da variável neste caso funciona mas acaba dando muito trabalho.
descobrir que a solução mas adequada é utilizar o getactivewindow(não sei se escrevi corretamente) para capturar o nome do formulário.
Obrigado a todos pela ajuda.
e aí cara... funcionou desse jeito que vc falou? com o comando GetActiveWindow? Pois se traduzindo ao pé da letra, o comando pega o nome da tela ativa... e pelo que eu entendi, vc quer que retorne o possível erro no exato momento que vc chama o Form Principal, seria isso?
GOSTEI 0
Braytiner Heggendorn
25/10/2005
Tente usar o objeto Screen do Delphi para obter o nome do controle e do formulário atual
GOSTEI 0
Thomaz_prg
25/10/2005
tenta aí fazer um for usando o objeto screen (como dito pelo colega).
For i:= 0 to Screen.Forms.Count -1 do
Para pegar o nome dos forms
Screen.Forms[i].Name
For i:= 0 to Screen.Forms.Count -1 do
Para pegar o nome dos forms
Screen.Forms[i].Name
GOSTEI 0
Marco Salles
25/10/2005
e aí cara... funcionou desse jeito que vc falou? com o comando GetActiveWindow? Pois se traduzindo ao pé da letra, o comando pega o nome da tela ativa...
Olhe LNunes , tb estou curioso para saber se funcionou ...
A Idéia simples porem um pouquinho cansativa (eu digo so um pouquinho) , porque e so copiar e colar nos eventos onShow de cada formulário aberto , como foi colocado pelo amido Facc
tente criar ela no Form Principal na parte de Public, daí nos demais Forms vc colocaria (veja o local mais apropriado) pra receber o nome do form
Código:
[b:4ec5514397]e na rotina onde grava os erros, vc passaria a variável [/b:4ec5514397]
FPrincipal.VForm := NomeFormulario.Caption
Ate o momento acho a idéia mais plausivel
[b:4ec5514397]Na secção Public do Form Principal[/b:4ec5514397]
var NomeFormularioErro:Strings;
procedure TFormPrincipal.ApplicationEvents1Exception(Sender: TObject; E: Exception); var Filename: string; LogFile: TextFile; begin // prepares log file FileName:=´C:\NomeDaPasta.txt´; AssignFile (LogFile, Filename); if FileExists (FileName) then Append (LogFile) // open existing file else Rewrite (LogFile); // create a new one // write to the file and show error Writeln (LogFile, DateTimeToStr (Now) + ´-> Ocorreu um Erro No Formulário :´+ NomeFormularioErro); Writeln (LogFile,´ O Tipo de erro apresentado foi :´ + E.Message); // close the file CloseFile (LogFile); end;
GOSTEI 0
Thomaz_prg
25/10/2005
Amigo, uso da forma com a qual eu disse, e funciona legal... se você quer pegar o nome do form com erro, é só pegar o último formulário instanciado no Objeto Screen ( Screen.Forms[ Screen.Forms.Count-1 ]).
GOSTEI 0
Marco Salles
25/10/2005
Amigo, uso da forma com a qual eu disse, e funciona legal... se você quer pegar o nome do form com erro, é só pegar o último formulário instanciado no Objeto Screen ( Screen.Forms[ Screen.Forms.Count-1 ]).
Eu entendi e confesso que ate tinha me esquecido do objeto global Screen
..
Mas o problema é que quando ocorre um erro em algum formulario , para que o nome dele seje passado para o manipulador de evento Application , voce deve saber o indice do formulario que esta ativo..
Na minha opinião não basta escrever
Screen.Forms[ Screen.Forms.Count-1 ].Name porque nen sempre sera o formulário onde foi gerado a exceção
Mas de modo geral a idéia de usar o Screen é válida eu particularmente vou tentar dar uma investida nela amanhã
GOSTEI 0
Lnunes
25/10/2005
Agradeço a atenção de todos mas até o momento não encontrei a solução para este problemas , contudo com as novas idéias postadas pelo Marco Salles ,thomaz_prg e braytiner acredito que a solução esteja mais próxima,
principalmente a idéia de realizar um for usando o objeto screen.
Vou tentar e caso tenha êxito vou disponibilizar o código para todos, pois acho que a captura de erros sendo feita desta forma vai ajudar a todos.
principalmente a idéia de realizar um for usando o objeto screen.
Vou tentar e caso tenha êxito vou disponibilizar o código para todos, pois acho que a captura de erros sendo feita desta forma vai ajudar a todos.
GOSTEI 0
Marco Salles
25/10/2005
[b:87be56a274]LNunes Citou:[/b:87be56a274]
[b:87be56a274]Marco Salles citou:[/b:87be56a274]
Não posso garantir porque cada caso é um caso , mas fiz uns testes aqui e nas primeiras simulaçoes , a resposta foi satisfatória.. Utilizei o Objeto Global Screen como foi lembrado pelos amigos. Mas usei a propriedade [b:87be56a274]Screen.activeForm.Caption[/b:87be56a274] , que fornece o nome do formulário que esta ativo..
boa sorte...
Agradeço a atenção de todos mas até o momento não encontrei a solução para este problemas...
[b:87be56a274]Marco Salles citou:[/b:87be56a274]
Mas de modo geral a idéia de usar o Screen é válida eu particularmente vou tentar dar uma investida nela amanhã
Não posso garantir porque cada caso é um caso , mas fiz uns testes aqui e nas primeiras simulaçoes , a resposta foi satisfatória.. Utilizei o Objeto Global Screen como foi lembrado pelos amigos. Mas usei a propriedade [b:87be56a274]Screen.activeForm.Caption[/b:87be56a274] , que fornece o nome do formulário que esta ativo..
procedure TFormPrincipal.ApplicationEvents1Exception(Sender: TObject; E: Exception); var Filename: string; LogFile: TextFile; begin // prepares log file FileName:=´C:\NomeDaPasta.txt´; AssignFile (LogFile, Filename); if FileExists (FileName) then Append (LogFile) // open existing file else Rewrite (LogFile); // create a new one // write to the file and show error Writeln (LogFile, DateTimeToStr (Now) + ´-> Ocorreu um Erro No Formulário :´+ Screen.activeForm.Caption); Writeln (LogFile,´ O Tipo de erro apresentado foi :´ + E.Message); // close the file CloseFile (LogFile); end;
boa sorte...
GOSTEI 0
Rgaffo
25/10/2005
Tenta assim:
(Components[0].Owner).ClassName --> Isso resulta na classe form que deu o erro.
Ex.: Se o nome do formulário for frmClientes o resultado do comando acima é: TfrmClientes, já ajuda neh?
Sem mais,
Robert
(Components[0].Owner).ClassName --> Isso resulta na classe form que deu o erro.
Ex.: Se o nome do formulário for frmClientes o resultado do comando acima é: TfrmClientes, já ajuda neh?
Sem mais,
Robert
GOSTEI 0
Rgaffo
25/10/2005
melhor ainda:
[b:457e70dfcf]procedure [/b:457e70dfcf]TForm1.Erro(Sender: TObject; E : Exception);
[b:457e70dfcf]var[/b:457e70dfcf]
ClassRef: TComponent;
[b:457e70dfcf]begin[/b:457e70dfcf]
ClassRef := TComponent(Sender).Components[0].Owner;
ShowMessage(ClassRef.ClassName);
[b:457e70dfcf]end[/b:457e70dfcf];
Essa é minha procedure em que eu centralizo o erro em toda a aplicação, todos os erros vão para essa procedure.
Com o código acima vc consegue pegar o nome do form que deu erro, da mesma forma que o outro código que eu citei, mas com esse ele pega o nome de qq formulário da sua aplicação.
[b:457e70dfcf]procedure [/b:457e70dfcf]TForm1.Erro(Sender: TObject; E : Exception);
[b:457e70dfcf]var[/b:457e70dfcf]
ClassRef: TComponent;
[b:457e70dfcf]begin[/b:457e70dfcf]
ClassRef := TComponent(Sender).Components[0].Owner;
ShowMessage(ClassRef.ClassName);
[b:457e70dfcf]end[/b:457e70dfcf];
Essa é minha procedure em que eu centralizo o erro em toda a aplicação, todos os erros vão para essa procedure.
Com o código acima vc consegue pegar o nome do form que deu erro, da mesma forma que o outro código que eu citei, mas com esse ele pega o nome de qq formulário da sua aplicação.
GOSTEI 0
Lnunes
25/10/2005
Marco Salles já testei o código que você postou e funciona exatamente da forma que preciso, ficou muito bom.
Mas gostaria de agradecer tambem a colegas thomaz_prg e braytiner que deram a idéia de utilizar o objeto Screen do Delphi , e dos outros que participaram como o Martins e o Facc.
rgaffo não testei a sua dica pois a minha idéia é utilizar o ApplicationEvents
mas agradeço a sua ajuda.
Mas gostaria de agradecer tambem a colegas thomaz_prg e braytiner que deram a idéia de utilizar o objeto Screen do Delphi , e dos outros que participaram como o Martins e o Facc.
rgaffo não testei a sua dica pois a minha idéia é utilizar o ApplicationEvents
mas agradeço a sua ajuda.
GOSTEI 0
Rgaffo
25/10/2005
mas essa dica funciona independente do lugar que vc usar.
[]s
[]s
GOSTEI 0
Marco Salles
25/10/2005
[b:06df9658c1]Citação de LNunes[/b:06df9658c1]
[b:06df9658c1]Citação de rgaffo[/b:06df9658c1]
[color=darkred:06df9658c1]Vamos Voltar no tunel do tempo....[/color:06df9658c1]
[b:06df9658c1]Citação de LNunes[/b:06df9658c1]
[color=red:06df9658c1]Vamos recordar um pouco de teoria[/color:06df9658c1]
O Objeto global Application tem um evento chamado OnException...Podemos escrever um método correto e conectar esse método ao código.
Porém a partir do delphi 5.0 foi definido um novo componente que é o AppliationEvents.
E desse componente que o [b:06df9658c1]Lnunes[/b:06df9658c1] se refere . A dica do [b:06df9658c1]rgaffo[/b:06df9658c1] na minha concepção [b:06df9658c1]funciona[/b:06df9658c1] , so que ela ficou um pouco solta no ar... Eu não sei se ele mudou o nome do Componente ApllicationEvents Para Erros ou se ele [b:06df9658c1]não usou o Componente [/b:06df9658c1]e resolveu escrever o método e conencta-lo ao Objeto Global Application, o que acredito eu , deixou o nosso amigo LNunes um pouco confuso
Em poutras palavras , não basta escrever um método Erros do tipo:
[b:06df9658c1]é preciso conecta-lo ou usar o objeto ApplicationEvents...[/b:06df9658c1]
:P :P
Pois bem foi so uma tentativa de entendimento de ambas as partes
Marco Salles já testei o código que você postou e funciona exatamente da forma que preciso, ficou muito bom.
rgaffo não testei a sua dica pois a minha idéia é utilizar o ApplicationEvents
mas agradeço a sua ajuda
.[b:06df9658c1]Citação de rgaffo[/b:06df9658c1]
mas essa dica funciona independente do lugar que vc usar.
[color=darkred:06df9658c1]Vamos Voltar no tunel do tempo....[/color:06df9658c1]
[b:06df9658c1]Citação de LNunes[/b:06df9658c1]
Facc agradeço primeiramente a sua atenção mas o problema é que esta função fica em um evento do
[b:06df9658c1]componente application [/b:06df9658c1]event no formulário principal destinado a capturar qualquer execeção que
ocorra no sistema
[color=red:06df9658c1]Vamos recordar um pouco de teoria[/color:06df9658c1]
O Objeto global Application tem um evento chamado OnException...Podemos escrever um método correto e conectar esse método ao código.
Porém a partir do delphi 5.0 foi definido um novo componente que é o AppliationEvents.
E desse componente que o [b:06df9658c1]Lnunes[/b:06df9658c1] se refere . A dica do [b:06df9658c1]rgaffo[/b:06df9658c1] na minha concepção [b:06df9658c1]funciona[/b:06df9658c1] , so que ela ficou um pouco solta no ar... Eu não sei se ele mudou o nome do Componente ApllicationEvents Para Erros ou se ele [b:06df9658c1]não usou o Componente [/b:06df9658c1]e resolveu escrever o método e conencta-lo ao Objeto Global Application, o que acredito eu , deixou o nosso amigo LNunes um pouco confuso
Em poutras palavras , não basta escrever um método Erros do tipo:
procedure TForm1.Erro(Sender: TObject; E : Exception); begin blablabla.... end;
[b:06df9658c1]é preciso conecta-lo ou usar o objeto ApplicationEvents...[/b:06df9658c1]
:P :P
Pois bem foi so uma tentativa de entendimento de ambas as partes
GOSTEI 0
Rgaffo
25/10/2005
Delphiano Marco Salles, o intuito da procedure completa era para dar a visão geral do código, mas o que tinha que ser usado era:
[b:1fa5f30a0f]var[/b:1fa5f30a0f]
ClassRef: TComponent;
[b:1fa5f30a0f]begin[/b:1fa5f30a0f]
ClassRef := TComponent(Sender).Components[0].Owner;
ShowMessage(ClassRef.ClassName);
Que pode ser simplificado para:
[b:1fa5f30a0f]var[/b:1fa5f30a0f]
NomeForm : String;
[b:1fa5f30a0f]begin[/b:1fa5f30a0f]
NomeForm := (TComponent(Sender).Components[0].Owner).ClassName;
Como no exemplo que eu tinha dados antes.
No objeto ApplicationEvents no evento OnException eu posso implementar qualquer código, não é?
Então talvez o que tenha confudindo é por eu ter colocado a visualização do código em uma procedure, dando entender assim que essa procedure tinha que ser usada, mas não era para usa-la é sim o código implementado nela, porém se eu tivesse escrito assim:
[b:1fa5f30a0f]procedure [/b:1fa5f30a0f]TForm1.ApplicationEvents1Exception(Sender: TObject;
E: Exception);
[b:1fa5f30a0f]var[/b:1fa5f30a0f]
ClassRef: TComponent;
[b:1fa5f30a0f]begin[/b:1fa5f30a0f]
ClassRef := TComponent(Sender).Components[0].Owner;
ShowMessage(ClassRef.ClassName);
[b:1fa5f30a0f]end[/b:1fa5f30a0f];
Ninguém tinha ficado com dúvida, mas é a mesma coisa, certo? rsrs :D
Mas o seu código e bem menor e mais fácil de entender.
[]s
Até mais.
[b:1fa5f30a0f]var[/b:1fa5f30a0f]
ClassRef: TComponent;
[b:1fa5f30a0f]begin[/b:1fa5f30a0f]
ClassRef := TComponent(Sender).Components[0].Owner;
ShowMessage(ClassRef.ClassName);
Que pode ser simplificado para:
[b:1fa5f30a0f]var[/b:1fa5f30a0f]
NomeForm : String;
[b:1fa5f30a0f]begin[/b:1fa5f30a0f]
NomeForm := (TComponent(Sender).Components[0].Owner).ClassName;
Como no exemplo que eu tinha dados antes.
No objeto ApplicationEvents no evento OnException eu posso implementar qualquer código, não é?
Então talvez o que tenha confudindo é por eu ter colocado a visualização do código em uma procedure, dando entender assim que essa procedure tinha que ser usada, mas não era para usa-la é sim o código implementado nela, porém se eu tivesse escrito assim:
[b:1fa5f30a0f]procedure [/b:1fa5f30a0f]TForm1.ApplicationEvents1Exception(Sender: TObject;
E: Exception);
[b:1fa5f30a0f]var[/b:1fa5f30a0f]
ClassRef: TComponent;
[b:1fa5f30a0f]begin[/b:1fa5f30a0f]
ClassRef := TComponent(Sender).Components[0].Owner;
ShowMessage(ClassRef.ClassName);
[b:1fa5f30a0f]end[/b:1fa5f30a0f];
Ninguém tinha ficado com dúvida, mas é a mesma coisa, certo? rsrs :D
Mas o seu código e bem menor e mais fácil de entender.
[]s
Até mais.
GOSTEI 0