Ver Mensaje Individual
  #3  
Antiguo 10-05-2005
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Reputación: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
A ver qué tal parece esta opción

Hola,

Donde dije:

"Yo lo he podido solucionar de esta manera, que, probablemente no sea la mejor. En todo caso a ver qué te parece la solución y la explicación que le doy al error que te encuentras."

Debí decir:

Vale. Hasta aquí el típico párrafo en que uno se lava las manos antes de tratar de indicar la solución de un problema, comprendiendo que lo que va a decir puede estar equivocado (como así ha resultado).

Donde dije:

"Primero el error. Este aparece, si no estoy equivocado, porque, efectivamente, al cerrar una vez la "forma" secundaria liberas de la memoria cualquier referencia de esta."

Debí decir:

Hasta aquí más o menos estoy de acuerdo con lo que pensaba antes. Efectivamente, liberas una referencia, pero no cualquier referencia; y no es que se libere la "forma", pero únicamente una referencia a la misma.

Donde dije:

"Luego, al comprobar que no está creada la forma secundaria para crearla de nuevo se produce un error, porque, no está creada, pero tampoco puede crearse, puesto que su tipo ya no existe en la aplicación: ya se liberó."

Debí decir:

Esto es de lo peor, creo. Como bien dice roman, no se comprueba (con "if not Assigned(Form2) then ...") si la forma ha sido o no creada, sino si la referencia a ella es nula ("nil"). Y el tipo de la forma no puede liberarse: puede liberarse una determinada referencia al tipo, o un objeto de dicho tipo, pero no el tipo como tal.

Donde dije:

"La solución puede que pase por declarar una variable del tipo de la forma en donde vayas a emplear esta. Comprobar que no está ya creada una instancia de esta forma (secundaria) en la variable en cuestión. ¿No lo está? Se crea y se muestra la forma. ¿Lo está? Entonces no hace falta mostrarla, sino darla el foco, si es preciso."

Quise decir:

La solución no pasa por ahí, ya está claro, pero, ¿cómo pude pensar lo contrario? En realidad no hay que crear una variable del tipo de la forma, porque dicha variable ya está creada, quiere decirse, podemos utilizarla. Esta variable no guarda la forma como tal, sino una referencia a ella. Lo que debemos comprobar, como dice roman, es que dicha variable no guarda una referencia nula.

Donde dije:

"Utilizamos el evento "OnClose" de la forma secundaria para dar el valor "caFree" a la variable "Action" de tipo "TCloseAction"."

Debí decir:

Vamos a ver... ¿qué pretendía conseguir con esto? Efectivamente, dando el valor "caFree" a la variable "Action" que podemos encontrar en los parámetros del evento "OnClose" de un formulario, ¿qué liberamos? ¿Liberamos la referencia a dicho formulario? ¿El propio formulario? ¿El tipo del formulario? Liberamos la memoria asignada al objeto del tipo del formulario, pero no la referencia a este, la cual seguirá estando disponible... aunque ya no nos servirá, pues esta referencia será nula.

Donde dije:

"Aquí puedes ver un poco de código:"

Código Delphi [-]
       uses
         Unit2; // Contiene el tipo de una "Forma" secundaria
       
       var // Esta variable contendrá dicho tipo
         Formulario2: TForm2; 
       
       procedure TForm1.Button1Click(Sender: TObject);
       begin
         // Si la forma secundaria no se ha asignado aún
         if not Assigned(Form2) then
         begin
           // Utilizamos "Formulario2" para crear la Forma secundaria
           Formulario2 := TForm2.Create(Self);
           Formulario2.Show; // Y la mostramos
         end else // Si la forma secundaria ya ha sido asignada
           Formulario2.SetFocus; // Enfocamos
       end;

Debí decir:

Aquí está el código tanto de la parte en que se crea el formulario o forma como de la sentencia a utilizar en el evento "OnClose" de dicho formulario:

Código Delphi [-]
  
  (* Desde Form1 mostraremos el formulario o forma Form2 *)
  
  uses
    Unit2; // Contiene TForm2
  
  procedure TForm1.Button1Click(Sender: TObject);
  begin
     If not Assigned(Form2) then // Podría ser: if Form2 = nil then
     begin   
       Form2 := TForm2.Create(Self);
       Form2.Show();
     end else
       Form2.SetFocus();
  end;
  
  (* Evento OnClose de Form2 *)
  
  procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
  begin
    Form2 := nil; // Anulamos la referencia a Form2 existente hasta aquí
  end;

Donde dije:

"No creas que me sé explicar todo lo que trato de explicarte a ti (¿Qué es esto?), al menos no todavía, pero el caso es que funcionar parece funcionar. Pruébalo tú a ver qué tal."

Debí decir:

No tengo mucha idea de cómo lo he hecho, pero, tecleando como un poseso he conseguido solucionar el problema, al menos, aparentemente. Tal vez alguien pueda aportar otro punto de vista, pero, tal vez esto pueda ayudarte en algo.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 10-05-2005 a las 20:41:13. Razón: (corrección del texto)
Responder Con Cita