PDA

Ver la Versión Completa : Abrir solo una vez un MDIChild


jafera
07-06-2011, 10:40:43
Hola a todos.

Estuve buscando la forma de abrir una sola vez un form MDI y encontré varias soluciones en este foro.

Mi pregunta es si los ejemplos que vi, los cuales son basicamente en la llamada del form MDIChild desde el MDIPadre, se pueden aplicar entre dos MDIChild.

Por el momento si desde un child abro el otro child con un dobleclick en un dbgrid, funciona de maravilla. Si desde este segundo child vuelvo a llamar al primero, se me abre una nueva copia del form, cosa que no quiero, quiero que si existe el form llamado me lo muestre con los nuevos datos del registro actual.

He hecho pruebas y no me acaba de convencer pues al cerrar me da errores con el FreeAndNil, actualmente tengo action:=caFree;

Saludos

ecfisa
07-06-2011, 12:46:56
Hola jafera.

Si desde este segundo child vuelvo a llamar al primero, se me abre una nueva copia del form, cosa que no quiero

Una aplicación MDI está compuesta por ventanas hijas, área de cliente o frame y la ventana de clientes. Esta última es la que administra a todas las ventanas MDIChild que de ella dependen.
Para que no te suceda lo que comentas, es necesario que una ventana hija llame a otra mediante la ventana padre.

Para ejemplificar supongamos que tenemos: frmMain (MDIForm) con un TMainMenu y dos TMenuItem, cada uno de los cuales llama a las ventanas frmChild1 y frmChild2 (MDIChilds). En cada ventana hija, además tenemos un TButton que llama a la otra ventana hija.

frmMain:

implementation

uses Unit2, Unit3;

procedure TfrmMain.frmChild1AbrirClick(Sender: TObject);
begin
TfrmChild1.Mostrar;
end;

procedure TfrmMain.frmChild2AbrirClick(Sender: TObject);
begin
TfrmChild2.Mostrar;
end;


frmChild1:

implementation

uses Unit1;

class procedure TfrmChild1.Mostrar;
begin
if not Assigned(frmChild1) then
frmChild1:= TfrmChild1.Create(nil)
else
frmChild1.BringToFront;
end;

procedure TfrmChild1.btnShowChild2Click(Sender: TObject);
begin
frmMain.frmChild2AbrirClick(Self); // llamar a otro MDIChild
end;

procedure TfrmChild1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;

procedure TfrmChild1.FormDestroy(Sender: TObject);
begin
frmChild1:= nil; // necesario por: if not Assigned...
end;


frmChild2:

uses Unit1;

class procedure TfrmChild2.Mostrar;
begin
if not Assigned(frmChild2) then
frmChild2:= TfrmChild2.Create(nil)
else
frmChild2.BringToFront;
end;

procedure TfrmChild2.btnShowChild1Click(Sender: TObject);
begin
frmMain.frmChild1AbrirClick(Self); // llamar a otro MDIChild
end;

procedure TfrmChild2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;

procedure TfrmChild2.FormDestroy(Sender: TObject);
begin
frmChild2:= nil; // necesario por: if not Assigned...
end;

De este modo no te abrirá una nueva copia del form MDIChild.

Saludos.

jafera
07-06-2011, 16:59:15
Gracias Ecfisa, como siempre al rescate de los Delphinaufragos.

Hay una cosa que no entiendo

De donde sale esta linea?

class procedure TfrmChild1.Mostrar;

Saludos

ecfisa
07-06-2011, 17:18:56
Gracias Ecfisa, como siempre al rescate de los Delphinaufragos.

Hay una cosa que no entiendo

De donde sale esta linea?

class procedure TfrmChild1.Mostrar;

Saludos

Es un método de clase, se aplica a una referencia de clase y no necesita de la existencia de una instancia de la misma para ser llamado.

La declaración iría en cada MDIChild:

type
TfrmChild1 = class(TForm)
private
public
class procedure Mostrar;
end;


Saludos.:)

jafera
07-06-2011, 18:08:08
Ahora que tengo 10 minitillos voy a ver si lo pruebo

Saludos

jafera
08-06-2011, 11:50:58
type
TfrmChild1 = class(TForm)
private
public
class procedure Mostrar;
end;


Hola de nuevo, no lo entiendo. si coloco la linea del class me dice que no puede compìlar



[Error] Parcs.pas(202): Unsatisfied forward or external declaration: 'TF_Parcs.Mostrar'

Que puedo estar haciendo mal?

Gracias

ecfisa
08-06-2011, 12:30:17
Hola Jafera.

Aparentemente te falta incluir la unidad en que está declarado 'TF_Parcs' tendría que mirar el código...

Mejor te pongo el código funcional del ejemplo de arriba así lo estudias con tranquilidad.

Un saludo.

jafera
08-06-2011, 15:31:56
Gracias Ecfisa

No se que pasa pero no puedo abrir los archivos zip adjuntos, no solo el tuyo, sino ninguno.

De momento lo he solucionado así y funciona


procedure TF_Parcs.JvDBGrid1DblClick(Sender: TObject);
begin
if not Assigned(F_Camions) then
begin
F_Camions:=TF_Camions.Create(nil);
F_ModulDades.Camions.Locate('ID',Camions_ParcID.Value,[]);
end
else
begin
F_ModulDades.Camions.Locate('ID',Camions_ParcID.Value,[]);
F_Camions.BringToFront;
end;
end;



Y en el formClose


Action:=caFREE;

Y en el formDestroy


F_Camions:=nil;


Saludos

ecfisa
08-06-2011, 15:50:41
Hola Jafera.
No se que pasa pero no puedo abrir los archivos zip adjuntos, no solo el tuyo, sino ninguno.
Ya lo he comentado antes pero me pasaba lo mismo cuando usaba Internet Explorer en Club Delphi y no pude darle solución.
Por ese motivo empecé a usar Mozilla Firefox y nunca más tuve problemas.

Un saludo.

jafera
08-06-2011, 16:58:11
Ahora si lo he descargado con el Mozilla.

Hago pruebas

Saludos