Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Abrir solo una vez un MDIChild (https://www.clubdelphi.com/foros/showthread.php?t=74242)

jafera 07-06-2011 10:40:43

Abrir solo una vez un MDIChild
 
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.

Cita:

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:
Código Delphi [-]
implementation

uses Unit2, Unit3;

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

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

frmChild1:
Código Delphi [-]
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:
Código Delphi [-]
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

Cita:

Empezado por jafera (Mensaje 402909)
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:
Código Delphi [-]
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

Código Delphi [-]
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

Código Delphi [-]
 
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

Código Delphi [-]
 
Action:=caFREE;
Y en el formDestroy

Código Delphi [-]
 
F_Camions:=nil;

Saludos

ecfisa 08-06-2011 15:50:41

Hola Jafera.
Cita:

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


La franja horaria es GMT +2. Ahora son las 13:18:11.

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