2

它与...有关TListItems.DefineProperties...这是我的写作尝试:

  Stream := TFileStream.Create('ListView.dat', fmCreate);
  Writer := TWriter.Create(Stream, 4096);
  TListItemsHelper(ListView.Items).DefineProperties(Writer);
  Writer.Free;
  Stream.Free;

...它显然有效,但阅读代码

  Stream := TFileStream.Create('ListView.dat', fmOpenRead or fmShareDenyWrite);
  Reader := TReader.Create(Stream, 4096);
  TListItemsHelper(ListView.Items).DefineProperties(Reader);
  Reader.Free;
  Stream.Free;

... 不使用文件内容填充项目。我在这里做错了什么?

4

1 回答 1

3
procedure ListViewSaveToStream(aListView: TListView; Stream: TStream);
var
  i: integer;
  aItem: TListItem;
  n: longint;
  buffer: smallint;
  b: boolean;
  s: string;
begin
  Stream.Size := 0;
  n := aListView.Items.Count;
  Stream.Write(n, SizeOf(n));

  if n > 0 then
  begin
    if aListView.ItemFocused <> nil then
      n := aListView.ItemFocused.Index
    else
      n := -1;
    Stream.Write(n, SizeOf(n));

    for i := 0 to aListView.Items.Count - 1 do
    begin
      aItem := aListView.Items[i];

      s := aItem.Caption;
      buffer := Length(s);
      Stream.Write(buffer, SizeOf(buffer));
      if buffer > 0 then
        Stream.Write(s[1], buffer);

      s := aItem.SubItems.CommaText;
      n := Length(s);
      Stream.Write(n, SizeOf(n));
      if n > 0 then
        Stream.Write(s[1], n);

      b := aItem.Checked;
      Stream.Write(b, SizeOf(b));

      buffer := aItem.ImageIndex;
      Stream.Write(buffer, SizeOf(buffer));

      buffer := aItem.StateIndex;
      Stream.Write(buffer, SizeOf(buffer));

      buffer := aItem.OverlayIndex;
      Stream.Write(buffer, SizeOf(buffer));

      buffer := aItem.Indent;
      Stream.Write(buffer, SizeOf(buffer));

      n := integer(aItem.Data);
      Stream.Write(n, SizeOf(n));

      b := aItem.Selected;
      Stream.Write(b, SizeOf(b));

    end;
  end;
end;

procedure ListViewVLoadFromStream(aListView: TListView; Stream: TStream);

var
  i: integer;
  aItem: TListItem;
  cnt, n, ItemFocusedIndex: longint;
  buffer: smallint;
  b: boolean;
  s: string;
begin
  aListView.Items.BeginUpdate;
  try
    aListView.Items.Clear;

    Stream.Position := 0;

    Stream.Read(cnt, SizeOf(cnt));
    if cnt > 0 then
    begin
      aListView.AllocBy := cnt;

      Stream.Read(ItemFocusedIndex, SizeOf(ItemFocusedIndex));

      for i := 0 to cnt - 1 do
      begin
        aItem := aListView.Items.Add;

        Stream.Read(buffer, SizeOf(buffer));
        if buffer > 0 then
        begin
          SetLength(s, buffer);
          Stream.Read(s[1], buffer);
          aItem.Caption := s;
        end;

        Stream.Read(n, SizeOf(n));
        if n > 0 then
        begin
          SetLength(s, n);
          Stream.Read(s[1], n);
          aItem.SubItems.CommaText := s;
        end;

        Stream.Read(b, SizeOf(b));
        aItem.Checked := b;

        Stream.Read(buffer, SizeOf(buffer));
        aItem.ImageIndex := buffer;

        Stream.Read(buffer, SizeOf(buffer));
        aItem.StateIndex := buffer;

        Stream.Read(buffer, SizeOf(buffer));
        aItem.OverlayIndex := buffer;

        Stream.Read(buffer, SizeOf(buffer));
        aItem.Indent := buffer;


        Stream.Read(n, SizeOf(n));
        aItem.Data := TObject(n);

        Stream.Read(b, SizeOf(b));

      end;
    end;


  finally
    aListView.Items.EndUpdate;
  end;
end;

procedure LVSaveToFile(const Filename: string; aListView: TListView);
var
  FS: TFileStream;
begin
  FS := TFileStream.Create(Filename, fmCreate);
  try
    ListViewSaveToStream(aListView, FS);
  finally
    FS.Free;
  end;
end;

procedure ListViewLoadFromFile(const Filename: string; aListView: TListView);

var
  FS: TFileStream;
begin
  if FileExists(Filename) then
  begin
    FS := TFileStream.Create(Filename, fmOpenRead or fmShareDenyNone);
    try
      ListViewVLoadFromStream(aListView, FS);
    finally
      FS.Free;
    end;
  end;
end;

// Example...
procedure TForm3.Button1Click(Sender: TObject);
begin
  LVSaveToFile('C:\temp\test.sav', ListView1);
end;

procedure TForm3.Button2Click(Sender: TObject);
begin
  ListViewLoadFromFile('C:\temp\test.sav', ListView2);

end;
于 2012-11-10T08:05:52.403 回答