Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 01-09-2003
Avatar de javiermorales
javiermorales javiermorales is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante
Posts: 272
Poder: 21
javiermorales Va por buen camino
Raised Exception

Buenas Tardes, se me produce el siguiente error:

"Project SIGECO.exe raised exception class EAccessViolation with message 'Violación de acceso en la dirección 00503A36 en módulo 'SIGECO.EXE'. Leer de dirección 'FFFFFFFF'. Process stopped. Use Step or Run to continue"

Le he realizado una traza y no indica el punto exacto del código donde se produce el error, pero ocurre en todos los formularios que cierro a través de código. Dichos formularios se han creado utilizando el siguiente código:

Código:
Application.CreateForm(TFormClass(listaclass[i]),Pantalla[j]);
IndicePantalla := j;
Pantalla[j].Show;
Por su puesto es mucho más largo, pero en concreto este es el momento en que se crea el formulario y no dá ningún problema. Para cerrar dicho formulario, realizo lo siguiente

Código:
  Pantalla[i].Close;
  Pantalla[i].Free;
  Pantalla[i] := nil;
Teniendo en cuenta que el valor de i se le pasa en el momento de la creación del formulario.

Se produce el error, se acepta el mensaje y todo continua,pero claro los usuarios se preocupan y da una imagen muy pobre de la aplicación

Será muy bienvenida cualquier sugerencia. Gracias a todos. Un saludo.
Responder Con Cita
  #2  
Antiguo 01-09-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
¿Lo has ejecutado paso a paso y verificado si i tiene el valor que tu crees que tiene?
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #3  
Antiguo 01-09-2003
sanxpue sanxpue is offline
Miembro
 
Registrado: jul 2003
Posts: 196
Poder: 21
sanxpue Va por buen camino
Lightbulb

tambien pasa cuando remueves las formas del proyecto..

si es que las removiste debes de usar el showmodal y no nada mas show..

saludos desde Puebla Mexico
asanxt@hotmail.com
Responder Con Cita
  #4  
Antiguo 02-09-2003
Julià T. Julià T. is offline
Miembro
 
Registrado: may 2003
Ubicación: en el teclado
Posts: 314
Poder: 21
Julià T. Va por buen camino
Cita:
'Violación de acceso en la dirección 00503A36 en módulo 'SIGECO.EXE'. Leer de dirección 'FFFFFFFF'. Process stopped. Use Step or Run to continue
Violación de acceso suele ocurrir cuando intentas acceder a una parte de un array que no está accesible Ej: intentas acceder al myarray[7] cuando tan solo tienes hasta myarray[6]

El error FFFFFFFF aparece cuando intentamos acceder a una clase que no se ha creado (falta la línea "myclass.create(parametros)")

Espero que se entienda
Responder Con Cita
  #5  
Antiguo 02-09-2003
Avatar de javiermorales
javiermorales javiermorales is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante
Posts: 272
Poder: 21
javiermorales Va por buen camino
Muchas gracias por vuestras contestaciones, voy a verificar que el item del array al que intento acceder no es nulo y que el indice del mismo es exactamente al que se supone debo acceder.

Cuando tenga los resultados os los hare llegar. Gracias de nuevo.
Responder Con Cita
  #6  
Antiguo 04-09-2003
Avatar de javiermorales
javiermorales javiermorales is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante
Posts: 272
Poder: 21
javiermorales Va por buen camino
Hola a todos, ya he verificado que el indice del array es el correcto y que el valor de ese item no es NULL y es accesible.

Realizando la traza, no se detiene en ninguna línea de codigo, sino que tras terminar el código que debe ejecutar, saca el error, sin realizar parada en línea alguna.

Si se os osurre alguna cosa más que verificar será muy bién venida. Gracias, un saludo.
Responder Con Cita
  #7  
Antiguo 05-09-2003
Julià T. Julià T. is offline
Miembro
 
Registrado: may 2003
Ubicación: en el teclado
Posts: 314
Poder: 21
Julià T. Va por buen camino
Vuelvo a mirar el código que pones y me he dado cuenta de que:

el close, Free, nil, lo deberias poner en la ventana que utilizas con el Show, no en la que lo llama, más o menos así:

procedure Tform1.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
action:=cafree;
end;

si fuera Showmodal si que podrias realizarlo con el código que escribes.
Responder Con Cita
  #8  
Antiguo 05-09-2003
Avatar de javiermorales
javiermorales javiermorales is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante
Posts: 272
Poder: 21
javiermorales Va por buen camino
Es cierto, debería haber puesto el código cmpleto, ya que en realidad, hace lo siguiente:

Código:
Pantalla[i].Close;
if (Pantalla[i] <> NULL) then
begin
  Pantalla[i].Free;
  Pantalla[i] := nil;
