Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Problema al Cerrar Aplicacion (https://www.clubdelphi.com/foros/showthread.php?t=63829)

Efren2006 04-03-2009 20:48:19

Problema al Cerrar Aplicacion
 
Saludos

Ahora tengo el siguiente problema, mi aplicacion crea los formularios segun la opcion que el usuario seleccione, ademas los tengo dentro de uan BPL por modulo es decir Ejemplo [Contabilidad,Facturacio, Etc] esto esta trabajando perfectamente, el problema es que cuando el usuario tiene abierto por lo menos 1 formulario y trata de cerrar la aplicacion yo coloque en el evento OncloseQuery lo Siguiente;

Código Delphi [-]
 
procedure TMenu.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
Var
  idx:Integer;
Begin
Canclose:=False;
if Application.MessageBox('Desea Salir del Sistema ...?','Salir',
           MB_YESNO+MB_ICONQUESTION+MB_DEFBUTTON2)=IdYes Then
      Begin
      for idx:=Screen.FormCount-1 downto 1 do
          Begin
          if TForm(Screen.Forms[idx]).Name<>'' Then
              If TForm(Screen.Forms[idx]).Owner=Self Then
                 TForm(Screen.Forms[idx]).Close;
          End;
      Canclose:=True;
      end;
end

Cuando efectua este procedimiento, el sistema se queda en un Loop, y da error de memoria, Estoy utilizando Delphi 2009 y me percato que pareciera que no esta haciendole Free al formulario Abierto, pero yo tengo en los formularios en el evento Close;

Código Delphi [-]
 
procedure TFBase.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action:=caFree;
end;

Ya que todos mis Formularios Heredan de un Formulario Base;

Alguna Sugerencia ??

rgstuamigo 04-03-2009 22:05:17

Hola Efren2006 , me gustaria especificara si los formularios los estas creando en forma dinamica es decir en tiempo de ejecucion, o asi como te lo crea el IDE de Delphi por defecto?:confused:

Efren2006 05-03-2009 01:25:00

Cita:

Empezado por rgstuamigo (Mensaje 340211)
Hola Efren2006 , me gustaria especificara si los formularios los estas creando en forma dinamica es decir en tiempo de ejecucion, o asi como te lo crea el IDE de Delphi por defecto?:confused:

Los estoy creando en tiempo de ejecucion,, Son; FormStyle=fsStayOnTop

jconnor82 05-03-2009 07:41:56

Segun lo q haz puesto es logico q entre en un loop infinito, porque, al ejecutar la TForm(Screen.Forms[idx]).Close nuevamente va a entrar a FormCloseQuery y asi susesivamente, lo q podrias hacer es en vez de usar FormCloseQuery usar el evento OnClose.

Código Delphi [-]
procedure TfmMain.FormClose(Sender: TObject; var Action: TCloseAction);
var
  idx:Integer;
begin
  if Application.MessageBox('Desea Salir del Sistema ...?','Salir',
    MB_YESNO+MB_ICONQUESTION+MB_DEFBUTTON2) = IdYes Then
  begin
    for idx:=Screen.FormCount-1 downto 1 do
      begin
        if TForm(Screen.Forms[idx]).Name<>'' Then
          if TForm(Screen.Forms[idx]).Owner=Self Then
            TForm(Screen.Forms[idx]).Close;
      end;
  end else
    Action := caNone;
end;

No lo he probado, y tambien depende en q forma estes usando el evento, supongo y se esta ejecutando en el formulario principal, es una aplicacion MDI??

Efren2006 05-03-2009 16:35:27

Cita:

Empezado por jconnor82 (Mensaje 340260)
Segun lo q haz puesto es logico q entre en un loop infinito, porque, al ejecutar la TForm(Screen.Forms[idx]).Close nuevamente va a entrar a FormCloseQuery y asi susesivamente, lo q podrias hacer es en vez de usar FormCloseQuery usar el evento OnClose.


Código Delphi [-]procedure TfmMain.FormClose(Sender: TObject; var Action: TCloseAction);
var
idx:Integer;
begin
if Application.MessageBox('Desea Salir del Sistema ...?','Salir',
MB_YESNO+MB_ICONQUESTION+MB_DEFBUTTON2) = IdYes Then
begin
for idx:=Screen.FormCount-1 downto 1 do
begin
if TForm(Screen.Forms[idx]).Name<>'' Then
if TForm(Screen.Forms[idx]).Owner=Self Then
TForm(Screen.Forms[idx]).Close;
end;
end else
Action := caNone;
end;




No lo he probado, y tambien depende en q forma estes usando el evento, supongo y se esta ejecutando en el formulario principal, es una aplicacion MDI??


Ya coloque dicho evento en el evento FormClose, igual queda en el loop, entiendo porque piensa que deberia quedar en el lopp, pero no es asi porque yo estoy cerrando son los formularios abierto a partir del formulario prinicipal, tambien valide esto colocando la siguiente pregunta

Código Delphi [-]
 
 if TForm(Screen.Forms[idx]).Name<>Name Then


Mi formulario prinicipal esta creado
Código Delphi [-]
FormStyle = FsNormal


El problema pareciera que cuando ejecuto el evento Close del formulario no esta haciendo el FREE ,, pero ya verifique eso en el formulario base.. la verdad ya he probado de todo..

rgstuamigo 05-03-2009 20:51:48

Cita:

Los estoy creando en tiempo de ejecucion...
Si lo lo estas creando en tiempo de ejecucion y has puesto en el On close este codigo:
Código Delphi [-]
procedure TFBase.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action:=caFree;//aqui estas liberando memoria.
end;
Eso significa que ya no necesitas ir liberando todos los formularios cuando cierres el Principal.Me entiendes?.
Ademas cuando se cierra el principal este automaticamente cierra a todos los formularios de la aplicacion;por tanto tan solo en el evento OnCloseQuery yo pondria tan solo lo siguiente modificando un poco tu codigo:
Código Delphi [-]
if MessageDlg('Desea Salir del Sistema ...?',mtConfirmation,[mbYes,mbNo],0)=mrNo then
   CanClose:=False;//aqui la variable CanClose viene por defecto con True
                   //asi que si me no me preguntase atraves de este dialogo igual se cerraria el formulario.
                   //Este dialogo es tan solo para tener la posibilidad de cambiar dicha 
                   //variable a False para que no se cierre el formulario
Pruebalo..
Saludos..;)

