Ver Mensaje Individual
  #5  
Antiguo 11-07-2006
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Reputación: 29
Lepe Va por buen camino
Con un poco de código lo verás más claro.

Normalmente querás crear los objetos y añadir los items a mostrar en el combo:
Código Delphi [-]
type TProvincia = class (TObject)
  public
     property Provincia:String read GetProvincia write SetProvincia;
end;


procedure TForm1.AddItems;
var p :TProvincia;
begin
 query1.sql.text := ' select distinct nombreProvincia from Provincias;';
 query1.Open;
 while not query1.eof do // para cada registro
 begin
   p := Tprovincia.Create; // creo en memoria mi objeto
   p.Provincia := query1.Fields[0].AsString;
   Combo1.AddObject(p.Provincia, p); // Añado el Nombre de la Provincia
//                                                 al combo y lo asocio con su objeto
   query1.next;
 end;
end; // AddItems

Si te fijas, no libero los objetos, ya que, como bien has dicho, solo se guarda un puntero, por tanto, el objeto debe existir en memoria mientras queramos acceder a él.

Tambien verás que siempre uso la misma variable "p" para crear los objetos; esto no es problema, ya que al decir "p := Tprovincia.Create" siempre se reserva memoria nueva para la variable "p" en cada iteración del bucle, así que no machacamos objetos en memoria. Cada Objeto creado estará en RAM, y la única forma de acceder a él, es mediante el ComboBox.
Código Delphi [-]
Function TForm1.ConseguirObjetoAsociado:TProvincia;
begin
  Result := nil; // en caso de error devolvemos un puntero nulo.
  if Combobox.ItemIndex = -1 then Exit; 
// No hay seleccionado ningún elemento en el combo,
// se devuelve el puntero nulo y salimos de la función

  Result := TProvincia(Combobox1.Objects[Combobox1.Itemindex]);
end;

Como norma general, si una funcion devuelve un objeto (que en realidad devuelve un puntero a ese objeto), se debe asignar un puntero nulo en caso de fallos. Obviamente cuando se use esta función, siempre se deberá tener en cuenta:
Código Delphi [-]
var x:Tprovincia;
x := ConseguirObjetoAsociado;
if  x <> nil then
  ShowMessage(x.Provincia)
else
  ShowMessage('no se ha encontrado el objeto. No puedo usar la variable X  porque daría un Access Violation');

Despues de este paréntesis, sigo explicando la funcioncita.
Cada Item del Combobox tiene asociado su propio objeto, por tanto, podemos usar el ItemIndex del Combo para acceder a ese objeto.

Se debe hacer un moldeo de Tipos "TProvincia (.....)" porque el combo acepta un TObject o una clase que derive de TObject. Nosotros, que lo hemos programado, sabemos que hemos introducido con AddObject un tipo de datos TProvincia, pues debemos decir al compilador que lo trate como tal, para que podamos acceder a todas las propiedades que tiene dicha Clase.

Por último nos queda un detalle: Liberar los objetos.
Código Delphi [-]
procedure Tform1.VaciarComboYObjetos;
var i:integer;
begin
  for i:=0 to Combobox.Items.count-1 do
     TProvincia(combobox.Objects[i]).Free; // libero cada Objeto de la RAM

  Combobox.Items.Clear;
end;
Despues de vaciar el combo, cualquier intento de acceder a los objetos nos dará un Access Violation. Normalmente se llama antes de liberar el Form de memoria.

Podría parecer que con solo hacer un "comboBox.Items.Clear" se debería destruir los objetos, pero lamentablemente delphi no sabe como tratar el objeto concreto que nosotros hemos añadido.

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