2008-12-14 13 views
8

Quiero crear un control de lista de reproducción. Tengo mucha información para mostrar en una TStringList. Quiero asignar un registro a TStringGrid.Objects en lugar de a un objeto porque muchos objetos pueden tardar un tiempo en crear/destruir. También lleva mucha RAM.Quiero asignar un registro a TStringList.Objects

Un registro será mucho más rápido y delgado. ¿Cómo puedo hacer eso?

TYPE 
AMyRec= packed record 
     FullName  : string[255];  
     RelativePath : boolean;   
     IsInvalid : boolean;   
     InCache  : boolean;   
     etc 
     end; 
+1

¿Cómo está creando sus registros? Usar New (PMyRec) tomará una cantidad de tiempo similar (o cualquier otro método que los cree en el montón) –

Respuesta

1

puede utilizar el puntero de registro.

List.AddObject(MyRecord.FullName, @MyRecord); 
+0

No, no puedes hacer eso. El registro es más grande que cuatro bytes. Clavija cuadrada, agujero redondo. –

+1

Sí, puedes. Cada Tlist tiene un Objeto de 4 bytes que puede usar para cualquier propósito. Puede asignar su registro y establecer este objeto como un puntero al registro para que pueda encontrarlo fácilmente. Esta es la respuesta correcta. – lkessler

+0

¿No necesitarías asegurarte de poner el registro en el montón en lugar de la pila? Si está en la pila, quedará obsoleto cuando se salga del alcance. –

0

asignar la memoria para los registros también lleva tiempo.

cree su registro y coloque el puntero a los objetos en la lista de cadenas.

6

Puede usar un TList en un puntero de su registro.

Ej:

Type  
PMyrec = ^AMyRec; 

uso

var 
    MyRec : PMyRec; 
new(MyRec); 
MyRec^.Fullname := 'test'; 
MyRec^.RelativePath := false; 

etc

{Mi lista es una lista que tiene crear otro lugar}

MyList.Add(MyRec); 

Usted tendrá que manejar la eliminación de artículos del li st ejemplo

Dispose(PMyRec(MyList[Index]));

Para utilizar un elemento de la lista:

var 
    MyRec : PMyRec; 

PMyRec := MyList.Items[i]; 
txtBox.Text = PMyRec^.Fullname; 

etc

1

SOLUCIONADO
He intentado algo como esto ahora (basado en el ejemplo de KiwiBastard):

Type 
AMyRec= packed record 
     FullName  : string[255]; 
     RelativePath : boolean; 
     IsInvalid : boolean; 
     end; 
PMyrec = ^AMyRec; 

procedure TPlaylst.Button1Click(Sender: TObject); 
VAR MyRec1: PMyRec; 
    PlaylistCtrl: TStringGrid; 
begin 
{SET} 
new(MyRec1); 
MyRec1^.Fullname := 'test'; 
MyRec1^.RelativePath := false; 
PlaylistCtrl.Objects[1,1]:= Pointer(MyRec1); 


{GET} 
... 
end; 

+1

De nuevo, solo haga una conversión de tipo: PlaylistCtrl.Objects [1,1]: = Puntero (MyRec1); y al revés para obtener los datos de nuevo: MyRec: = TMyRec (PlaylistCtrl.Objects [1,1]); –

+0

Un objeto tiene cuatro bytes más que el registro correspondiente. Y el segundo elenco de tipos de Mike debería ser PMyRec, no TMyRec. –

+0

Entonces, ¿usar registros en lugar de objetos "comerá" aproximadamente la misma cantidad de RAM? – Ampere

1

¿Estás seguro de que estás dispuesto a asignar todos esos objetos? Al observar la estructura del registro, parece que desea un objeto por fila, no por celda. Para hacerlo, tiene al menos 2 opciones:

  1. (Mi favorito debido a la libertad que brinda) Utiliza TDrawGrid en su lugar y dibuja el contenido de su celda manualmente. ¡Realmente no es tan difícil!
  2. Hace un objeto que encapsula este registro. Es una tarea fácil, así, como por ejemplo:

type 
    TMyRec= packed record 
    FullName  : string[255]; 
    RelativePath : boolean; 
    IsInvalid : boolean; 
    end; 
    TMyData = object (TObject) 
    private 
    FData: TMRec; 
    public 
    constructor Create(AData: TMyRec); 
    property FullName: String read FData.FullName write FData.FullName; 
    property RelativePath: Boolean read FData.RelativePath write FData.RelativePath; 
    property IsInvalid: Boolean read FData.IsInvalid write FData.IsInvalid; 
    end; 

... 

constructor TMyData.Create(AData: TMyRec); 
begin 
    FData := AData; 
end; 

Ahora cada vez que desee conectar sus datos a la red que acaba de empacar en ese objeto y, a continuación, puede utilizar la colección de objetos.

Ahora, en lugar de pasar por todos los problemas, simplemente cree un controlador de eventos para TDrawGrid.DrawCell como

procedure TMainForm.GrdPathsDrawCell(Sender: Object; ...);

uso GrdPaths.Canvas.Handle con DrawText Unicode o si se necesita el uso DrawTextW (ambos vienen de API de Windows por lo que hay un montón de ejemplos de cómo usarlo) y usted usted y su cliente guardar mucha frustración, memoria y, sobre todo, tiempo.

Cuestiones relacionadas