Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Error al abrir un formulario (https://www.clubdelphi.com/foros/showthread.php?t=71541)

jafera 25-12-2010 23:32:05

Error al abrir un formulario
 
Buenas a todos.

Tengo una aplicación en D6, con Firebird como base de datos, es una aplicacióm MDI y tengo un problema que no siempre se produce, lo cual no me ayuda en nada en aislarlo.

Ejecuto en Main Form (MDI), desde allí llamo a un Form child con la siguiente instruccion:

Código Delphi [-]
 
F_Parcs:=TF_Parcs.Create(self);

Este form tiene un JVDbgrid con una serie de registros de un Dataset, si hago doble click en una linea del Grid, esto me llama a un nuevo form con la siguiente sintaxis:

Código Delphi [-]
 
F_Camions:=TF_Camions.Create(Application);
F_ModulDades.Camions.Locate('ID',Camions_ParcID.Value,[]);

La primera vez que hago un doble click, abre sin ningun problema el form, pero a veces cuando llamo a un segundo registro desde el mism grid, despues de haber cerrado el primero

Código Delphi [-]
Action:=CaFree;

me lanza un error de access violation at adress....

Alguien me puede hacer un F1 con este prolema?

Gracias por adelantado

Josep

ecfisa 26-12-2010 07:51:56

Hola.

Agregá en a tus forms MDIChilds el evento OnDestroy con la siguiente línea:

Código Delphi [-]
procedure TNombreDelForm.FormDestroy(Sender: TObject);
begin
  NombreDelForm:= nil;
end;

Ya que con
Código Delphi [-]
Action:= caFree
no estás destruyendo inmediatamente el form, solo le estás indicando a Windows que puede disponer de la memoria ocupada por dicho form
cuando él lo considere necesario.

También podés destruirlo en el evento OnClose:
Código Delphi [-]
procedure TNombreDelForm.FormClose(Sender: TObject; var Action: TCloseAction);;
begin
  Action:= caFree;
  NombreDelForm:= nil;
end;

Pero me parece que el evento OnDestroy es más adecuado.

Saludos.

jafera 29-12-2010 01:49:53

Gracias Ecfisa.

He probado tus indicaciones y funciona, no da el error de access violation, pero ahora lo que pasa es que el form queda minimizado y no se destruye.

Esto es correcto?

Debo poner algo más?

Es que si le pongo el action:=cafree y el form:=nil en el onclose sigue fallando.

Saludos

Josep

ecfisa 29-12-2010 12:33:38

Hola jafera.

Por favor, aclarame dos dudas:
. ¿ F_Camions es MDIChild ?
. ¿ Podrías poner el trozo de código donde lo creas y mostras? (Show/ShowModal)


Saludos.

jafera 29-12-2010 12:49:57

Gracias Ecfisa.

El metodo de llamada es el que puse en el primer post del hilo

Código Delphi [-]
 
procedure TF_Parcs.JvDBGrid1DblClick(Sender: TObject);
begin
        F_Camions:=TF_Camions.Create(Application);
        F_ModulDades.Camions.Locate('ID',Camions_ParcID.Value,[]);
end;

Veo que tras las pruebas el problema sigue siendo en action:=caFree, con el destroy a nil funciona bien pero no me lo cierra.

El form style es fsMDIChild

Saludos

Josep

ecfisa 29-12-2010 14:38:43

Hola jafera.

Llamando a F_Camions desde F_Parcs de este modo:
Código Delphi [-]
...
procedure TF_Parcs.MostrarChild(FrmClass: TFormClass);
var
  i: Integer;
begin
  for i:= 0 to Screen.FormCount -1 do
    if Screen.Forms[i] is FrmClass then
    begin
      Screen.Forms[i].WindowState:= wsNormal;
      Screen.Forms[i].BringToFront;
      Exit;
    end;
  with FrmClass.Create(Application) do Show;
end;

procedure TF_Parcs.DBGrid1DblClick(Sender: TObject);
begin
  MostrarChild(TF_Camions);
end;

Y teniendo en F_Camions:
Código Delphi [-]
...
procedure TF_Camions.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action:= caFree;
end;

procedure TF_Camions.FormDestroy(Sender: TObject);
begin
  F_Camions:= nil;
end;
No tendrías que tener ningun inconveniente.

Para salir de toda duda hice la prueba y el form se cierra correctamente sin arrojar ninguna excepción.

Saludos.

jafera 29-12-2010 15:41:27

Gracias Ecfisa.

He puesto todo lo que me dices y funciona, pero al darle varias veces, reiteradamente, dobleclick en el grid, abrir, cerrar, abrir, cerrar, al cabo de varios intentos sale el maldito mensaje de access error

Josep

ecfisa 29-12-2010 18:16:23

Hola.

Debe haber algún código más involucrado que provoca el fallo. Usando sólamente el código que te puse no me dá ese error...
Revisá bién los métodos y eventos de TF_Camions poniendo breaks y usando Trace Into.

Espero lo resuelvas pronto.

Un saludo.

jafera 21-01-2011 10:43:32

Buenas a todos.

Despues de unos dias fuera de servicio, retomé el problema en cuestión y gracias a un hilo en el que se hablaba de eurekalogs, lo instalé y di con la solución.

Eureka me dio error en las lineas siguientes:

Código Delphi [-]
 
procedure TF_Camions.DBCheckBox3Click(Sender: TObject);
begin
if DBCheckBox3.Checked = True then
        begin
                F_Camions.DBEdit10.Visible:=True;
                F_Camions.Label14.Visible:=True;
        end
        else
        begin
                F_Camions.DBEdit10.Visible:=False;
                F_Camions.Label14.Visible:=False;
        end;
end;

Todo parece correcto y siempre habia funcionado, lo que hice fue anular F_Camions de las lineas quedando el código así

Código Delphi [-]
 
procedure TF_Camions.DBCheckBox3Click(Sender: TObject);
begin
if DBCheckBox3.Checked = True then
        begin
                DBEdit10.Visible:=True;
                Label14.Visible:=True;
        end
        else
        begin
                DBEdit10.Visible:=False;
                Label14.Visible:=False;
        end;
end;

y ya no ha fallado más. No se si el llamar a un componente de un form con el nombre del form delante puede afectar así pero......

Gracias por vuestra ayuda.

Josep


La franja horaria es GMT +2. Ahora son las 07:47:38.

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