Criação de Componentes
Veja neste artigo de Fabio Francelino, como criar um componente para rastrear erros.
Rastreando Erros com TExErrorDialog
Como sabemos é muito importante o modo como tratamos os erros ocorridos nos sistemas, tanto os esperados quanto os inesperados, isso pode fazer a diferença na hora da manutenção de um sistema complexo e também transmite confiabilidade ao usuário final. Um programa é considerado robusto quando tem a capacidade de rastrear todos os seus erros e apresentar uma informação plausível para o usuário tomar alguma decisão ou entrar em contato com o setor de desenvolvimento do sistema.
Criando o pacote
Vamos começar criando um pacote para o componente TExErrorDialog. Vá no menu File|New>Other e escolha a opção Package. Salve o pacote com o nome sugerido em um diretório e clique na opção Options, na descrição do pacote digite o nome que irá aparecer na lista de pacotes instalados (Component|Install Packges). Certifique-se que as opções Designtime and runtime e Explicit rebuild estejam marcadas, caso queira, acesse a aba Version Info e configure as descrições do arquivo.
Criando a unit do componente
Vá ao menu Component>New Component, na caixa de diálogo crie um descendente (Ancestor Type) de TComponent com o nome (Class Name) de “TExErrorDialog” na paleta ExControls e o nome da unit como “untExErrorDialog”, não se esqueça de mudar o diretório da unit, clique em OK. Vamos codificar as propriedades, eventos e tipos do componente conforme a Listagem 1.
Listagem 1. Código fonte completo
unit untExErrorDialog;
interface
uses Windows, Messages, SysUtils, Classes, Forms;
type
{ Tipos de Erro }
TErrorType = (etNone = 0, etRunTime = 1, etSQL = 2,
etValidation = 3, etLogic = 4);
{ Status do Erro }
TErrorStatus = (esNone = 0, esFatal = 1,
esNormal = 2);
{Tipo de Erro}
TErrorInfo = record
ErrorStatus: TErrorStatus;
ErrorType: TErrorType;
ErrorSource: string;
ErrorMsgUser: string;
ErrorMsgSys: string;
ErrorClass: string;
ErrorMethod: string;
ErrorCode: string;
end;
{ Componente de Erro }
TExErrorDialog = class(TComponent)
private
FErrorInfo: TErrorInfo;
FErrorStatus: TErrorStatus;
FErrorType: TErrorType;
FErrorSource: string;
FErrorMsgUser: string;
FErrorMsgSys: string;
FErrorClass: string;
FErrorMethod: string;
FErrorCode: string;
FShowDetail: Boolean;
FClearAfterShow: Boolean;
FOnBeforeShow: TNotifyEvent;
FOnAfterShow: TNotifyEvent;
procedure SetErrorInfoValues();
procedure SetErrorPropValues();
protected
public
procedure Clear();
procedure ShowErrorMsg(); overload;
procedure ShowErrorMsg(
const pErrorInfo: TErrorInfo); overload;
published
property ErrorStatus: TErrorStatus
read FErrorStatus write FErrorStatus;
property ErrorType: TErrorType
read FErrorType write FErrorType;
property ErrorSource: string
read FErrorSource write FErrorSource;
property ErrorMsgUser: string
read FErrorMsgUser write FErrorMsgUser;
property ErrorMsgSys: string
read FErrorMsgSys write FErrorMsgSys;
property ErrorClass: string
read FErrorClass write FErrorClass;
property ErrorMethod: string
read FErrorMethod write FErrorMethod;
property ErrorCode: string
read FErrorCode write FErrorCode;
property ShowDetail: Boolean
read FShowDetail write FShowDetail;
property ClearAfterShow: Boolean
read FClearAfterShow write FClearAfterShow;
property OnBeforeShow: TNotifyEvent
read FOnBeforeShow write FOnBeforeShow;
property OnAfterShow: TNotifyEvent
read FOnAfterShow write FOnAfterShow;
end;
procedure Register;
implementation
uses untExGuiErrorDialog;
procedure Register;
begin
RegisterComponents('ExControls', [TExErrorDialog]);
end;
{ Mostra a mensagem passando os parametros internos }
procedure TExErrorDialog.ShowErrorMsg();
begin
{ Sincroniza as propriedades com o record }
SetErrorInfoValues;
{ Chama a rotina }
ShowErrorMsg(FErrorInfo);
end;
{ Mostra a mensagem passando os parametros
de pErrorInfo }
procedure TExErrorDialog.ShowErrorMsg(
const pErrorInfo: TErrorInfo);
begin
{ Cria o formulario }
frmExGuiErrorDialog :=
TfrmExGuiErrorDialog.Create(Self);
FErrorInfo := pErrorInfo;
frmExGuiErrorDialog.SetFieldValue(pErrorInfo);
{ Sincroniza o record com as propriedades }
SetErrorPropValues;
{ Verifica e dispara o evento }
if Assigned(FOnBeforeShow) then
FOnBeforeShow(Self);
{ Seta o valor da propriedade ShowDetail }
frmExGuiErrorDialog.cmdDetalhes.Visible :=
FShowDetail;
{ Mostra o form Modal }
frmExGuiErrorDialog.ShowModal;
if Assigned(FOnAfterShow) then
FOnAfterShow(Self);
{ Verifica e limpa os parametros }
if FClearAfterShow then
Clear();
{ Libera a memória }
frmExGuiErrorDialog.Free;
frmExGuiErrorDialog := nil;
end;
{ Seta as propriedades internas do record }
procedure TExErrorDialog.SetErrorInfoValues();
begin
{ Seta as propriedades do record }
FErrorInfo.ErrorType := FErrorType;
FErrorInfo.ErrorStatus := FErrorStatus;
FErrorInfo.ErrorSource := FErrorSource;
FErrorInfo.ErrorMsgUser := FErrorMsgUser;
FErrorInfo.ErrorMsgSys := FErrorMsgSys;
FErrorInfo.ErrorClass := FErrorClass;
FErrorInfo.ErrorMethod := FErrorMethod;
FErrorInfo.ErrorCode := FErrorCode;
end;
{ Seta as propriedades internas do componente }
procedure TExErrorDialog.SetErrorPropValues();
begin
{ Seta as propriedades do record }
FErrorType := FErrorInfo.ErrorType;
FErrorStatus := FErrorInfo.ErrorStatus;
FErrorSource := FErrorInfo.ErrorSource;
FErrorMsgUser := FErrorInfo.ErrorMsgUser;
FErrorMsgSys := FErrorInfo.ErrorMsgSys;
FErrorClass := FErrorInfo.ErrorClass;
FErrorMethod := FErrorInfo.ErrorMethod;
FErrorCode := FErrorInfo.ErrorCode;
end;
{ Limpa todas as propriedades internas }
procedure TExErrorDialog.Clear();
begin
{ Limpa as propriedades do record }
with FErrorInfo do
begin
ErrorType := etNone;
ErrorStatus := esNone;
ErrorSource := EmptyStr;
ErrorMsgUser := EmptyStr;
ErrorMsgSys := EmptyStr;
ErrorClass := EmptyStr;
ErrorMethod := EmptyStr;
ErrorCode := EmptyStr;
end;
{ Limpa as propriedades publicas }
ErrorType := etNone;
ErrorStatus := esNone;
ErrorSource := EmptyStr;
ErrorMsgUser := EmptyStr;
ErrorMsgSys := EmptyStr;
ErrorClass := EmptyStr;
ErrorMethod := EmptyStr;
ErrorCode := EmptyStr;
end;
end.
Propriedades do componente
Nessa seção destaco as propriedades ErrorStatus e ErrorType que são de tipos, delarados no inicio da unit e que nos mostram os tipos de erros que vamos apresentar e qual o status desses erros, como vemos no código a seguir:
{ Tipos de Erro }
TErrorType = (etNone = 0, etRunTime = 1, etSQL = 2,
etValidation = 3, etLogic = 4);
{ Status do Erro }
TErrorStatus = (esNone = 0, esFatal = 1,
esNormal = 2);
Eventos do componente
Declaramos dois eventos para ajudar a controlar erros fatais e dar um tratamento genérico de erro que são OnBeforeShow e OnAfterShow. As propriedades ClearAfterShow e ErrorStatus trabalham baseadas no seguintes eventos:
property OnBeforeShow: TNotifyEvent read FonBeforeShow
write FOnBeforeShow;
property OnAfterShow: TNotifyEvent read FonAfterShow
write FOnAfterShow;
Codificando o componente
Temos duas rotinas que merecem destaque, pois ambas tem o mesmo nome com parâmetros diferentes. ShowErrorMsg (com a diretiva overload, que permite declarar rotinas com nomes iguais e parâmetros de tipos diferentes), em uma das suas declarações possui um parâmetro que é um record, ou seja, uma estrutura de dados (definida no escopo da unit), para facilitar o intercâmbio de um conjunto de informações entre rotinas e funções. Por causa desse record devemos sincronizar as propriedades do componente com o record recebido como parâmetro e vice-versa, para isso temos as rotinas SetErrorInfoValues e SetErrorPropValues veja na Listagem 2.
Listagem 2. Rotinas do componente
private
procedure SetErrorInfoValues();
procedure SetErrorPropValues();
protected
public
procedure Clear();
procedure ShowErrorMsg(); overload;
procedure ShowErrorMsg(
const pErrorInfo: TErrorInfo); overload;
Formulário do componente
Sei que vocês estão tentados a compilar o componente, mas ainda falta a parte mais importante: o formulário de apresentação, ou seja, onde todas as informações serão exibidas para o usuário final.
Adicione um novo formulário (File|New>Form) no pacote e salve sua unit como “untGuiExErrorDialog.pas” e o nome do formulário como “frmExGuiErrorDialog”. Por que Gui?, Gui é a abreviação de Graphic User Interface nada mais conveniente.
Adicione no formulário os seguintes componentes: um StaticText, dois Buttons, um Memo e quatro Image. Disponha os componentes para que fiquem parecido com a Figura 1.
Figura 1. Formulário de apresentação dos erros
Altere as propriedades dos componentes conforme a Tabela 1.
|
Componente |
Nome |
Valor |
|
StaticText |
Name |
lblErrMsg |
|
|
BevelKind |
BkTile |
|
Button |
Name |
cmdDetalhes |
|
|
Caption |
<<&Detalhes |
|
|
Default |
True |
|
Button |
Name |
cmdOk |
|
|
Caption |
&Ok |
|
|
Cancel |
True |
|
Memo |
Name |
txtErrorDescription |
|
|
ScrollBars |
ssVertical |
|
Image |
Name |
imgValidation |
|
Image |
Name |
imgLogic |
|
Image |
Name |
imgInformation |
|
Image |
Name |
imgRunTime |
Tabela 1. Propriedade dos componentes no formulário
Escolha uma imagem de 32x32 para cada um dos Images (altere para False a propriedade Visible dos Images), cada imagem representa um tipo de erro, e deixe todos exatamente sobrepostos, ao terminar lembre-se de voltar o tamanho do seu formulário para que fique sem aparecer o Memo (altere para bsSingle a propriedade BorderStyle do formulário). Insira na seção public do formulário o seguite código:
procedure SetFieldValue(const pErrorInfo: TErrorInfo);
E implemente-o conforme a Listagem 3.
Listagem 3. Código do método SetFieldValue do formulário
procedure TfrmExGuiErrorDialog.SetFieldValue(
const pErrorInfo: TErrorInfo);
begin
with pErrorInfo do
begin
{ Verifica qual o tipo de erro }
case ErrorType of
etNone:
begin
Caption := 'Tipo de Erro Desconhecido.';
imgRunTime.Visible := True;
end;
etValidation:
begin
Caption := 'Erro de Validação.';
imgValidation.Visible := True;
end;
etSQL:
begin
Caption := 'Erro de Comando SQL.';
imgRunTime.Visible := True;
end;
etRunTime:
begin
Caption := 'Erro de Run-Time.';
imgRunTime.Visible := True;
end;
etLogic:
begin
Caption := 'Erro de Lógica de Programação.';
imgLogic.Visible := True;
end;
end;
lblErrMsg.Caption := ErrorMsgUser;
txtErrorDescription.Text :=
'Code: ' + ErrorCode + #13#10 +
'Source: ' + ErrorSource + #13#10 +
'Class: ' + ErrorClass + #13#10 +
'Method: ' + ErrorMethod + #13#10 +
'Description: ' + ErrorMsgSys;
end;
end;
No botão OK apenas indicamos a propriedade ModalResult como mrOK e fechamos o formulário (Close).
Devemos declarar na cláusula uses do formulário a unit do componente (untExErrorDialog), o que já nos permite tirar vantagem do record, facilitando o intercâmbio de informações entre o componente e o formulário.
Outro detalhe, é o tipo de erro etSQL não possuir uma imagem em particular, ele utiliza a mesma imagem do erro de run-time. Já podemos compilar e instalar o componente.
Alterando a imagem que representa o componente
Escolha uma imagem que representa bem o componente no formato .BMP com o tamanho 24x24, vá no menu Tools e abra o Image Editor, crie um novo Resource files (.dcr), adicione um novo bitmap, mude seu nome para o nome do componente (TEXERRORDIALOG) e cole a imagem desenhada na área em branco, salve o arquivo com o nome “untExErrorDialog.dcr”.
Para que a figura apareça na IDE do Delphi, vá no menu Project|View Source e adicione a seguinte linha de código:
{$R *.res}
{$R untExErrorDialog.dcr} <- adicione aqui
...
Veja na Figura 2, como ficará o componente registrado na IDE do Delphi.
Figura 2. Componente ExErrorDialog instalado na IDE do Delphi
Utilizando o ExErrorDialog
Vamos finalmente testar todas as funcionalidades do componente. Crie uma nova aplicação no Delphi e configure o formulário como mostra a Figura 3.
Figura 3. Utilizando o componente
O código completo do componente e do exemplo está para download no endereço do artigo. Para testar, temos na Listagem 4, o código do botão Run-Time, onde utilizamos constantes (declaradas no formulário) para mostrar as mensagens de erros ao usuário (propriedade ErrorMsgUser).
Listagem 4. Utilizando o componente de Erro
procedure TForm1.Button1Click(Sender: TObject);
begin
try
{ Forçando o Erro }
Button1.Tag := StrToInt('X');
except
{ Seta as informaçõe do erro }
with ExErrorDialog1 do
begin
ErrorType := etRunTime;
ErrorStatus := esNormal;
ErrorClass := 'TButton';
ErrorMethod := 'Tag';
ErrorSource := 'cmdRunTimeClick';
ErrorMsgUser := ErrConvert; <- constante
ErrorMsgSys := 'X is not a valid integer value.';
ShowErrorMsg;
end;
end;
end;
No exemplo, um erro do tipo fatal pode causar o fechamento do seu programa com uma mensagem elegante (Figura 4), podemos ainda mostrar o último erro ocorrido sem nenhum esforço e ainda tratar mensagens de erro no evento OnBeforeShow. Podemos chamar rotinas passando nosso TErrorInfo como parâmetro e verificar o código retornado na propriedade ErrorCode, o que torna fácil o intercâmbio de informações de erro.
Figura 4. Componente em execução
Aconselho a colocar apenas um componente em seu DataModule e utilizá-lo em todo o seu programa, tornando fácil e prático a exibição de uma mensagem de erro. Podemos chamar funções que já preenchem as propriedades de erro e depois avaliar se mostramos o erro ou não. Os erros de lógica, como por exemplo, pode alertar programadores sobre valores inválidos em suas chamadas de funções e rotinas.
Outro aspecto que devemos destacar é a necessidade que alguns sistemas tem de fazer um log de erro, com o evento AfterShow você poderá chamar sua rotina de log e passar um TErrorInfo para ser gravado em um arquivo.
Se o leitor gostar dessa brincadeira poderá estender o componente e adicionar as funcionalidades de log embutidas no componente e até uma opção de envio de e-mail.
Conclusões
Utilizando corretamente esse componente você será capaz de identificar as seguintes informações sobre o erro: em qual função ocorreu o erro, por que, qual componente foi o responsável pelo erro, qual medida a ser tomada, qual o código, quem disparou a função. Isso reduz seu tempo de manutenção praticamente em 50% pois agora você já sabe tudo sobre o erro e basta somente corrigi-lo e não procurá-lo.
Fabio Alves Francelino
Fabio Alves Francelino (francelino@mackenzie.com.br) é Analista de Sistemas formado pela Universidade Presbiteriana Mackenzie. Trabalha com ADO e DataSnap em projetos cliente/servidor e multicamadas, desenvolve componentes e jogos para Delphi.
4 COMENTÁRIOS
[Error] untGuiExErrorDialog.pas(23): Undeclared identifier: 'TErrorInfo'
[Error] untGuiExErrorDialog.pas(46): Undeclared identifier: 'ErrorType'
[Error] untGuiExErrorDialog.pas(100): Undeclared identifier: 'ErrorMsgUser'
[Error] untGuiExErrorDialog.pas(104): Undeclared identifier: 'ErrorCode'
[Error] untGuiExErrorDialog.pas(106): Undeclared identifier: 'ErrorSource'
[Error] untGuiExErrorDialog.pas(106): Incompatible types: 'String' and 'Integer'
[Error] untGuiExErrorDialog.pas(108): Undeclared identifier: 'ErrorClass'
[Error] untGuiExErrorDialog.pas(108): Incompatible types: 'String' and 'Integer'
[Error] untGuiExErrorDialog.pas(110): Undeclared identifier: 'ErrorMethod'
[Error] untGuiExErrorDialog.pas(110): Incompatible types: 'String' and 'Integer'
[Error] untGuiExErrorDialog.pas(112): Undeclared identifier: 'ErrorMsgSys'
[Error] untGuiExErrorDialog.pas(112): Incompatible types: 'String' and 'Integer'
[Fatal Error] ExErrorDialog.pas(154): Could not compile used unit 'untGuiExErrorDialog.pas'
[Fatal Error] untGuiExErrorDialog.pas(33): Could not compile used unit 'C:\Sistoque\DialogoErro\ExErrorDialog.pas'
Código do Projeto
unit ExErrorDialog;
interface
uses Windows, Messages, SysUtils, Classes, Forms;
type
{ Tipos de Erro }
TErrorType = (etNone = 0, etRunTime = 1, etSQL = 2,
etValidation = 3, etLogic = 4);
{ Status do Erro }
TErrorStatus = (esNone = 0, esFatal = 1,
esNormal = 2);
{Tipo de Erro}
TErrorInfo = record
ErrorStatus: TErrorStatus;
ErrorType: TErrorType;
ErrorSource: string;
ErrorMsgUser: string;
ErrorMsgSys: string;
ErrorClass: string;
ErrorMethod: string;
ErrorCode: string;
end;
{ Componente de Erro }
TExErrorDialog = class(TComponent)
private
FErrorInfo: TErrorInfo;
FErrorStatus: TErrorStatus;
FErrorType: TErrorType;
FErrorSource: string;
FErrorMsgUser: string;
FErrorMsgSys: string;
FErrorClass: string;
FErrorMethod: string;
FErrorCode: string;
FShowDetail: Boolean;
FClearAfterShow: Boolean;
FOnBeforeShow: TNotifyEvent;
FOnAfterShow: TNotifyEvent;
procedure SetErrorInfoValues();
procedure SetErrorPropValues();
protected
public
procedure Clear();
procedure ShowErrorMsg(); overload;
procedure ShowErrorMsg(const pErrorInfo: TErrorInfo); overload;
published
property ErrorStatus: TErrorStatus
read FErrorStatus write FErrorStatus;
property ErrorType: TErrorType
read FErrorType write FErrorType;
property ErrorSource: string
read FErrorSource write FErrorSource;
property ErrorMsgUser: string
read FErrorMsgUser write FErrorMsgUser;
property ErrorMsgSys: string
read FErrorMsgSys write FErrorMsgSys;
property ErrorClass: string
read FErrorClass write FErrorClass;
property ErrorMethod: string
read FErrorMethod write FErrorMethod;
property ErrorCode: string
read FErrorCode write FErrorCode;
property ShowDetail: Boolean
read FShowDetail write FShowDetail;
property ClearAfterShow: Boolean
read FClearAfterShow write FClearAfterShow;
property OnBeforeShow: TNotifyEvent
read FOnBeforeShow write FOnBeforeShow;
property OnAfterShow: TNotifyEvent
read FOnAfterShow write FOnAfterShow;
end;
procedure Register;
implementation
uses untGuiExErrorDialog;
procedure Register;
begin
RegisterComponents('ExControls', [TExErrorDialog]);
end;
{ Mostra a mensagem passando os parametros internos }
procedure TExErrorDialog.ShowErrorMsg();
begin
{ Sincroniza as propriedades com o record }
SetErrorInfoValues;
{ Chama a rotina }
ShowErrorMsg(FErrorInfo);
end;
{ Mostra a mensagem passando os parametros
de pErrorInfo }
procedure TExErrorDialog.ShowErrorMsg(const pErrorInfo: TErrorInfo);
begin
{ Cria o formulario }
frmExGuiErrorDialog :=
TfrmExGuiErrorDialog.Create(Self);
FErrorInfo := pErrorInfo;
frmExGuiErrorDialog.SetFieldValue(pErrorInfo);
{ Sincroniza o record com as propriedades }
SetErrorPropValues;
{ Verifica e dispara o evento }
if Assigned(FOnBeforeShow) then
FOnBeforeShow(Self);
{ Seta o valor da propriedade ShowDetail }
frmExGuiErrorDialog.cmdDetalhes.Visible := FShowDetail;
{ Mostra o form Modal }
frmExGuiErrorDialog.ShowModal;
if Assigned(FOnAfterShow) then
FOnAfterShow(Self);
{ Verifica e limpa os parametros }
if FClearAfterShow then
Clear();
{ Libera a memória }
frmExGuiErrorDialog.Free;
frmExGuiErrorDialog := nil;
end;
{ Seta as propriedades internas do record }
procedure TExErrorDialog.SetErrorInfoValues();
begin
{ Seta as propriedades do record }
FErrorInfo.ErrorType := FErrorType;
FErrorInfo.ErrorStatus := FErrorStatus;
FErrorInfo.ErrorSource := FErrorSource;
FErrorInfo.ErrorMsgUser := FErrorMsgUser;
FErrorInfo.ErrorMsgSys := FErrorMsgSys;
FErrorInfo.ErrorClass := FErrorClass;
FErrorInfo.ErrorMethod := FErrorMethod;
FErrorInfo.ErrorCode := FErrorCode;
end;
{ Seta as propriedades internas do componente }
procedure TExErrorDialog.SetErrorPropValues();
begin
{ Seta as propriedades do record }
FErrorType := FErrorInfo.ErrorType;
FErrorStatus := FErrorInfo.ErrorStatus;
FErrorSource := FErrorInfo.ErrorSource;
FErrorMsgUser := FErrorInfo.ErrorMsgUser;
FErrorMsgSys := FErrorInfo.ErrorMsgSys;
FErrorClass := FErrorInfo.ErrorClass;
FErrorMethod := FErrorInfo.ErrorMethod;
FErrorCode := FErrorInfo.ErrorCode;
end;
{ Limpa todas as propriedades internas }
procedure TExErrorDialog.Clear();
begin
{ Limpa as propriedades do record }
with FErrorInfo do
begin
ErrorType := etNone;
ErrorStatus := esNone;
ErrorSource := EmptyStr;
ErrorMsgUser := EmptyStr;
ErrorMsgSys := EmptyStr;
ErrorClass := EmptyStr;
ErrorMethod := EmptyStr;
ErrorCode := EmptyStr;
end;
{ Limpa as propriedades publicas }
ErrorType := etNone;
ErrorStatus := esNone;
ErrorSource := EmptyStr;
ErrorMsgUser := EmptyStr;
ErrorMsgSys := EmptyStr;
ErrorClass := EmptyStr;
ErrorMethod := EmptyStr;
ErrorCode := EmptyStr;
end;
end.
unit untGuiExErrorDialog;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TfrmExGuiErrorDialog = class(TForm)
txtErrorDescription: TMemo;
imgValidation: TImage;
imgLogic: TImage;
imgInformation: TImage;
imgRunTime: TImage;
lblErrMsg: TStaticText;
cmdDetalhes: TButton;
cmdOk: TButton;
private
{ Private declarations }
public
{ Public declarations }
procedure SetFieldValue(const pErrorInfo: TErrorInfo);
end;
var
frmExGuiErrorDialog: TfrmExGuiErrorDialog;
implementation
uses ExErrorDialog;
{$R *.dfm}
procedure TfrmExGuiErrorDialog.SetFieldValue(const pErrorInfo: TErrorInfo);
begin
with pErrorInfo do
begin
{ Verifica qual o tipo de erro }
case ErrorType of
etNone:
begin
Caption := 'Tipo de Erro Desconhecido.';
imgRunTime.Visible := True;
end;
etValidation:
begin
Caption := 'Erro de Validação.';
imgValidation.Visible := True;
end;
etSQL:
begin
Caption := 'Erro de Comando SQL.';
imgRunTime.Visible := True;
end;
etRunTime:
begin
Caption := 'Erro de Run-Time.';
imgRunTime.Visible := True;
end;
etLogic:
begin
Caption := 'Erro de Lógica de Programação.';
imgLogic.Visible := True;
end;
end;
lblErrMsg.Caption := ErrorMsgUser;
txtErrorDescription.Text :=
'Code: ' + ErrorCode + #13#10 +
'Source: ' + ErrorSource + #13#10 +
'Class: ' + ErrorClass + #13#10 +
'Method: ' + ErrorMethod + #13#10 +
'Description: ' + ErrorMsgSys;
end;
end;
end.
Acompanhando o artigo, detectei 1 problema na criação do componente:
procedure Register;
implementation
//uses untExGuiErrorDialog;
uses untGuiExErrorDialog;
procedure Register;
begin
RegisterComponents('ExControls', [TExErrorDialog]);
end;
Observe que o nome da unit declarada na uses esta diferente do nome sugerido no artigo. Apos esta correção consegui compilar e instalar o componente.
Já no código do teste do componente notei que o código faz referencia ao registro "ErrConvert" que não esta declarado no componente e na sequencia tem o comentário que esta como <- e o correto e estar como // veja exemplo:
Errado
ErrorSource := 'cmdRunTimeClick';
ErrorMsgUser := ErrConvert; <- constante
ErrorMsgSys := 'X is not a valid integer value.';
Correto
ErrorSource := 'cmdRunTimeClick';
ErrorMsgUser := ErrorCode; // constante
ErrorMsgSys := 'X is not a valid integer value.';
Abs.!
Tentamos contato com o autor, porém o e-mail cadastrado não está mais ativo.
Um abraço e até mais

download

