2005. október 31., hétfő

Load and save a TStringGrid from/ to a stream


Problem/Question/Abstract:

I have a form with 4 StringGrids which I fill at run time with data. It takes some time to enter the data and so I thought it would save me some time if I could save and load the form with its data - something I've never done in Delphi before. I've sorted the menu and the dialogue boxes but what method do I have to write to save the form, its StringGrids and the data therein - simply?

Answer:

You will have noticed that the StringGrid is a control that does not allow you to enter strings into it at design-time. The reason is that the streaming system cannot handle array properties like Cells, so the standard component streaming is no use for your task. But you can write your own routines to save a StringGrids content, of course. Something like this for example:

procedure SaveGridToStream(aStream: TStream; aGrid: TStringGrid);
var
  i, k: Integer;
  iBuf: Integer;
  S: string;

  procedure WrInt(anInt: Integer);
  begin
    aStream.WriteBuffer(anInt, Sizeof(anInt));
  end;

begin
  with aGrid do
  begin
    WrInt(ColCount);
    WrInt(rowCount);
    for i := 0 to rowCount - 1 do
      for k := 0 to colCount - 1 do
      begin
        S := Cells[k, i];
        WrInt(Length(S));
        if Length(S) > 0 then
          aStream.WriteBuffer(S[1], Length(S));
      end;
  end;
end;

procedure LoadGridFromStream(aStream: TStream; aGrid: TStringGrid);
var
  i, k: Integer;
  iBuf: Integer;
  S: string;

  function RdInt: Integer;
  begin
    aStream.ReadBuffer(Result, Sizeof(Result));
  end;

begin
  with aGrid do
  begin
    ColCount := RdInt;
    RowCount := RdInt;
    for i := 0 to rowCount - 1 do
      for k := 0 to colCount - 1 do
      begin
        iBuf := RdInt;
        if iBuf > 0 then
        begin
          SetLength(S, iBuf);
          aStream.ReadBuffer(S[1], iBuf);
          Cells[k, i] := S;
        end;
      end;
  end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése