Board index » delphi » StringGrid LoadFromFile/SaveToFile LoadFromStream/SaveToStream

StringGrid LoadFromFile/SaveToFile LoadFromStream/SaveToStream

On p. 363 of Tom Swan's book, "Delphi Development for Windows 95,"
he shows an example of reading a StringGrid using a loop with
LoadFromFile for each row in the StringGrid.  When I use very
similar code in an example, I only get the first line loaded by
LoadFromFile for all lines.  What am I missing?

I've tried using LoadFromStream instead of LoadFromFile, but
still only get the first line back, but lines after the
first one are blank.  In Ray Lischner's book, "Secrets of
Delphi 2", he says (on p. 58) that LoadFromStream ignores
the current stream position for the source and destination
stream.  So I guess this means I only get the first line using
LoadFromStream.

I can use a SaveToStream in a loop to save a StringGrid
(SaveToFile overwrote the same file with each row!), but
how can I read it back?

Thanks in advance for any help.
--
Earl F. Glynn          EarlGl...@WorldNet.att.net
EFG Software              913/859-9557  Voice/Fax
   Scientific/Engineering/Medical Applications
             Overland Park, KS  USA

 

Re:StringGrid LoadFromFile/SaveToFile LoadFromStream/SaveToStream


Quote
Earl F. Glynn wrote:
> I can use a SaveToStream in a loop to save a StringGrid
> (SaveToFile overwrote the same file with each row!), but
> how can I read it back?

OK, I didn't plan on answering my own question, but the following
seems to work:

{Save TStringGrid to file}
procedure TForm1.btnSaveClick(Sender: TObject);
  VAR
    j     :  INTEGER;
    Stream:  TFileStream;
begin
  Stream := TFileStream.Create(GridFile, fmCreate);

  Stream.Write(StringGrid.RowCount, SizeOf(StringGrid.RowCount));
  Stream.Write(StringGrid.ColCount, SizeOf(StringGrid.ColCount));

  TRY
    FOR j := 0 TO StringGrid.RowCount-1 DO
    BEGIN
      StringGrid.Rows[j].SaveToStream(Stream);
    END
  FINALLY
    Stream.Free
  END
end;

{Restore TStringGrid from File}
procedure TForm1.btnRestoreClick(Sender: TObject);
  VAR
    ColCount:  LongInt;
    i       :  INTEGER;
    j       :  INTEGER;
    RowCount:  LongInt;
    Stream  :  TFileStream;
    Strings :  TStringList;
begin
  TRY
    Strings := TStringList.Create;
    Stream := TFileStream.Create(GridFile, fmOpenRead);

    Stream.Read(RowCount, SizeOf(RowCount));
    Stream.Read(ColCount, SizeOf(ColCount));

    StringGrid.RowCount := RowCount;
    StringGrid.ColCount := ColCount;

    TRY
     {Unfortunately, this reads the whole file, not just one row.
     This is a bad design to have "SaveToStream" and "LoadFromStream"
     work so differently with a TStringGrid.}
     Strings.LoadFromStream(Stream);
    FINALLY
      Stream.Free
    END;

    {One dimensional count = product of two dimensions}
    IF   Strings.Count = StringGrid.RowCount * StringGrid.ColCount
    THEN BEGIN
       FOR j := 0 TO StringGrid.RowCount-1 DO
         FOR i := 0 TO StringGrid.ColCount-1 DO
          StringGrid.Cells[i,j] := Strings[i + j*StringGrid.ColCount]
    END
    ELSE BEGIN
      MessageDlg('Corrupt StringGrid File <' + GridFile + '>', mtError,[mbOK],0);
      EXIT
    END

  FINALLY
    Strings.Free
  END
end;

Tom Swan should update his example.  It does not work.

--
Earl F. Glynn          EarlGl...@WorldNet.att.net
EFG Software              913/859-9557  Voice/Fax
   Scientific/Engineering/Medical Applications
             Overland Park, KS  USA

Other Threads