Ver Mensaje Individual
  #8  
Antiguo 07-02-2018
Avatar de gatosoft
[gatosoft] gatosoft is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Bogotá, Colombia
Posts: 833
Reputación: 21
gatosoft Va camino a la fama
Buen día,

Personalmente estoy de acuerdo con lo expresado por Roman en el post #9 del hilo que enlazo aquí

Sin embargo hay una solucion que yo utilizo para evitar lidiar con los FreeAndNil, "releases" mal ubicados.

y es la siguiente:

1) Creo un Tform1 que es el MDIform y un tform2 que es el MDIChild
2) Elimino la variable automática que crea el Tform2 (form2), como sugiere ElKurgan
3) en el evento onclose del Tform2 agrego la linea: Action:= caFree;
4) Para efectos de la prueba agrego dos botones u opciones de menú en el form1.

a) el primer boton instancia formularios TForm2 sin asignarlos a variables (pues se liberarán con el Onclose.

Código Delphi [-]
procedure TForm1.NuevoFormulario1Click(Sender: TObject);
begin
  With Tform2.Create(Self) do
     Begin
       inc(contador);
       Caption:= IntTostr(contador);
       show;
     End;
end;

b) el segundo crea un formulario asignado a una única variable llamada MyFormX

Código Delphi [-]
procedure TForm1.formX1Click(Sender: TObject);
begin
  if not Assigned(MyFormX) then
     begin
       MyFormX:= TForm2.Create(Self);
       MyFormX.Show;
     end else
         MyFormX.BringToFront;
end;


PERO...!!! éste útlimo código solo funcionará una vez pues el Action:=caFree, libera la memoria pero la variable queda asignada por tanto Assigned(MyformX) solo será falso la primera vez...

entonces aqui utilizo un truco que me parece bastante seguro: Utilizo una variable de clase para indicar si el formulario está instanciado o no

Código Delphi [-]
unit Unit2;

type
  TForm2 = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
    Class var EstoyOcupado: String;
  end;

y en el Form1 cambio el llamado al boton:
Código Delphi [-]
procedure TForm1.formX1Click(Sender: TObject);
begin
  if not Assigned(MyFormX) or (TForm2.EstoyOcupado <> 'SI') then
     begin
       MyFormX:= TForm2.Create(Self);
       TForm2.EstoyOcupado:='SI';
       MyFormX.Show;
     end else
         MyFormX.BringToFront;
end;


De ésta manera quedan asi los códigos

Form1:
Código Delphi [-]
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    Nuevoform1: TMenuItem;
    NuevoFormulario1: TMenuItem;
    formX1: TMenuItem;
    procedure NuevoFormulario1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure formX1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    contador: Integer;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses Unit2;

Var MyFormX: TForm2;

procedure TForm1.FormCreate(Sender: TObject);
begin
  contador:=0;
end;

procedure TForm1.formX1Click(Sender: TObject);
begin
  if not Assigned(MyFormX) or (TForm2.EstoyOcupado <> 'SI') then
     begin
       MyFormX:= TForm2.Create(Self);
       TForm2.EstoyOcupado:='SI';
       MyFormX.Show;
     end else
         MyFormX.BringToFront;
end;

procedure TForm1.NuevoFormulario1Click(Sender: TObject);
begin
  With Tform2.Create(Self) do
     Begin
       inc(contador);
       Caption:= IntTostr(contador);
       show;
     End;
end;

end.

Form2:
Código Delphi [-]
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
  TForm2 = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
    Class var EstoyOcupado: String;
  end;

implementation

{$R *.dfm}

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

end.
Responder Con Cita