Efren2006 06-03-2009 15:46:04

Saludos a Todos

Gracias por su tiempo en ayudarme con este Problema,,,

Resolvi el problema del Loop, colocando esto;

Código Delphi [-]
 
..
..
for idx:=Screen.FormCount-1 downto 1 do
  If Screen.Forms[idx] is TForm Then
    If TForm(Screen.Forms[idx]).Name<>Name Then
       If TForm(Screen.Forms[idx]).Owner=Self Then
          TForm(Screen.Forms[idx]).Destroy;

Pero al terminar de cerrar la aplicacion me consigo con el siguiente error;
Cita:

Exception EInvalidPointer in module rtl120.bpl at 000087c9

rgstuamigo 20-03-2009 22:27:34

Cita:

Exception EInvalidPointer in module rtl120.bpl at 000087c9
Pues pienso que eso ocurre por estas tratando de liberar un formulario que ya se libero anteriormente.Por eso no se debe utilizar el destructor directamente,para destruir o liberar un objeto en delphi utiliza el metodo Free. Es decir tu ultima linea seria:
Código Delphi [-]
TForm(Screen.Forms[idx]).Free;
Pero insisto de que no es nesesario hacer todo esto:
Código Delphi [-]
for idx:=Screen.FormCount-1 downto 1 do
  If Screen.Forms[idx] is TForm Then
    If TForm(Screen.Forms[idx]).Name<>Name Then
       If TForm(Screen.Forms[idx]).Owner=Self Then
          TForm(Screen.Forms[idx]).Destroy;
por lo anterirmente que comente en el anterior Post;
Saludos...:cool:

Efren2006 20-03-2009 23:07:25

Saludos rgstuamigo

Como comente anteriormente comparto tu teoria, porque anteriormente lo usaba asi, pienso que el problema se debe a que estoy contruyendo estos formularios que se encuentran dentro de una BPL, la verdad ya he hechos muchas pruebas y la verdad la aplicacion falla en algunos equipos y en otros no,,, la verdad estoy por rehacer completamente el formulario Principal para verificar posibles errores..

Gracias por tu tiempo ...


La franja horaria es GMT +2. Ahora son las 21:34:22.

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