Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 16-05-2013
jocaro jocaro is offline
Miembro
 
Registrado: sep 2011
Posts: 104
Poder: 13
jocaro Va por buen camino
Crear varios objetos de un mismo tipo

Hola

En mi aplicación tengo un botón que, cada vez que se pulsa, genera un nuevo objeto con una determinada información. El código es el siguiente

Código Delphi [-]

procedure TSDIAppForm.VentanaNotaClick(Sender: TObject);
var
  sVacio: String;
  tnNodAux: TTreeNode;
  Stream: TStream;
  iLonMat: Integer;
begin

  iLonMat := length(agVentNot);
  SetLength(agVentNot, iLonMat + 1 );

  { Creación de form para ver una nota (se crea un form cada vez que se
    selecciona una nota) }
  agVentNot[iLonMat] := TFrmVerNota.Create(Application);

  { Escribir camino de la nota en cabecera de la ventana }
  tnNodAux := ArbolElementos.Selected;
  agVentNot[iLonMat].Caption := CaminoArbolElementos( tnNodAux, sVacio );

  { Cargar nota en visor TRichView }
  Stream := FrmBasDat.TablaNotas.CreateBlobStream(FrmBasDat.TablaNotas.FieldByName('DesNot'), bmRead);
  agVentNot[iLonMat].RVVerNota.LoadRVFFromStream(Stream);
  agVentNot[iLonMat].RVVerNota.Format;

  agVentNot[iLonMat].Visible := True;

  Stream.Free;

end;


unit VerNota;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,RVScroll, RichView, RVEdit, DBRV, RVStyle,
  RVStr;
type
  TFrmVerNota = class(TForm)
    RVVerNota: TRichView;
    EstiloVerNota: TRVStyle;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FrmVerNota: TFrmVerNota;

implementation

uses
  BasDat;

{$R *.dfm}

end.

Mis dudas son las siguientes:

¿Existe una forma mas elegante de hacerlo que asignándolo a una matriz?
¿Se podría hacer con un objectlist, por ejemplo? En ese caso, ¿como podría ver las propiedades, variables, etc. del objeto, utilizados en el código anterior, ya que lo he intentado y no lo consigo?

¿Al cerrar cualquiera de los forms generados, mediante el aspa de la parte superior derecha, se libera el objeto de éste o hay que mandar un close en el evento FormClose?

Gracias por vuestra atención
Responder Con Cita
  #2  
Antiguo 16-05-2013
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 23
maeyanes Va por buen camino
Hola...

Como bien comentas, puedes hacer uso de la clase TObjectList:

Código Delphi [-]
var
  NoteForm: TFrmVerNota;

begin
  NoteForm := TFrmVerNota.Create(nil);
  // Usas la variable NoteForm para asignar propiedades. Ej:
  NoteForm.Caption := 'Something';
  // FNotes sería un objecto de tipo TObjectList
  FNotes.Add(NoteForm)
end;

// Para referenciar un objeto guardado en el TObjectList:
var
  NoteForm: TFrmVerNota;

begin
  NoteForm := FNotes[i] as TFrmVerNota;
  
  // O de esta forma:
  NoteForm := TFrmVerNota(FNotes[i])
end;

Ahora, si usas Delphi 2010 o superior, podrías usar la clase genérica TObjectList<T>:

Código Delphi [-]
uses
  Generics.Collections;

// Se declara y crea un objecto del tipo TObjectList< TFrmVerNota >:
  FNotes := TObjectList< TFrmVerNota > .Create;

// Se usa este objecto en tu método:
FNotes.Add(TFrmVerNota.Create(nil));

// Al ser un TObjectList que contiene elementos del tipo TFrmVerNota, puedes hacer lo siguiente:
FNotes[FNotes.Count - 1].Caption := 'Something';
FNotes[FNotes.Count - 1].Show

// O usar la forma anterior:
var
  NoteForm: TFrmVerNota;

begin
  NoteForm := TFrmVerNota.Create(nil);
  NoteForm.Caption := 'Something';
  NoteForm.Shot;
  FNotes.Add(NoteForm)
end;

Sobre el liberar el formulario al cerrarlo, tendrías que usar el evento OnClose poniendo el valor de la variable Action en caFree:

Código Delphi [-]
procedure TFrmVerNota.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  // Aquí podrías eliminar el formulario del objeto TObjectList:
  FNotes.Remove(Self)
end;

// Para hacer lo anterior, tendrías que declarar una propiedad en la clase TFrmVerNota en la cual le pases el objeto:
type
  TFrmVerNota = class(TForm)
  private
    FNotes: TObjectList< TFrmVerNota >; // O solo TObjectList
  public
    property FNotes: TObjectList< TFrmVerNota >
      read FNotes
      write FNotes;
  end

// Al crear el formulario haces algo como:
FNotes.Add(TFrmVerNota.Create(nil));
FNotes[FNotes.Count - 1).Notes := FNotes;
// ...
FNotes(FNotes.Count - 1).Show


