PDA

Ver la Versión Completa : Destroy en OnClose de MDIChild


ixMike
03-10-2006, 19:25:27
Amigos del foro:

En un programa DMI que estoy desarrolando tengo un menú en la ventana madre, y al cual (en parte) deshabilito si no hay ventanas hijas. En la ventana hija (es siempre la misma, la creo cuantas veces necesite), en su evento OnClose coloco lo siguiente:


Procedure TFHija.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Destroy;
frmMain.ActualizarMenus;
end;


Hago esto porque es la única forma de actualizar el menú, porque si lo coloco en el evento OnDestroy no funciona.

Pero, ¿es esto correcto? ¿Hay alguna otra forma mejor de hacerlo?

Gracias.

roman
03-10-2006, 19:31:43
Creo que estaría mejor así:


Procedure TFHija.FormClose(Sender: TObject; var Action: TCloseAction);
begin
frmMain.ActualizarMenus;
Action := caFree;
end;


// Saludos

ixMike
03-10-2006, 19:35:42
Pues no
porque al llamar a ActualizarMenus la ventana sigue existiendo y entonces el menu no cambia para nada (por eso tuve que recurrir a lo que antes he puesto), pero gracias de todas formas

roman
03-10-2006, 19:55:37
Cierto, no había caido en eso. Pero a ver, lo que haces puede darte problemas por varias razones:

1. Se aconseja el uso de Free en lugar de Destroy;
2. No se aconseja destruir un formulario desde alguno de sus eventos y en su lugar debe usarse Action := caFree en el evento OnClose.

Te pongo una forma de hacer lo que deseas. Esta ya la he probado :)

1. Al formulario hijo déjalo sólo con el Action := caFree en el OnClose.
2. Cuando crees un nuevo formulario hijo, le pides que notifique a su padre cuando fallezca :eek:


with TFormHijo.Create(...) do
begin
FreeNotification(Self);
end;


3. En el formulario padre redefine el método Notification para recibir tal notificación:


type
TFormPadre = class(TForm)
protected
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
end;

implementation

procedure TFormPadre.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;

{ Si el hijo se muere y ya no hay más (MDIChildCount = 0) ... }
if (AComponent is TFormHijo) and (Operation = opRemove) and (MDIChildCount = 0) then
ActualizarMenus;
end;


// Saludos

seoane
03-10-2006, 20:15:56
Sin palabras Roman, me encanta cuando te sacas cosas como esta de la manga. Esta me la guardo ...

roman
03-10-2006, 20:28:43
Pues te lo agradezco. De hecho, en mi opinión/gusto, esta técnica es la más apropiada para el sempiterno problema de crear un formulario sólo si no existe ya:


if not Assigned(FormHijo) then
FormHijo := TFormHijo.Create(...);

FormHijo.Show;


Es el padre quien pone en nil la referencia FormHijo cuando recibe la notificación de defunción.

// Saludos

ixMike
05-10-2006, 19:25:53
Muchísimas gracias.;)

Como siempre, sencillo y eficaz. :rolleyes:

Además, esto me va a ir de maravilla para otros muchos programas futuros (y algún otro presente)