Ir al contenido


Foto

Método para crear ventanas de Excepciones personalizadas


  • Por favor identifícate para responder
6 respuestas en este tema

#1 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 05 diciembre 2008 - 06:42

Creo este hilo para enseñarles cómo hacer una ventana personalizada para las capturas de excepciones, parecido a algo como esto (Lo puedes personalizar a tu gusto):

Imagen Enviada

Imagen Enviada

Paso 1

Vamos a crear un formulario que será la ventana de aviso como las imágenes anteriores, éste es el código de dicho formulario:

Nombre de la unidad (Unit): Aviso.
Nombre del Formulario (Form): FAviso.


delphi
  1. unit Aviso;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.   Dialogs, StdCtrls, pngimage, ExtCtrls;
  8.  
  9. type
  10.   TFAviso = class(TForm)
  11.     Label1: TLabel;
  12.     Image1: TImage;
  13.     btDetalle: TButton;
  14.     btCerrar: TButton;
  15.     mError: TMemo;
  16.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  17.     procedure btCerrarClick(Sender: TObject);
  18.     procedure btDetalleClick(Sender: TObject);
  19.   private
  20.     { Private declarations }
  21.   public
  22.     { Public declarations }
  23.   end;
  24.  
  25. var
  26.   FAviso: TFAviso;
  27.  
  28. implementation
  29.  
  30. {$R *.dfm}
  31.  
  32. procedure TFAviso.FormClose(Sender: TObject; var Action: TCloseAction);
  33. begin
  34. Action := caFree;
  35. end;
  36.  
  37. procedure TFAviso.btCerrarClick(Sender: TObject);
  38. begin
  39. Close;
  40. end;
  41.  
  42. procedure TFAviso.btDetalleClick(Sender: TObject);
  43. begin
  44. if btDetalle.Caption = 'Detalles >>' then
  45.   begin
  46.     FAviso.Height := 243;
  47.     btCerrar.Top := 176;
  48.     btDetalle.Top := 176;
  49.     mError.Visible := True;
  50.     btDetalle.Caption := &#39;<< Detalles&#39;;
  51.   end else begin
  52.     FAviso.Height := 152;
  53.     btCerrar.Top := 88;
  54.     btDetalle.Top := 88;
  55.     mError.Visible := False;
  56.     btDetalle.Caption := &#39;Detalles >>&#39;;
  57.   end;
  58. end;
  59.  
  60. end.



Paso 2

En este paso vamos a crear un procedimiento en el Form principal de tu aplicativo, lo llamaremos Mostrar:



delphi
  1. procedure Mostrar(cMensaje,cError: string);
  2. begin
  3.   FAviso := TFAviso.Create(Application);
  4.   FAviso.Label1.Caption := cMensaje; {Label}
  5.   FAviso.mError.Text := cError; {Memo}
  6.   FAviso.ShowModal;
  7.   Freeandnil(FAviso);
  8. end;



cMensaje: Es el mensaje General del formulario asignado por ti.
cError: es el mensaje de error por defecto de la excepción.

Método de uso.

Ahora veremos cómo usar el procedimiento y el llamado de la ventana, para su perfecto funcionamiento debemos agregar en el uses de tu form principal la unidad Aviso que creamos anteriormente, colocaremos el siguiente código en un botón en el form principal:



delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3. //algo de código
  4. try
  5.   //código
  6. except
  7.   on E: Exception do
  8.     if E.ClassNameIs(&#39;EDatabaseError&#39;) then
  9.       begin
  10.       Mostrar(&#39;Se produjo un error al intentar conectarse a la base de datos.&#39;, E.Message);
  11.       Abort;
  12.     end;
  13.   end;
  14. end;



Esa es una de las tantas formas de capturar una excepción, debe estar encerrado en un Try...Except para capturar esos errores, aquí una lista de excepciones genéricos de Delphi (también puedes capturar excepciones de componentes):

EAbort: Finaliza la secuencia de eventos sin mostrar el mensaje de error.

EAccessViolation: Comprueba errores de acceso a memoria inválidos.

EBitsError: Previene intentos para acceder a arrays de elementos booleanos.

EComponentError: Nos informa de un intento inválido de registar o renombar un componente.

EConvertError: Muestra un error al convertir objetos o cadenas de texto string.

EDatabaseError: Especifica un error de acceso a bases de datos.

EDBEditError: Error al introducir datos incompatibles con una máscara de texto.

EDivByZero: Errores de división por cero.

EExternalException: Significa que no reconoce el tipo de excepción (viene de fuera).

EIntOutError: Representa un error de entrada/salida a archivos.

EIntOverflow: Especifica que se ha provocado un desbordamiento de un tipo de dato.

EInvalidCast: Comprueba un error de conversión de tipos.

EInvalidGraphic: Indica un intento de trabajar con gráficos que tienen un formato desconocido.

EInvalidOperation: Ocurre cuando se ha intentado realizar una operación inválida sobre un componente.

EInvalidPointer: Se produce en operaciones con punteros inválidos.

EMenuError: Controla todos los errores relacionados con componentes de menú.

EOleCtrlError: Detecta problemas con controles ActiveX.

EOleError: Especifica errores de automatización de objetos OLE.

EPrinterError: Errores al imprimir.

EPropertyError: Ocurre cuando se intenta asignar un valor erroneo a una propiedad del componente.

ERangeError: Indica si se intenta asignar un número entero demasiado grande a una propiedad.

ERegistryExcepcion: Controla los errores en el resigtro.

EZeroDivide: Controla los errores de división para valores reales.


Espero lo disfruten ;)

Saludos.





  • 0

#2 Caral

Caral

    Advanced Member

  • Administrador
  • 4.255 mensajes
  • LocationCosta Rica

Escrito 05 diciembre 2008 - 06:54

Hola
Muy bueno amigo, ademas muy util, como todos los tutoriales que haces.
Gracias por el aporte.
Saludos
  • 0

#3 felipe

felipe

    Advanced Member

  • Administrador
  • 3.283 mensajes
  • LocationColombia

Escrito 05 diciembre 2008 - 07:01

Muy bueno el tema Fernando, muchas gracias...
  • 0

#4 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.286 mensajes
  • LocationArgentina

Escrito 06 diciembre 2008 - 12:23

Hola Fernando,
Me gusta mucho la idea del tema del mostrar/ocultar detalle.
Se puede ampliar incluso para que se pueda elegir la imagen, o incluso hasta elegir que botones deseamos que aparezca. Tampoco es para complicarlo demasiado, pero de poder se puede.

Lo que si considero conveniente es que en vez de establecer los textos de forma directa, sería mejor emplear propiedades. Algo así:



delphi
  1. property Message: string read FMessage write SetMessage;
  2. property Detail: string read FDetail write SetDetail;



También se podría, incluso, ver hasta que punto sería factible y bueno hacer que el memo se adapte al tamaño del texto. Yo no más digo...

Como cuadro de díalogo es muy bueno. Le veo muy buena utilidad. Ahora, hay casos en donde es poco viable este enfoque.
En ciertas ocasiones, se tiene un Log de Excepción singleton que captura todos los eventos, y por tanto no llega a capturarse la excepción en donde se desea darle control. ¿Porqué sucede esto? Porque el manejo de las excepciones va desde lo general hacia lo particular. El primero en enterarse de las excepciones, es TAplication, de allí se empieza a subir hasta llegar al método, y al objeto que pueda ser capaz de capturar la excepción.

Si centralizamos las excepciones, siguiendo el uso del "patrón" RCE (Registro Centralizado de los Errores), y deseamos usar el cuadro de díalogo, lo mejor es diseñar las clases de forma que se capturen las excepciones y se las propaguen hacia el objeto dependiente, añadiendo más detalles: en pocas ir convirtiendo las excepciones de modo que cada clase sea capaz de capturar las excepciones que pueda manejar a un nivel más comprensible. Esto último es lo que se conoce como "patrón" CE (Convertir Excepciones).

¿Porqué menciono esto?
Porque en definitiva, esos cripticos mensajes en inglés poco le dicen al usuario final. Si en vez de mostrarle esos mensajes raros, le podemos decir que se ha producido una excepción EAccesoDenegado con un Mensaje como "El usuario no tiene los permisos necesarios" es más entendible y útil.
En resumen:
Centralizar las excepciones, con el fin de llegar un log. En caso de no saber como interpretarlas o manejarlas, o en su defecto, se necesita propagarla hacia el objeto interezado, convertir la excepción a otra que sea entendible para el objeto interesado.

Espero no haber aburrido el tema.
Disculpen si fui demasiado técnico.

Saludos,
  • 0

#5 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 06 diciembre 2008 - 12:39

Gracias Delphius, nunca está más aportar ideas nuevas y consejos, siempre será bienvenido por estos lares ;).

Saludos.
  • 0

#6 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 19 septiembre 2009 - 02:48

ENECUME no te has planteado crear un componente con este procedimiento, seria de mucha utilidad.
  • 0

#7 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 19 septiembre 2009 - 07:22

ENECUME no te has planteado crear un componente con este procedimiento, seria de mucha utilidad.


mmm, no lo había pensado de esa manera, tal vez lo haga :D, gracias desart (y).

Saludos.
  • 0