Espero que con esta pequeña explicación se resuelva tu problema.


Saludos...

Nota: Donde veas < TFrmVerNota > debes ponerlo todo sin espacios, esto lo hice así por que el foro elimina el contenido de <TFrmVerNota> si lo escribo todo junto.
__________________
Lee la Guía de Estilo antes que cualquier cosa. - Twitter

Última edición por maeyanes fecha: 16-05-2013 a las 16:21:42.
Responder Con Cita
  #3  
Antiguo 16-05-2013
jocaro jocaro is offline
Miembro
 
Registrado: sep 2011
Posts: 104
Poder: 13
jocaro Va por buen camino
Muchisimas gracias maeyanes.

De pequeña explicación, nada. Me has dado una respuesta elaborada y muy clara. Me han funcionado correctamente los cambios que he hecho con ObjectList, a partir de tu código y anotaciones.

No he conseguido que funcione el borrado en el ObjectList, seguro que debido a un error mio. Me produce un 'Access violation at address...'.

Me queda la duda de que pasa cuando cierro el form por medio del aspa superior derecha ¿Sólo se hace un .hide del form, pero no se destruye el objeto? ¿Si borro el objeto de la lista de objetos, se pierde su referencia?. Si es así quedaría liberado sólo con esa operación o habría que hacer el Action := caFree de todos modos?

En fin, un saludo y gracias de nuevo.
Responder Con Cita
  #4  
Antiguo 16-05-2013
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 23
maeyanes Va por buen camino
Hola...

El error Access violation at address... se produce por una omisión mía. Te explico: la clase TObjectList puede 'tomar' posesión de los objetos que se agregan, esto se traduce a que, al eliminar un objeto de la lista, esta lo destruye automáticamente.

Para evitar el error de acceso de memoria, tienes que crear el objeto TObjectList pasando False como valor del parámetro del constructor:

Código Delphi [-]
FNotes := TObjectList.Create(False);

con esto le indicas a la lista que no debe destruir los objetos al eliminarlos de la esta.

Entonces el código del evento OnClose ya te debería funcionar sin errores.

Sobre tu duda al cerrar el formulario, si usas el código que te puse de ejemplo, este se destruirá cada vez que uses el botón cerrar del fomulario (la famosa aspa superior derecha )


Saludos...
__________________
Lee la Guía de Estilo antes que cualquier cosa. - Twitter
Responder Con Cita
  #5  
Antiguo 17-05-2013
jocaro jocaro is offline
Miembro
 
Registrado: sep 2011
Posts: 104
Poder: 13
jocaro Va por buen camino
Hola Maeyanes, he cambiado la creación de la lista tal como me comentas, pero sigue produciendo 'Access violation...'

Código Delphi [-]
FNotes := TObjectList.Create(False);

¿Puedes explicarme un poco mas detalladamente el código que me pasas para liberar el formulario? hay detalles que no tengo claros. Por ejemplo:

¿La propiedad sería 'FNotes' o 'Remove'

Código Delphi [-]
    property FNotes: TObjectList< TFrmVerNota >

¿ '.Notes' tengo que definirla a priori?

Código Delphi [-]
FNotes[FNotes.Count - 1).Notes := FNotes;

Gracias una vez mas por todo
Responder Con Cita
  #6  
Antiguo 17-05-2013
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 23
maeyanes Va por buen camino
Hola...

¿Podrías poner el código completo de como lo estás haciendo ahora?


Saludos...
__________________
Lee la Guía de Estilo antes que cualquier cosa. - Twitter
Responder Con Cita
  #7  
Antiguo 21-05-2013
jocaro jocaro is offline
Miembro
 
Registrado: sep 2011
Posts: 104
Poder: 13
jocaro Va por buen camino
Hola Maeyanes, disculpa el retraso. He tenido un pequeño accidente doméstico y no he podido contestar antes.

No puedo poner el código, ya que lo tengo en mi lugar habitual de trabajo y en un par de semanas no podré pasarme por allí.

Si ves alguna manera de contarme la lógica de declaración de la propiedad en la clase TFrmVerNota para pasar el objeto te lo agradecería.

Un saludo
Responder Con Cita
Respuesta



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
Modificar propiedad de varios componentes del mismo tipo chartres Varios 3 30-12-2011 20:59:25
Varios detail en un mismo QReport alastor Impresión 2 27-06-2006 18:30:31
Varios details en un mismo group? subzero Impresión 1 26-09-2005 19:08:34
Como Asignar Variable Tipo Array de Tform a otro Array del Mismo tipo morfeo21 Varios 5 17-08-2004 17:39:51
Varios RemoteDataModule en un mismo servidor Toni Providers 2 02-06-2004 20:50:01


La franja horaria es GMT +2. Ahora son las 19:59:25.


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