Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 11-05-2015
oscjae oscjae is offline
Miembro
 
Registrado: may 2005
Posts: 70
Poder: 19
oscjae Va por buen camino
Como liberar frame

Hola, tengo dudas si es correcto eliminar un frame como lo hago, os pongo el ejemplo

Tengo un tipo creado por mi, un registro, y un array abierto de ese registro

Código Delphi [-]
type
  TReg= record
              vCampo1:Real;
              vCampo2:Integer;
              vFrame:TFrame;
            end;
  TLista= array of TReg;

Evidentemente el frame se crea en tiempo de ejecucion, cuando inicializo la variable de tipo TLista hago lo siguiente

Código Delphi [-]

procedure InicializarLista;
var
  i:Integer;
begin
  for i:=0 to Length(vLista)-1 do
    FreeAndNil(vLista[i].vFrame);
  
  SetLength(vLista,0);
end;

Seria correcto liberar el frame de esa forma, gracias!!!
Responder Con Cita
  #2  
Antiguo 11-05-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola oscjae.

En líneas generales la idea es correcta, pero para obtener los límites del arreglo dinámico usa las funciones Low y High:

Código Delphi [-]
procedure LiberarLista;
var
  i: Integer;
begin
  for i:= Low( vLista ) to High( vLista ) do
    if Assigned( vLista[i].vFrame ) then
      FreeAndNil( vLista[i].vFrame );

  SetLength( vLista, 0 );
end;

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #3  
Antiguo 11-05-2015
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Respuesta corta: Sí, si todos los frames tienen el mismo Owner.

Respuesta larga: No es aconsejable porque...

Ese código te dará problemas si los frames están en diferentes Owners. Cuando creas el Frame, le tienes que pasar el Dueño que lo destruirá; si se destruye el form, hara un "frame.free" y tu array se queda apuntando a una zona de memoria que ya ha sido liberada, por tanto, al liberar tu array, petará el programa con un "Access Violation". Desde ese que ha petado hasta el final del array, se quedan en memoria porque no han podido liberarse.

PD: Yo odio los arrays, prefiero un TList o TObjectList.
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #4  
Antiguo 11-05-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Lepe.

Es muy acertada tu observación sobre el peligro con los diferentes Owners y dependerá del código de creación ( que no tenemos a la vista ).

Dada la forma en que oscjae hacía la liberación, partí del supuesto que en la creación fijaba a nil como propietario de los frames.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #5  
Antiguo 12-05-2015
oscjae oscjae is offline
Miembro
 
Registrado: may 2005
Posts: 70
Poder: 19
oscjae Va por buen camino
Esta seria la forma de crearlo

Código Delphi [-]
vLista[vPosicion].vFrame:=TFame.Create(nil);
vLista[vPosicion].vFrame.Parent:=vPanelParent;
vLista[vPosicion].vFrame.Align:=alClient;

El panel en el que lo coloco (vPanelParent) también seria destruido, ya que uso un ScrollBox para ir creando paneles en tiempo de ejecución y colocando dentro los frame, cuando e de eliminar uno por la razón que sea, elimino el frame y también el panel, no se si es la mejor forma de crear un frame en tiempo de ejecución, hasta ahora siempre lo había hecho así.
Responder Con Cita
  #6  
Antiguo 12-05-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola oscjae.

Todos los descendientes de TComponent poseen la propiedad Owner que contiene (o no) al componente propietario y esta se determina por el valor pasado al parámetro en la creación. El propietario se encargará de liberar la memoria del componente poseido cuando él mismo sea liberado.

Si fijas la propiedad Owner a nil,
Código Delphi [-]
  Frame := TFame.Create( nil );
estas indicando que no tiene propietario; por lo que liberar la memoria queda bajo tu responsabilidad y es correcto que lo hagas.

Cita:
Empezado por oscjae Ver Mensaje
El panel en el que lo coloco (vPanelParent) también seria destruido, ya que uso un ScrollBox para ir creando paneles en tiempo de ejecución y colocando dentro los frame, cuando e de eliminar uno por la razón que sea, elimino el frame y también el panel...
Realmente ahora no se si visualizo claramente la acción, por que van apareciendo nuevos actores como los Panels y el ScrollBox.

