Ver Mensaje Individual
  #14  
Antiguo 31-05-2012
LoPiTaL LoPiTaL is offline
Miembro
 
Registrado: abr 2009
Posts: 168
Reputación: 16
LoPiTaL Va por buen camino
Un apunte de última hora, y no es por ir de "listillo" :P y por favor, corregidme si me equivoco....

El problema que tenías originalmente, era con acceder a los datos del campo "Data" del TreeView, no con la base de datos, ¿correcto?

Tú hacías lo siguiente (lo pongo de nuevo, ya que hace tropecientos mensajes que pasó):

Código Delphi [-]
Nodo1.Data := Pointer(DataModule1.EDBQuery1.Fieldbyname('Codigo').AsString);

Y al hacer:

Código Delphi [-]
ShowMessage(String(Nodo.Data^));

no te funcionaba.

Pues bien, yo creo, independientemente de todo el tema de bases de datos que habéis estado discutiendo (del cual, yo no tengo ni idea), que no te funciona porque el tipo "string" es un tipo manejado, creado y destruido por Delphi cuando se queda sin referencias. Si haces un casting a Pointer, la referencia se pierde y Delphi te destruye la string nada más salir de la función, pudiendo ser reutilizado su espacio.

Por eso tu otra solución SI funciona:

Código Delphi [-]
MiClase.Codigo :=DataModule1.EDBQuery1.Fieldbyname('Codigo').AsString;
Nodo1:=TreeView1.Items.AddChildObject(Nodo0, DataModule1.EDBQuery1.FieldByName('NOMBRE').AsString, MiClase);

ya que tienes una instancia de un objeto NO manejado (de tipo TMiClase), por lo que no se te autodestruye. Y este objeto mantiene una referencia al string (MiClase.Codigo) por lo que tampoco te destruye éste y todo funciona bien.

Otra solución, sin usar clases auxiliares, podría haber sido la siguiente (escrita sobre el navegador y sin probar):

Código Delphi [-]
var
  LPAnsiChar: PAnsiChar;
  LStr: AnsiString;
begin
  //Hago casting a AnsiString porque así cada caracter ocupa un único byte. Para usar 
  //la versión Unicode, en lugar de length, usar la función ByteLength
  LStr:=AnsiString(DataModule1.EDBQuery1.Fieldbyname('Codigo').AsString);
  LPAnsiChar:=AllocMem(length(LStr)+1);
  Move(LStr[1], LPAnsiChar^, length(LStr);
  Nodo1.Data:=LPAnsiChar;
end

Por supuesto, cuando elimines el nodo del TreeView, deberás hacer un Dispose(Nodo1.Data).

Un saludo,
LoPiTaL
Responder Con Cita