end;
Y en el Close del Formulario es donde se realiza el Free y nil. He dejado esa parte aquí, por si por algún error no realizaba la liberación en el formulario, aunque trazándolo nunca llega a ejecutar la parte del condicional, puesto que lo ha liberado antes.

Gracias por contestar.
Responder Con Cita
  #9  
Antiguo 06-09-2003
Julià T. Julià T. is offline
Miembro
 
Registrado: may 2003
Ubicación: en el teclado
Posts: 314
Poder: 21
Julià T. Va por buen camino
Si utilizas un showmodal, el código de la función se detine en ese punto, en cambio si utilizas show no, por lo que el código sigue y se libera el form, con lo que o no lo puedes utilizar o no tiene tiempo a ejecutar el código y da errorres como los que te da

ejempo código con showmodal

Tform1.funcion1
begin
Form2:=Tform2.Create(self);
Form2.Showmodal;
Form2.free;
end;

ejempo código con showmodal
Tform1.funcion1
begin
Form2:=Tform2.Create(self);
Form2.Show;
//no hay free
end;

Tform2.Close .....
begin
action:=caFree;
end;
Responder Con Cita
  #10  
Antiguo 06-09-2003
Julià T. Julià T. is offline
Miembro
 
Registrado: may 2003
Ubicación: en el teclado
Posts: 314
Poder: 21
Julià T. Va por buen camino
perdona las prisa, corrigo el anterior

Si utilizas un showmodal, el código de la función se detine en ese punto, en cambio si utilizas show no, por lo que el código sigue y se libera el form, con lo que o no lo puedes utilizar o no tiene tiempo a ejecutar el código y da errorres como los que te da

Código:
ejempo código con showmodal
Tform1.funcion1
begin
Form2:=Tform2.Create(self);
Form2.Showmodal;
Form2.free;
end;
Código:
ejempo código con show 
Tform1.funcion1
begin
Form2:=Tform2.Create(self);
Form2.Show;
//no hay free se debe liberar en el propio formulario 
end;


Tform2.Close .....
begin
action:=caFree;
end;
Responder Con Cita
  #11  
Antiguo 06-09-2003
Avatar de javiermorales
javiermorales javiermorales is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante
Posts: 272
Poder: 21
javiermorales Va por buen camino
Gracias Julia.T por responder. Te comento un poco más el funcionamiento que tiene la aplicación:

Desde la pantalla principal, que nunca se cierra salvo para finalizar la aplicación, es donde se construyen los formularios, cuando se selecciona la opción de menu, que a su vez construyo dinamicamente basándome en la base de datos donde están las autorizaciones que tenga cada usuario, así como las opciones de menú asociadas y el nombre de cada uno de los formularios que se deben lanzar.

Se utiliza Show y no Showmodal, por que no es el formulario padre quien libera al formulario, sino que en módulo aparte es donde tengo el procedimiento de liberación. Además si utilizase ShowModal, quedaría restringida la utilización de opciones de menú diferentes al mismo tiempo (sabemos que eso no es posible, pero sí podemos ir cambiando de formulario en la ejecución)

Es decir el main crea la clase y lanza el formulario, asignando a un array global de clases el formulario creado. El formulario creado puede terminar su ejecución de dos maneras:

1.- Haciendo click en la cruz superio derecha, con lo que se llama al evento close del formulario:
Código:
Procedimiento Close del formulario
  Pantalla[i].Free;
  Pantalla[i] := nil;
2.- Pulsando la tecla ESC, que esta reprogramada, para llamar a un procedimiento global de liberación:
Código:
Procedimiento Global de Liberación
Pantalla[i].Close;
if (Pantalla[i] <> NULL) then//No se ejecuta Nunca
begin
  Pantalla[i].Free;
  Pantalla[i] := nil;
end;
El error me lo da al utilizar la tecla reprogramada, pero no en ninguna de las líneas de código, sino al termimar de ejecutar todo el código. Realizando las comprobaciones, el formulario se libera y todo funciona correctamente, pero le salta ese error al usuario y no queda demasiado bién.

Muchas Gracias de nuevo Julia, espero haberme explicado un poco mejor esta vez. Un saludo
Responder Con Cita
  #12  
Antiguo 06-09-2003
Julià T. Julià T. is offline
Miembro
 
Registrado: may 2003
Ubicación: en el teclado
Posts: 314
Poder: 21
Julià T. Va por buen camino
¡Entendido!

Me pasó lo mismo en un programa que hize en Delphi 2, ya hace mucho, lo solucioné colocando un manipulador de exepciones global y acallando el error (creo que luego colocando el Action:=caFree en el onclose dejó de hacerlo, y creo que es por eso que siempre coloco este código en los close).

