PDA

Ver la Versión Completa : Abstract Error al cerrar aplicación


jymy788
01-07-2005, 11:23:37
Buenas a todos.

Tengo un problemón. Tengo mi aplicación Delphi (con Delphi 7) que permite cambiar de tipo de usuario desde dentro, sin cerrar la aplicación. En el cambio de usuario, dependiendo del usuario, tiene unos permisos u otros, muestra y esconde menús, componentes....

El caso es que si cambio más de una vez de usuario, al cerrar la aplicación, me da el típico Abstract Error o/y Access Violation y aunque sé que tiene que ver con destroys y demás, no consigo encontrar donde.

Os pongo parte de mi código a ver si se os ocurre algo.

Gracias de antemano

procedure TFormMain.BitBtnChangeUserClick(Sender: TObject);
var
ok : boolean;
begin
if ((Application.MessageBox(pChar(BwUserChange),
pchar(BcAtencion), mb_ICONQUESTION or mb_OKCANCEL) = IDOK)) then
begin
Application.Initialize;
Application.Title := 'madd02';
//leemos parametros de ejecucion
ok := BfProSetOpen();

if Assigned(FormListOutput) then
begin
FormListOutput.Close;
FormListOutput.Destroy;
end;


if Assigned(FormSelectAvanzado) then
begin
FormSelectAvanzado.Close;
end;

FormMain.Destroy;

// Seleccion de usuario
Application.CreateForm(TFormMain, FormMain);
FormMain.IniForm(ok);

if (BvUserApli = BcProUserCentral) then
begin
BvUserApli := BcProUserMuni;
end
else
begin
BvUserApli := BcProUserCentral;
end;

// comprobamos si se ha selecionado usuario
if (BvUserApli <> '') then
begin
// cargamos entorno
SetLength(Permisos, 0);
BfProLoadOptionUser();
// Validamos entorno
BfForEntorno(FormMain);
// Lista de Output
Application.CreateForm(TFormListOutput, FormListOutput);
// inicializamos el estado de autenticación para el informe corporativo
// restringido
BvProValidInfCorpRes := false;
if (BvUserApli = BcProUserCentral) then
begin
// desactivamos menus propios de SADD
FormListOutput.FLBInfSelected.Visible := false;
// selector avanzado
//Application.CreateForm(TFormSelectAvanzado, FormSelectAvanzado);
end;

// inicio
Application.Run;
end;
end;
end;



En el evento OnClose del Main tengo lo siguiente:

for cont := (MDIChildCount - 1) downto 0 do
MDIChildren[cont].Close;
Action := CaFree;

Y ya no sé por donde tirar. Sé que no es aconsejable utilizar Destroy, he probado con Free, incluso con Release en todos los sitios donde se me ha ocurrido pero nada.

Lo dicho, gracias por vuestro tiempo

kalimero
01-07-2005, 11:40:35
hola.

¿has probado a poner un punto de ruptura en el código y localizar mas exactamente donde te da el error?

Saludos

jymy788
01-07-2005, 11:43:16
Sip, y si te digo donde me da igual te entra la risa. En la unidad Controls, en el evento onMouseUp, vamos que no, que no puede ser......

Lepe
01-07-2005, 13:33:33
if Assigned(FormListOutput) then
begin
FormListOutput.Close;
FormListOutput.Destroy;
end;


Destroy no se puede llamar, tienes que llamar a Free, por otra parte, despues de destruirlo, FormListOutput (que en realidad es un puntero) no queda fijado a nulo, por tanto, puede entrar en ese if dando Access violation.

Useasé:

if Assigned(FormListOutput) then
begin
FormListOutput.Close;
freeAndNil(FormListOutput);
end;


Deberíamos ver que haces en el evento Onclose de cada formulario.

PD: Por favor,Edita el mensaje original y encierra el código entre

[ delphi ]
aqui vuestro codigo
[ /delphi ]

(sin espacios entre corchetes) Así consigues que respete el identado y aparezca las palabras reservadas en negrita y colores.

otras etiquetas:
code
sql
php
quote (citar un texto dicho por otra persona) [quote=Lepes] se transforma
en "Originalmente publicado por Lepes"




procedure Saludos();
begin
ShowMessage(' Un saludo y hasta luego');
end;


Un saludo

jymy788
01-07-2005, 14:02:00
sorry por lo de las etiquetas, se me pasó por completo

Este es mi código en el onClose


procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
var
cont : integer;
begin
for cont := (MDIChildCount - 1) downto 0 do
MDIChildren[cont].Close;

Action := CaFree;
end;



Había probado ya el FreeAndNil pero nada, me sigue fallando

De todas formas tengo un ejecutable (50k) que me he creado que me lo ejecuto al destruir la aplicación cuando cierro del todo el programa y con eso me evito las exepciones. Es una "chapuza" pero funciona y como urge....

De todas formas, una pregunta, como puedo obtener el PID del proceso "ejecutable.exe" de mi aplicación???

Un saludo

roman
01-07-2005, 17:55:45
Destroy no se puede llamar, tienes que llamar a Free


Bueno, esto no es del todo correcto. Se recomienda usar Free en lugar de Destroy mas no es es una obligación. Free lo que hace es no fallar si el objeto es nil y como en este caso se verifica primero que no lo sea pues da un poco lo mismo.

// Saludos

Lepe
01-07-2005, 20:55:01
Se agradece la aclaración Roman


Lo que no acabo de comprender es por qué usas Application.Initalize dentro de un botón. Si ese botón está en la forma principal, entonces qué tienes en el .dpr ¿?

Un saludo