Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   StringGrid rellenar rapidamente. (https://www.clubdelphi.com/foros/showthread.php?t=53780)

byfali 29-02-2008 13:11:27

StringGrid rellenar rapidamente.
 
Hola amigos. Estoy haciendo un programita que me muestra en un StringGrid el contenido de un archivo en modo Hexadecimal.
Todo va bien, el problema es que si el archivo es grande tarda un tiempo considerable ya que se va rellenado sobre la marcha.
Hay algun modo de cargar los datos y despues volcarlos en el StringGrid igual que se vuelcan los datos de un TStringList en un ListBox.?

Tambien me valdria para volcar los datos en un ListView.
Gracias.

Mick 29-02-2008 13:21:35

Es que usar un stringgrid para lo que pretendes no es la solucion correcta, no escala bien, si el archivo es grande seria inusable.

Una solucion mas adecuada es usar un TDrawGrid y en el evento OnDrawCell pintar directamente el valor correspondiente leyendolo del archivo, con esto funcionara para cualquier tamaño de archivo sea de 1K o de 1GB de tamaño. La cache del propio sistema operativo y los buffers de las funciones de lectura de archivos ya se encargaran de evitar que se este leyendo continuamente del disco duro.

Saludos

byfali 29-02-2008 13:24:43

Gracias Mick lo prabare haber que tal.

keyboy 29-02-2008 17:31:05

No estoy muy seguro de qué tanto beneficia usar un DrawGrid. De entrada, el StringGrid también tiene el evento OnDrawCell, pero los datos de cualquier manera se tienen que vaciar sobre el componente. Posiblemente hay algo que no termino de ver, pero veo más conveniente usar un componente como el TListView, o mejor, el TVirtualTreeView, que funcionan en modo virtual. Esto significa que el componente no debe tener todos los datos al mismo tiempo, sino que éstos pueden mantenerse en otra estructura más eficiente (incluso, quizá, el propio disco) y se proporcionan al componente conforme se van requiriendo.

Bye

Mick 29-02-2008 17:48:38

Cita:

Empezado por keyboy (Mensaje 269696)
No estoy muy seguro de qué tanto beneficia usar un DrawGrid. De entrada, el StringGrid también tiene el evento OnDrawCell, pero los datos de cualquier manera se tienen que vaciar sobre el componente. Posiblemente hay algo que no termino de ver, pero veo más conveniente usar un componente como el TListView, o mejor, el TVirtualTreeView, que funcionan en modo virtual. Esto significa que el componente no debe tener todos los datos al mismo tiempo, sino que éstos pueden mantenerse en otra estructura más eficiente (incluso, quizá, el propio disco) y se proporcionan al componente conforme se van requiriendo.

Bye

Ahi esta la clave, lo que no terminas de ver es que "los datos no se tienen que vaciar sobre el componente" un TDrawGrid solo facilita el dibujado en pantalla de un grid pero no hay ningun dato que traspasar al tdrawgrid, exceptuando el indicarle el numero de filas y columnas. Cada vez que el drawgrid te pida dibujar la Celda con coordenadas X,Y simplemente el programa debe leer el dato correspondiente a esas coordenadas del archivo en disco y dibujar ese dato directamente en pantalla.
Es decir un TDrawGrid es como el TVirtualTreeView que comentas.

Da igual de este modo que el archivo ocupe mucho o poco el consumo de memoria ram y la sobrecarga por cargar todos los datos en memoria al principio es CERO porque no se hace.

Saludos

keyboy 29-02-2008 17:51:28

¡Ah! Ok. Gracias por la aclaración. La verdad es que desconocía el uso del DrawGrid y di por sentado algo incorrecto.

Bye

byfali 29-02-2008 18:04:50

La verdad es que nunca e usado DrawGrid. Haber como me las avio para dibujar todos los datos que necesito mostrar.

Os muestro lo que llevo echo para que le echeis un vistazo. De momento solo es el esqueleto.

Solo hay que incluir un StringGrid y un boton.

implementation
{$R *.dfm}
function Min(i,j: Integer): Integer;
begin
if i < j then
Result:= i
else
Result:= j;
end;
procedure TForm15.Button1Click(Sender: TObject);
var
Buffer: array[1..16] of Byte;
F: File;
Leidos: Integer;
i,c,x: Integer;
Offset: Cardinal;
L:String;
begin
i:=0;
c:=0;
OpenDialog1.Execute;
AssignFile(F,OpenDialog1.FileName);
Filemode:= 0;
{$I-}
Reset(F,1);
{$I+}
if IOResult = 0 then
begin
Offset:= 0;
while not Eof(F) do
begin
//**********************
StringGrid1.Cells[i,c]:=IntToHex(Offset,8);
BlockRead(F,Buffer,16,Leidos);
//**************************
//********************************
for i:= 1 to Min(Leidos,8) do
StringGrid1.Cells[i,c]:=IntToHex(Buffer[i],2);
//***********************************
//**********************************
for i:= 9 to Min(Leidos,16) do
StringGrid1.cells[i,c]:=IntToHex(Buffer[i],2);
//***********************************
//***********************************
for i:= Min(Leidos,16) + 1 to 16 do
StringGrid1.Cells[i,c]:=#32;
for x:= 1 to Min(Leidos,16) do
if Char(Buffer[x]) in ['A'..'Z','a'..'z','0'..'9'] then
StringGrid1.Cells[i+x,c]:= Char(Buffer[x])
else
StringGrid1.Cells[i,c]:='.';
StringGrid1.Cells[i,c]:='|';
inc(Offset,Leidos);
inc(c);
i:=0;
// Va aumentado las filas segun lo necesite.
StringGrid1.RowCount:=StringGrid1.RowCount+1;
end;
CloseFile(F);
i:=0;
end;
end;

procedure TForm15.FormCreate(Sender: TObject);
begin
StringGrid1.ColCount:=34;
StringGrid1.DefaultColWidth:=15;
StringGrid1.DefaultRowHeight:=15;
StringGrid1.FixedCols:=0;
StringGrid1.FixedRows:=0;
StringGrid1.ColWidths[0]:=50;
end;

Mick 29-02-2008 18:52:22

Es mucho mas simple que todo lo que estas haciendo con el stringrid, un ejemplo:

Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids;

type
  TFormFile = class(TForm)
    FileGrid: TDrawGrid;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FileGridDrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
  private
    { Private declarations }
    FFileStream: TFileStream;
  public
    { Public declarations }
  end;

var
  FormFile: TFormFile;

implementation

{$R *.dfm}

procedure TFormFile.FormCreate(Sender: TObject);
begin
 FFileStream:= TFileSTream.Create('c:\windows\explorer.exe',fmOpenRead);
 FileGrid.RowCount:= ((FFileStream.Size + FileGrid.ColCount - 1) div FileGrid.ColCount) + 1;
end;

procedure TFormFile.FormDestroy(Sender: TObject);
begin
 FFileStream.Free;
end;

procedure TFormFile.FileGridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
 Car:Char;
begin
  FFileStream.Position:= ARow * FileGrid.ColCount + ACol;
  FFileStream.Read( Car,1);
  FileGrid.Canvas.TextRect(Rect,Rect.Left,Rect.Top, IntToHex(Ord(Car),2) );
end;

end.

Faltarian algunos detallitos como comprobaciones para evitar que se pinte una fila y coordenada que realmente
no se corresponde con ningun byte en el fichero en la ultima fila de grid, pero bueno deberia ser suficiente para
darte una idea de como se hace y solo falta ampliarlo un poco para que muestre la informacion en ascii, etc.

Saludos

byfali 01-03-2008 09:53:59

Gracias Mick lo probare.

byfali 01-03-2008 12:18:34

Lo que yo quiero hacer es que me muestre el archivo de la siguiente manera, igual que un editor hexadecimal. Que es como lo muestra en el codigo que puse como muestra.

00000000:45 53 54 4F 20 45 53 20 ..... :ESTO ES UNA .....
00000010:42 41 .... :PR

Lo podria hacer tambien con DrawGrid.?

JoseFco 25-03-2008 00:25:19

Hola amigos.

Cita:

Empezado por byfali (Mensaje 269928)
Lo que yo quiero hacer es que me muestre el archivo de la siguiente manera, igual que un editor hexadecimal. Que es como lo muestra en el codigo que puse como muestra.

00000000:45 53 54 4F 20 45 53 20 ..... :ESTO ES UNA .....
00000010:42 41 .... :PR

Lo podria hacer tambien con DrawGrid.?

Interesante lo que quieres hacer.Y muy interesante la pregunta.:confused:

A ver si los maestros nos dan una pista por donde comenzar.;)

Un Saludo.


La franja horaria es GMT +2. Ahora son las 10:39:41.

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