Si estamos en Delphi 5 o superior existe un componente llamado ApplicationEvents en la paleta addictional que tiene un evento llamado onException. Tan solo nos hará falta colocar algo de código
Código:
procedure TForm1.ApplicationEvents1Exception(Sender: TObject;
  E: Exception);
begin
//
end;
para que cuando ocurra no aparezca el error.

el ApplicationEvents lo deberás colocar el la ventana que se produce el error, sea la principal u otra.

Si tienes delphi 4 o inferior, deberia recuperar el programa, para acordarme de como lo hacia.

Espero que esto si te sirva finalmente
Responder Con Cita
  #13  
Antiguo 06-09-2003
Mick Mick is offline
Miembro
 
Registrado: may 2003
Posts: 405
Poder: 21
Mick Va por buen camino
Ocultar la excepcion no es una solucion, es un gravisimo error , porque el bug en el programa sigue existiendo, es como si para parar una epidemia los medicos decidiesen ocultar los cadáveres para que "no se note" .

Si se produce una excepcion
de ese tipo, es posible que alguna parte del programa (variables por ejemplo) se machaquen al azar, o que otros objetos no hayan podido ser destruidos porque una excepcion hace que la ejecucion del programa se interrumpa bruscamente en algun punto.

De modo que a partir de una excepcion de ese tipo cualquier programa quedara en un estado "inestable" no se puede garantizar que siga funcionando correctamente o (lo que es peor) que los resultados que de sean correctos, hasta que se cierre y se vuelva a ejecutar.

Salud2 !!!
Responder Con Cita
  #14  
Antiguo 07-09-2003
Julià T. Julià T. is offline
Miembro
 
Registrado: may 2003
Ubicación: en el teclado
Posts: 314
Poder: 21
Julià T. Va por buen camino
por cierto al puslar la tecla esc se finaliza todo el código tipo

tecla=esc =>
begin
Close;
exit;
end;

o bien queda algo colcago por finalizar

tecla=esc =>
begin
Close;
end;
.... continua el código
Responder Con Cita
  #15  
Antiguo 07-09-2003
Avatar de javiermorales
javiermorales javiermorales is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante
Posts: 272
Poder: 21
javiermorales Va por buen camino
Hola Juliá, este es el código del KeyDown donde se trata la tecla ESC:
Código:
  //Pulsacion de Cancelar (ESC)
  if (Key=VK_ESCAPE) then
  begin
    if not(DataSource3.DataSet.State in [dsInsert,dsEdit]) then
    begin
      Key := 0;
      LiberaPantalla(numpantalla);
    end
    else
      DBEdit18.SetFocus;
    Exit;
  end;
Está hecho de esta manera, para que cuando tenga el DataSource en edición, el Escape tenga su funcionalidad por defecto, es decir deshacer el último cambio. Y lo hace correctamente.

Tiene el Exit al final, porque dentro del KeyDown trato muchas mas teclas y como no puedo utilizar un Case, me veo obligado a hacerlo con if...else. Por eso pongo el Exit, para que no continue con los if...else.

¿Comentas lo del código al final, porque intentaría ejecutar el Exit sobre algo que ya no existe?.

Gracias. Un saludo.
Responder Con Cita
  #16  
Antiguo 07-09-2003
Julià T. Julià T. is offline
Miembro
 
Registrado: may 2003
Ubicación: en el teclado
Posts: 314
Poder: 21
Julià T. Va por buen camino
intenta colocar el exit dentro de la condición aunque creo que no soluciones nada

if (Key=VK_ESCAPE) then
begin
if not(DataSource3.DataSet.State in [dsInsert,dsEdit]) then
begin
Key := 0;
LiberaPantalla(numpantalla);
exit;
end

luego te envio el código que utilizo yo para crear y cerrar una ventana no modal desde otra
Responder Con Cita
  #17  
Antiguo 07-09-2003
Julià T. Julià T. is offline
Miembro
 
Registrado: may 2003
Ubicación: en el teclado
Posts: 314
Poder: 21
Julià T. Va por buen camino
Te muestro el código que utilizo para mostrar los informes de manera no modal y cerrarlos desde una ventana que no es la propia.

El inconveninete que tiene es que de esta manera no se puede acceder a ningun valor ni funcion de la ventana (solo mostrar y cerrar)

Código:
type
  TInformes = class(TForm)
  ...
  public
    class procedure Mostrar(ATag: integer);
    class procedure Tancar;
  end;

Var
 VTag:integer;

class procedure TInformes.Mostrar(ATag:integer);
Var
 I:integer;
 F:Tform;
begin
  For I:=Screen.FormCount-1 downto 0 do
  begin
   F:=Screen.Forms[i];
   if (F is Self) and(Atag<>0) then
    begin
     if (F.Tag=Atag) or (F.Tag+1000=Atag) then
     begin
      f.show;
      F.BringToFront;
      exit;
     end;
   end;
  end;
  VTag:=ATag;
  F:=Create(Application);
  F.FormStyle:=fsMDIChild;
  F.WindowState:=wsMaximized;
  F.BringToFront;
