• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 450
  • Last Modified:

How to load and save listview content

Hi,

I am using a working code to load and save the content of a listview.
Until Espasquier came with a more sufisticated code. That I want to
use but can read!

Can someone please help me to adjust the code of Espasquier
with the settings I use in my code:

procedure TMainForm.FormCreate(Sender: TObject);
begin
  if FileExists('Data1\Glucose.sav') then LoadListViewToFile(lstvGlucose, 'Data1\Glucose.sav');
  if FileExists('Data1\Bolus.sav') then LoadListViewToFile(lstvBolus, 'Data1\Bolus.sav');
  if FileExists('Data1\FoodDB.sav') then LoadListViewToFile(lstvFoodDB, 'Data1\FoodDB.sav');
  if FileExists('Data1\OwnDB.sav') then LoadListViewToFile(lstvOwnDB, 'Data1\OwnDB.sav');
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  SaveListViewToFile(lstvGlucose, 'Data1\Glucose.sav');
  SaveListViewToFile(lstvBolus, 'Data1\Bolus.sav');
  SaveListViewToFile(lstvFoodDB, 'Data1\FoodDB.sav');
  SaveListViewToFile(lstvOwnDB, 'Data1\OwnDB.sav');
end;

Thank you in advanced.

Peter



My code:

procedure TMainForm.FormCreate(Sender: TObject);
begin
  if FileExists('Data1\Glucose.sav') then LoadListViewToFile(lstvGlucose, 'Data1\Glucose.sav');
  if FileExists('Data1\Bolus.sav') then LoadListViewToFile(lstvBolus, 'Data1\Bolus.sav');
  if FileExists('Data1\FoodDB.sav') then LoadListViewToFile(lstvFoodDB, 'Data1\FoodDB.sav');
  if FileExists('Data1\OwnDB.sav') then LoadListViewToFile(lstvOwnDB, 'Data1\OwnDB.sav');
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  SaveListViewToFile(lstvGlucose, 'Data1\Glucose.sav');
  SaveListViewToFile(lstvBolus, 'Data1\Bolus.sav');
  SaveListViewToFile(lstvFoodDB, 'Data1\FoodDB.sav');
  SaveListViewToFile(lstvOwnDB, 'Data1\OwnDB.sav');
end;

procedure TMainForm.LoadListViewToFile(AListView: TListView; sFileName: string);
var
  F: TFileStream;
  IdxItem, IdxSubItem, IdxImage: Integer;
  W, ItemCount, SubCount: Word;
  pText: PChar;
  PTemp: PChar;
  MySignature: array [0..2] of Char;
  sExeName: string;
begin
  with AListView do
  begin
    ItemCount := 0;
    SubCount  := 0;
    sExeName := ExtractFileName(sFileName);
    if not FileExists(sFileName) then
    begin
      MessageBox(Handle, PChar(Format(Msg1, [sExeName])), 'I/O Error', MB_ICONERROR);
      Exit;
    end;
    F := TFileStream.Create(sFileName, fmOpenRead);
    F.Read(MySignature, SizeOf(MySignature));
    if MySignature <> 'LVF' then
    begin
      MessageBox(Handle, PChar(Format(Msg2, [sExeName])), 'I/O Error', MB_ICONERROR);
      Exit;
    end;
    F.Read(ItemCount, SizeOf(ItemCount));
    Items.Clear;
    for idxItem := 1 to ItemCount do
    begin
      with Items.Add do
      begin
        F.Read(SubCount, SizeOf(SubCount));
        F.Read(IdxImage, SizeOf(IdxImage));
        ImageIndex := IdxImage;
        F.Read(w, SizeOf(w));
        pText := StrAlloc(w + 1);
        pTemp := StrAlloc(w + 1);
        F.Read(pTemp^, W);
        StrLCopy(pText, pTemp, W);
        Caption := StrPas(pText);
        StrDispose(pTemp);
        StrDispose(pText);
        if SubCount > 0 then
        begin
          for idxSubItem := 1 to SubCount do
          begin
            F.Read(w, SizeOf(w));
            pText := StrAlloc(w + 1);
            pTemp := StrAlloc(w + 1);
            F.Read(pTemp^, W);
            StrLCopy(pText, pTemp, W);
            Items[idxItem - 1].SubItems.Add(StrPas(pText));
            StrDispose(pTemp);
            StrDispose(pText);
          end;
        end;
      end;
    end;
    F.Free;
  end;
end;

procedure TMainForm.SaveListViewToFile(AListView: TListView; sFileName: string);
var
  idxItem, idxSub, IdxImage: Integer;
  F: TFileStream;
  pText: PChar;
  sText: string;
  W, ItemCount, SubCount: Word;
  MySignature: array [0..2] of Char;
begin
  with AListView do
  begin
    ItemCount := 0;
    SubCount  := 0;
    MySignature := 'LVF';
    F := TFileStream.Create(sFileName, fmCreate or fmOpenWrite);
    F.Write(MySignature, SizeOf(MySignature));
    if Items.Count = 0 then
      ItemCount := 0
    else
      ItemCount := Items.Count;
    F.Write(ItemCount, SizeOf(ItemCount));
    if Items.Count > 0 then
    begin
      for idxItem := 1 to ItemCount do
      begin
        with Items[idxItem - 1] do
        begin
          if SubItems.Count = 0 then
            SubCount := 0
          else
            SubCount := Subitems.Count;
          F.Write(SubCount, SizeOf(SubCount));
          IdxImage := ImageIndex;
          F.Write(IdxImage, SizeOf(IdxImage));
          sText := Caption;
          w     := Length(sText);
          pText := StrAlloc(Length(sText) + 1);
          StrPLCopy(pText, sText, Length(sText));
          F.Write(w, SizeOf(w));
          F.Write(pText^, w);
          StrDispose(pText);
          if SubCount > 0 then
          begin
            for idxSub := 0 to SubItems.Count - 1 do
            begin
              sText := SubItems[idxSub];
              w     := Length(sText);
              pText := StrAlloc(Length(sText) + 1);
              StrPLCopy(pText, sText, Length(sText));
              F.Write(w, SizeOf(w));
              F.Write(pText^, w);
              StrDispose(pText);
            end;
          end;
        end;
      end;
    end;
    F.Free;
  end;
end;

ESPASQUIER:

// GLOBAL STREAM UTILS : Load/Save Int/Strings

procedure StreamWriteInt(aStream:TStream;Val:Integer);
begin
 aStream.Write(Val,sizeof(Val)); 
end;

function  StreaReadInt(aStream:TStream):Integer;
begin
 aStream.Read(Result,sizeof(Result));
end; 

procedure StreamWriteString(aStream:TStream;aString:String);
Var
 L:Integer;
begin
 L:=Length(aString);
 StreamWriteInt(L);
 if L>0 Then aStream.Write(PChar(@aString[1])^,L*sizeof(Char));
end;
 
function StreamReadString(aStream:TStream):String;
Var
 L:Integer;
begin
 L:=StreaReadInt(aStream);
 SetLength(Result,L);
 if L>0 Then aStream.Read(PChar(@Result[1])^,L*sizeof(Char));
end;

//======== Load/Save ListView in stream ========

procedure StreamWriteListView(aStream:TStream;aListView:TListView);
Var
 i,j:integer;
begin
 StreamWriteInt(aStream,aListView.Items.Count);
 for i:=0 to aListView.Items.Count-1 do
  with aListView.Items[idxItem - 1] do
   begin
    StreamWriteString(aStream,Caption);
    StreamWriteInt(aStream,ImageIndex);
    StreamWriteInt(aStream,Subitems.Count);
    for j:=0 to Subitems.Count-1 do StreamWriteString(aStream,Subitems[j]);
   end;
end;

procedure StreamReadListView(aStream:TStream;aListView:TListView);
Var
 N,i,NS,j:integer;
begin
 aListView.Clear;
 N:=StreamReadInt(aStream);
 for i:=0 to N-1 do
  with aListView.Items.Add do
   begin
    Caption:=StreamReadString(aStream);
    ImageIndex:=StreamReadInt(aStream);
    NS:=StreamReadInt(aStream,Subitems.Count);
    for j:=0 to NS-1 do Subitems.Add(StreamReadString(aStream));
   end;
end;

//======== Load/Save ONE ListView in a file ========

procedure SaveListViewToFile(AListView: TListView; sFileName: string);
var
 F: TFileStream;
begin
 F := TFileStream.Create(sFileName, fmCreate or fmOpenWrite);
 try
  StreamWriteListView(F,AListView);
 finally
  F.Free;
 end;
end;

procedure LoadListViewToFile(AListView: TListView; sFileName: string);
var
 F: TFileStream;
begin
 F := TFileStream.Create(sFileName, fmOpenRead);
 try
  StreamReadListView(F,AListView);
 finally
  F.Free;
 end;
end;

Open in new window

0
peterkiers
Asked:
peterkiers
  • 3
  • 2
1 Solution
 
Mahdi78Commented:
Like this?

procedure SaveListViewToFile(AListView: TListView; sFileName: string);
var
 F: TFileStream;
begin
 F := TFileStream.Create(sFileName, fmCreate or fmOpenWrite);
 try
  StreamWriteListView(F,AListView);
 finally
  F.Free;
 end;
end;

procedure LoadListViewToFile(AListView: TListView; sFileName: string);
var
 F: TFileStream;
begin
 F := TFileStream.Create(sFileName, fmOpenRead);
 try
  StreamReadListView(F,AListView);
 finally
  F.Free;
 end;
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  SaveListViewToFile(lstvGlucose, 'Data1\Glucose.sav');
  SaveListViewToFile(lstvBolus, 'Data1\Bolus.sav');
  SaveListViewToFile(lstvFoodDB, 'Data1\FoodDB.sav');
  SaveListViewToFile(lstvOwnDB, 'Data1\OwnDB.sav');
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  if FileExists('Data1\Glucose.sav') then LoadListViewToFile(lstvGlucose, 'Data1\Glucose.sav');
  if FileExists('Data1\Bolus.sav') then LoadListViewToFile(lstvBolus, 'Data1\Bolus.sav');
  if FileExists('Data1\FoodDB.sav') then LoadListViewToFile(lstvFoodDB, 'Data1\FoodDB.sav');
  if FileExists('Data1\OwnDB.sav') then LoadListViewToFile(lstvOwnDB, 'Data1\OwnDB.sav');
end;
0
 
Mahdi78Commented:
ok, this is mine

procedure LoadListViewToFile(AListView: TListView; sFileName: string);
var
  F: TFileStream;
begin
  F := TFileStream.Create(sFileName, fmOpenRead or fmShareDenyWrite);
  try
    F.ReadComponent(AListView);
  finally
    F.Free;
  end;
end;

procedure SaveListViewToFile(AListView: TListView; sFileName: string);
var
  F: TFileStream;
begin
  F := TFileStream.Create(sFileName, fmCreate or fmShareCompat);
  try
    F.WriteComponent(AListView);
  finally
    F.Free;
  end;
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  SaveListViewToFile(lstvGlucose, 'Data1\Glucose.sav');
  SaveListViewToFile(lstvBolus, 'Data1\Bolus.sav');
  SaveListViewToFile(lstvFoodDB, 'Data1\FoodDB.sav');
  SaveListViewToFile(lstvOwnDB, 'Data1\OwnDB.sav');
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  if FileExists('Data1\Glucose.sav') then LoadListViewToFile(lstvGlucose, 'Data1\Glucose.sav');
  if FileExists('Data1\Bolus.sav') then LoadListViewToFile(lstvBolus, 'Data1\Bolus.sav');
  if FileExists('Data1\FoodDB.sav') then LoadListViewToFile(lstvFoodDB, 'Data1\FoodDB.sav');
  if FileExists('Data1\OwnDB.sav') then LoadListViewToFile(lstvOwnDB, 'Data1\OwnDB.sav');
end;
0
 
peterkiersAuthor Commented:
It works great. Thanks.

Peter
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
epasquierCommented:
I really don't understand what was your question / problem here ???
0
 
epasquierCommented:
I tested my code, there were a few typos. I fixed all of them in the original question.
Read/Write Component works Ok without having to think much, but remember that it uses HUGE portions of code, so will be slower, will load/save everything not only data, including the ClassType of your listview

so it can be a problem if you want to change the look of your application, with different properties and/or another listview component
0
 
Mahdi78Commented:
Question was based at epasquier code, i have posted my solution to enrich topic,
i think the good answer is when epasquier code been adjusted
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now