Pero, si el Frame debe liberarse cuando lo hace el Panel contenedor, bién podrías hacer al Panel el Owner del frame, delegandole la responsabilidad de su liberación. Y si todo debe destruirse al destruirse el ScrollBox, podrías usar este como Owner... Todo depende del órden en que se vayan creando y se necesiten ir liberando frames y panels.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #7  
Antiguo 12-05-2015
oscjae oscjae is offline
Miembro
 
Registrado: may 2005
Posts: 70
Poder: 19
oscjae Va por buen camino
Hola ecfisa, la verdad es que como tu dices, todo seria mas sencillo si le doy Owner, el Owner como tu dices seria el panel, el scrollbox nunca se destruye, la idea es ir creando varios TPanel cuando se necesiten, y dentro del panel ira el frame, y claro, también esta la posibilidad de eliminar ese panel, con el frame, claro está, haciéndolo de la forma que tu dices, pasando como parámetro al Create el panel imagino que haciendo un
Código Delphi [-]
FreeAndNil(vPanel)
sería suficiente para no tener que hacer nada con el frame, que lo eliminará su propietario.

Gracias!!!
Responder Con Cita
  #8  
Antiguo 17-05-2015
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Llego 5 días tarde, pero en fin, daré mi opinión, ya que me doy por aludido en el tema.

Cuando he estado en una situación similar (scrollBox con Tframes), la forma más rápida de sincronizar ambos es:
- Los frames y paneles con Owner al ScrollBox
- Al borrar un panel, refrescar todo , es decir, hacer un scrollbox.DestroyComponents (que no debería usarse... pero está ahí para ser usado ), y después inicializar el array (poniendo los frames del array a nil, ya que el ScrollBox los liberó). Por ultimo, creo todos los paneles/frames de nuevo.

Otro método (sería lo suyo, pero implica más trabajillo), usar el Notification, me explico:

Cuando un componente del Form se va a liberar, informa a su dueño (si lo tiene) de este hecho, de forma que el dueño, no intentará liberarlo cuando se cierre. Ejemplito:

Un form con un botón y un TEdit, en el botón pones el código "edit1.Free".
Ejecutas el proyecto, pulsas el botón (el Edit desaparece del Form) y cierras el proyecto con la X roja.
No produce ningún error, porque el Edit informó al Form que se iba a liberar y ya el Form lo quitó de su lista de componentes que controla su destrucción.
Si el Form intenta liberar por segunda vez el Edit,daría un Access Violation.

Solo hay un problema: que tu array se entere que el componente frame se ha liberado. Para eso, puedes guardar en el Frame.Tag el índice donde se encuentra en vLista.

No tenemos ese código, pero en algún momento harás algo así:
vLista[n].vFrame := FrameRecienCreada;
pues agregas otra línea:
FrameRecienCreada.Tag := n ;

Y ahora en el form, añades lo siguiente:
Código Delphi [-]
type  TForm1 = class(TForm)
  private
    { Private declarations }
  protected
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;

  public
    { Public declarations }

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Notification(AComponent: TComponent;
  Operation: TOperation);
  var indice: Integer;
begin

// AComponent es el componente del Form que se va a liberar. Todavía está vivo.
// Operation puede ser opInsert (que se va a insertar en el Form) o bien opRemove (que se va a quitar del Form)
  inherited Notification(AComponent, Operation);
  if (AComponet is TFrame) and (operation = opRemove) then begin
    indice := TFrame(Acomponet).Tag;
    vLista[indice].vFrame := nil ;
  end;
end;

Saludos!
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Acceder desde un WebBrowser a un frame que esta dentro de otro frame. deneus Delphi para la web 1 25-10-2014 18:51:58
Como liberar el qreport ingabraham Impresión 2 28-01-2009 02:38:23
mostrar frame como modal peccatum Varios 19 05-06-2008 20:18:23
Como saber si me frame esta creado en cierto evento? Albano OOP 2 16-03-2007 00:13:44
Como acceder a los componentes de un frame? CORBATIN OOP 7 25-07-2003 21:24:23


La franja horaria es GMT +2. Ahora son las 18:23:30.


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
Copyright 1996-2007 Club Delphi