end;

class procedure TInformes.Tancar;
Var
 I:integer;
 F:Tform;
begin
  For I:=Screen.FormCount-1 downto 0 do
  begin
   F:=Screen.Forms[i];
   if (F is Self) then F.Close;  //and tag=num
  end;
end;
Responder Con Cita
  #18  
Antiguo 07-09-2003
Avatar de javiermorales
javiermorales javiermorales is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante
Posts: 272
Poder: 21
javiermorales Va por buen camino
Hola Julià, muchas gracias por tu última respuesta y por el código. Resulta que es bastante similar a como lo hago yo. Te lo adjunto:
1.- Código de creación de Forms
Código:
procedure TMainForm.AbrirForm();
var
  i, j : integer;
  a : boolean;
begin
 i := 0;
 j := 1;
 a := true;
 while (a) do
 begin
   if (Screen.Forms[i].Name = PDatItem(TreeView1.Selected.data)
       ^.Pantalla) then
    a := false
  else
  begin
    if (i < (Screen.FormCount - 1)) then
      i := i+1
    else
    begin
      a := false;
      i := 1000;
    end
  end
 end;
 if (i < 1000) then
   Screen.Forms[i].Show
 else
 begin
   i := 0;
   While (i < listaclass.Count) and (listaclass[i].ClassName <> 
              PDatItem(TreeView1.Selected.data)^.TPantalla) do
        inc(i);
   if (i < listaclass.Count) then //hemos encontrado la clase
   begin
     While (Pantalla[j] <> nil) and (j <= 25) do
       inc(j);
     Application.CreateForm(TFormClass(listaclass[i]),Pantalla[j]);
     IndicePantalla := j;
     Pantalla[j].Show;
   end
 end
end;
El código de cierre de formularios, lo he puesto en otra de las respuestas.

Gracias Julià, si le vieses algo al código, por favor coméntamelo.
Un saludo.
E
Responder Con Cita
  #19  
Antiguo 08-09-2003
Julià T. Julià T. is offline
Miembro
 
Registrado: may 2003
Ubicación: en el teclado
Posts: 314
Poder: 21
Julià T. Va por buen camino
Hola:

He rehecho el código para ir deprisa he hecho mi propia adaptación, me funciona correctamente.

Código:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Controls, Forms, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    Index:integer;
    listaclass:array[1..10] of TFormclass;
    listpant:array[1..10] of TForm;
    function Existe(Nombre: string): boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2, Unit3;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
//relleno los arrays con los forms y TForm
//creo que en tu caso son diferentes
 listaclass[1]:=TForm2;
 listaclass[2]:=TForm3;
 listpant[1]:=Form2;
 listpant[2]:=Form3;
end;

function TForm1.Existe(Nombre:string):boolean;
Var
 i:integer;
begin
 //busca en las ventanas creadas si existe la muestra
 Result:=False;
 For I:=Screen.FormCount-1 downto 0 do
  if Screen.Forms[i].Name = Nombre then
   begin
    Result:=True;
    Screen.Forms[i].Show;
    break;
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  Nombre:string;
begin
 //muestra o crea la ventana con el nomre indicado en el edit1.text
 Nombre:=Edit1.text;
 if Existe(Nombre) then exit;
 For i:=Low(listaclass) to High(listaclass) do
 begin
  if Assigned(listaclass[i]) and (listaclass[i].ClassName='T'+Nombre) then
  begin
    Application.CreateForm(listaclass[i],listpant[i]);
//   listpant[i]:=listaclass[i].Create(Self);   //no hay problema también sirve
   Index := i;
   listpant[Index].Show;
  end;
 end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 //esto cierra la última que has abierto sólo la última
 if Assigned(listpant[Index]) then FreeAndNil(listPant[Index]);
//if Assigned(listpant[Index]) then  listpant[Index].Close;   //no hay problema también sirve
//prefiero el close
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  i: integer;
  Nombre:string;
begin
 //Cierra la ventana indicada en el Edit1.text
 Nombre:=Edit1.text;
 For I:=Screen.FormCount-1 downto 0 do
  if Screen.Forms[i].Name = Nombre then Screen.Forms[i].Close;
end;

end.
Responder Con Cita
  #20  
Antiguo 08-09-2003
Avatar de javiermorales
javiermorales javiermorales is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante
Posts: 272
Poder: 21
javiermorales Va por buen camino
Muchas Gracias Julià. Voy a intentar adaptar el código que me has pasado a mi aplicación. En cuanto tenga los resultados te los comento.

Gracias de nuevo. Un abrazo.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 08:17:10.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi