Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Acces Violation al crear un Form (https://www.clubdelphi.com/foros/showthread.php?t=78896)

jpgonzalez 23-05-2012 18:09:34

Acces Violation al crear un Form
 
Buenas para todos...

Hace poco empece a migrar las aplicaciones que tengo en Delphi 5 hacia Delphi XE, y en una de las mismas me sale un "acces violation at address..." al crear un form.
El codigo es el que sigue:

Código Delphi [-]
   //action que se ejecuta al pulsar el BtnUsuarios que la tiene asociada, y abre el Form de usuarios
   procedure TFrmMain.actABMUsuariosExecute(Sender: TObject);  
   begin
      FrmABMUsuarios:= TFrmABMUsuarios.Create(self);
      FrmABMUsuarios.ShowModal;
      FrmABMUsuarios.Free;
   end;

   //action que se ejecuta al pulsar el BtnPerfilUsuario que la tiene asociada, y abre el Form de perfiles de usuarios
   procedure TFrmMain.actABMPerfildeUsuarioExecute(Sender: TObject);  
   begin
      FrmABMPerfilDeUsuario:= TFrmABMPerfilDeUsuario.create(self);
      FrmABMPerfilDeUsuario.ShowModal;
      FrmABMPerfilDeUsuario.Free;
   end;

Lo que pasa es que en el primer click en BtnUsuarios el FrmABMUsuarios se muestra perfectamente.
Si quiero pulsar nuevamente el BtnUsuarios o el BtnPerfilUsuario me tira "access violation".

Probe cambiando el create(self), create(nil) y create(application)...
Probe reiniciando la maquina por si la memoria habia quedado mal...
Sinceramente no se que es lo que pasa, ni porque tira ese error, si debbugueando veo que pasa por el FrmABMUsuarios.Free.

Por ultimo, cuando cierro el form (click derecho - close page), me tira un "invalid pointer operation".

Bueno, espero haber sido claro... desde ya muchas gracias... abrazo!!!

oscarac 23-05-2012 18:17:52

has probado quitando el free?

y colocandolo despues de donde invocas a los formularios

Caminante 23-05-2012 18:21:12

Me parece que despues de hacer free al formulario debes asignar nil a la variable.

Espero te sirva

Saludos

ecfisa 23-05-2012 18:33:53

Hola jpgonzalez.

¿ Podrías poner el código de los eventos OnClose de los tres forms ?

Es decir de: FrmMain, FrmABMUsuarios y FrmABMPerfilDeUsuario y si en alguno utilizas el evento OnDestroy también.

Saludos.

jpgonzalez 24-05-2012 13:12:54

Cita:

Empezado por oscarac (Mensaje 433322)
has probado quitando el free?

y colocandolo despues de donde invocas a los formularios

Buenas oscarac, la verdad que siempre use la misma logica en D5 y nunca tuve problemas. De hecho, en DXE hay llamadas donde esta secuencia me funciona perfectamente y en otras llamadas tira el Access Violation.
De todas maneras, me parece que el free no esta liberando el Form... mas abajo pongo el codigo. Abrazo y muchas gracias!!!



Cita:

Empezado por Caminante (Mensaje 433325)
Me parece que despues de hacer free al formulario debes asignar nil a la variable.

Espero te sirva

Saludos

Buenas Caminante, al igual que le dije a oscarac, mepa que algo con el tema del free y el nil hay... abajo pongo el codigo que le puse para probar.
Abrazo y muchasw gracias!!!



Cita:

Empezado por ecfisa (Mensaje 433329)
Hola jpgonzalez.

¿ Podrías poner el código de los eventos OnClose de los tres forms ?

Es decir de: FrmMain, FrmABMUsuarios y FrmABMPerfilDeUsuario y si en alguno utilizas el evento OnDestroy también.

Saludos.

Buenas ecfisa, nunca programe el evento onClose de los Forms... como dije anteriormente en D5 yo usaba esa secuencia de comandos y funcionaba perfectamente.
Habra diferencias en el manejo de los Forms o de memoria entre D5 y DXE???... ah, cabe aclarar que el D5 lo usaba desde el entorno de Borland y el DXE desde Embarcadero, capaz que eso tambien tenga que ver. Abrazo y muchas gracias!!!

Bueno, las soluciones propuestas me llevaron a probar con el siguiente codigo:
Código Delphi [-]
   procedure TFrmMain.actABMUsuariosExecute(Sender: TObject);
   begin
      if (FrmABMUsuarios = nil) then begin
         FrmABMUsuarios:= TFrmABMUsuarios.Create(self);
      end;
      FrmABMUsuarios.ShowModal;
      FrmABMUsuarios.Free;
      if(FrmABMUsuarios = nil) then begin
        ShowMessage('Se libero FrmABMUsuarios');
      end;
   end;

y me di cuenta de algunas cosas:
1- En el segundo click al Btn que abre FrmABMUsuarios, no entra al "if (FrmABMUsuarios = nil)"
2- Nunca entra en el "if(FrmABMUsuarios = nil)"

Supongo entonces que el form debe quedar en memoria, o algo por el estilo...
De todas maneras sigo sin entender el motivo por el cual me tira el "Acces Violation" cuando quiero abrir otro Form diferente, es decir, si luego de abrir el FrmABMUsuarios y cerrarlo, quiero abrir FrmABMPerfilDeUsuario.

Nuevamente muchas gracias a todos, sigo probando a ver que pasa... Abrazo!!!!

jpgonzalez 24-05-2012 14:05:19

Buenas para todos nuevamente...
Luego de probar y probar varias soluciones sin éxito, y pensando que el error estaba en la llamada al Form, descubri accidentalmente el problema real.

En realidad lo que estaba provocando el error es un componente que tenia en los Forms, el TDaoGrid.
Este es un componente de D5, que lo pude hacer compilar e instalarlo en DXE.
Por ese motivo, habia forms que abrian y cerraban correctamente y otros no... porque los que abrian y cerraban correctamente no tenian DaoGrid.
Este componente me es muy átil porque permite insertar imagenes dentro de la grilla, por la propiedad AllowIncSeach, que permite hacer búsquedas escribiendo en la grilla.

Como no encontré un componente similar para DXE, le "adapte" el de D5, y evidentemente esto no quedo bien, aunque figura instalado correctamente.

Nuevamente muchas gracias a todos, y comparto la solución para que lo tengan en cuenta... si hay un form que no quiere andar, revisar los componentes que usa!!!!

Abrazo!!!!!

ecfisa 24-05-2012 14:10:30

Hola jpgonzalez.

En el código de tu primer mensaje:
Código Delphi [-]
 ...
  FrmABMUsuarios:= TFrmABMUsuarios.Create(self);
  FrmABMUsuarios.ShowModal;
  FrmABMUsuarios.Free;
...
No parece haber nada que esté provocando ese error, es por eso que te pregunté por los eventos OnClose y OnDestroy, pero al mencionar que no los usas, quizá debas revisar en los eventos OnCreate y Onshow de dicho form.

Cita:

y me di cuenta de algunas cosas:
1- En el segundo click al Btn que abre FrmABMUsuarios, no entra al "if (FrmABMUsuarios = nil)"
2- Nunca entra en el "if(FrmABMUsuarios = nil)"
Eso es por que haciendo:
Código Delphi [-]
   FrmABMUsuarios.Free;
se libera la memoria pero no se ajusta el valor de la variable a nil, para eso hay que hacer:
Código Delphi [-]
  FrmABMUsuarios.Free;
  FrmABMUsuarios:= nil;
O de otro modo:
Código Delphi [-]
  FreeAndNil(FrmABMUsuarios);

Saludos.

jpgonzalez 24-05-2012 15:27:00

Groso ecfisa...
Muy clara tu explicación...
A pesar de que el error no tenia nada que ver con la liberación del Form, voy a usar esta explicación para la futura codificación.

Abrazo y muchas gracias!!!!


La franja horaria es GMT +2. Ahora son las 11:25:17.

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