Newsgroup: it.comp.lang.delphi
Titolo: Salvare non utilizzando il Record

Ciao a tutti, ho un'altra domanda da farvi.
Attualmente ho 5 ListBox contenenti un numero pari di Items.
Inoltre ho una ListView e 10 Label, tutte contenenti una certa stringa.
Adesso per salvare i file utilizzo i record, che secondo me sono un po'
limitati (intendo la stringa vista come 255 car. max), e devo avere 3 tipi
di record, uno per le listbox, uno per le label, uno per la listview.
Ottengo cosě 3 file.
Non esiste un metodo per salvare tutte queste 3 cose in un unico file???
PS:- Ripeto i record sono potenti, ma secondo me limitati nei 255 caratteri,
ho da salvare un edit moolto lungo, e non posso utilizzare un memo.
Sapete come raggruppare tutto questo in un unico file???
Ciao e grazie

 a écrit dans le message news:
wibS9.63470$Q%4.20...@news1.tin.it...

Se sei pigro (io lo sono e me ne vanto), prova a copiare tutte le tue
stringhe in una TStringList, poi usa SaveToFile. Per rileggetere, usa
LoadFromFile della TStringList, e spartisci. Altro vantaggio (forse): il
file č in formato testo, quindi anche editabile facilmente.
IceCream

Non era questione di pigrizia, anzi...
Io volevo solo avere il tutto in un unico file. In ogni caso per ricercarli
come posso fare però??? Non so dove comincia il file o dove finisce...

 a écrit dans le message news:
3FhT9.5883$0v.1...@news1.tin.it...

Se usi il metodo che ti ho suggerito, l'unico problema può essere quando
hai
un TMemo con più di una linea (ma non è difficile da risolvere). Supponiamo
che hai 3 TEdit e 2 TMemo con un numero di linee variabile. Ecco come
potresti procedere (non collaudato, buttato giù così come viene), anche se
non è il modo più elegante.
Buona fortuna
IceCream
-------------------------------
procedure Salva(const fName:string);
var
  Lista : TStringList;
  i     : integer;
begin
  Lista := TStringList.Create;
  try
    Lista.Add(IlTuoEdit1.Text);
    Lista.Add(IlTuoEdit2.Text);
    Lista.Add(IlTuoEdit3.Text);
    Lista.Add(IntToStr(IlTuoMemo1.Lines.Count));{Memorizza il numero di
linee}
    for i:=0 to IlTuoMemo1.Lines.Count-1 do
      Lista.Add(IlTuoMemo1.Lines[i]);
    Lista.Add(IntToStr(IlTuoMemo2.Lines.Count));
    for i:=0 to IlTuoMemo2.Lines.Count-1 do
      Lista.Add(IlTuoMemo2.Lines[i]);
    Lista.SaveToFile(fName);
  finally
    Lista.Free
  end;
end;
procedure Leggi(const fName:string);
var
  Lista : TStringList;
  i     : integer;
begin
  Lista := TStringList.Create;
  try
    Lista.LoadFromFile(fName);
    IlTuoEdit1.Text :=  Lista[0];
    Lista.Delete(0);
    IlTuoEdit2.Text :=  Lista[0];
    Lista.Delete(0);
    IlTuoEdit3.Text :=  Lista[0];
    Lista.Delete(0);
    i:= StrToInt(Lista[0]);{Quante linee nel memo 1?}
    Lista.Delete(0);
    while i>0 do
      begin
        IlTuoMemo1.Lines.Add(Lista[0]);
        Lista.Delete(0);
        dec(i);
      end;
    i:= StrToInt(Lista[0]);{Quante linee nel memo 2?}
    Lista.Delete(0);
    while i>0 do
      begin
        IlTuoMemo2.Lines.Add(Lista[0]);
        Lista.Delete(0);
        dec(i);
      end;
  finally
    Lista.Free
  end;
end;
---------------------------------------------------------------------------
Messaggio inviato attraverso 
http://www.trucchiperpc.it
 - sezione newsgroup

 Non esiste un metodo per salvare tutte queste 3 cose in un unico
file???
Ci sono diversi componenti in grado di prendere uno snapshot di una form
o di alcuni componenti e salvarla su disco (che e' poi quel che fa il
meccanismo di streaming di Delphi).
Il _problema_ di metodi come TStream.WriteComponent / ReadComponent e'
che salvano tutte le proprieta' del componente, il che puo' essere
dispendioso in termini di spazio su disco.
Se vuoi fare da te, usare un file di tipo INI e' rapido e abbastanza
veloce: segue (nell'altro messaggio) un esempio (nota: se ti interessa
che sia non leggibile, usa un TMemIniFile ed i metodi SetStrings,
GetStrings; quando si tratta di salvare/caricare usa una funzione di
compressione/decompressione).
Si noti che, in caso di liste il nome della property e' cablato come
'Items': non e' difficile, cmq, estendere ad altre proprieta' come
(TMemo.)Lines. Un po' piu' laborioso per (TStringGrid.)Cells, visto che
l'array in tal caso e' bidimensionale.
L'esempio dell'altro messaggio e' quick&dirty, mancano controlli etc.,
cmq dovrebbe essere sufficiente per dare un'idea.
Considera, in ogni caso, se non ti convenga racchiudere le info che
mostri sulla form in un oggetto in grado di sapere come salvare /
caricare le proprieta' rilevanti su disco.
Saluti
Paolo Arosio

Si veda altro msg per spiegazioni di quanto segue
Esempio:
// --- main form: componenti ----
object Form1: TForm1
  Left = 239
  Top = 252
  Width = 619
  Height = 348
  Caption = 'Form1'
  Color = clBtnFace
  Constraints.MinHeight = 270
  Constraints.MinWidth = 565
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  DesignSize = (
    611
    321)
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 8
    Top = 20
    Width = 83
    Height = 13
    Caption = 'Testo della label1'
  end
  object Label2: TLabel
    Left = 8
    Top = 40
    Width = 83
    Height = 13
    Caption = 'Testo della label2'
  end
  object Edit1: TEdit
    Left = 8
    Top = 64
    Width = 277
    Height = 21
    TabOrder = 0
    Text = 'Testo della edit1: 0123456789 0123456789 0123456789'
  end
  object ListView1: TListView
    Left = 8
    Top = 92
    Width = 277
    Height = 109
    Columns = <
      item
        Width = -1
        WidthType = (
          -1)
      end
      item
        Width = -1
        WidthType = (
          -1)
      end
      item
        Width = -1
        WidthType = (
          -1)
      end
      item
        Width = -1
        WidthType = (
          -1)
      end>
    Items.Data = {
      9E0000000300000000000000FFFFFFFFFFFFFFFF020000000000000006497465
      6D20310C737562697474656D20312E310B7375626974656D20312E3200000000
      FFFFFFFFFFFFFFFF0300000000000000056974656D320B7375626974656D2032
      2E310B7375626974656D20322E320B7375626974656D20322E3300000000FFFF
      FFFFFFFFFFFF0000000000000000056974656D33FFFFFFFFFFFFFFFFFFFF}
    TabOrder = 1
    ViewStyle = vsReport
  end
  object ListBox1: TListBox
    Left = 8
    Top = 208
    Width = 277
    Height = 102
    Anchors = [akLeft, akTop, akBottom]
    ItemHeight = 13
    Items.Strings = (
      'ListItem 1'
      'ListItem 2'
      'ListItem 3'
      'ListItem 4'
      'ListItem 5')
    TabOrder = 2
  end
  object Memo1: TMemo
    Left = 300
    Top = 48
    Width = 302
    Height = 262
    Anchors = [akLeft, akTop, akRight, akBottom]
    Lines.Strings = (
      'Memo1')
    TabOrder = 3
  end
  object Button1: TButton
    Left = 308
    Top = 16
    Width = 75
    Height = 25
    Caption = 'Save'
    TabOrder = 4
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 392
    Top = 16
    Width = 75
    Height = 25
    Caption = 'Load'
    TabOrder = 5
    OnClick = Button2Click
  end
  object Button3: TButton
    Left = 472
    Top = 16
    Width = 75
    Height = 25
    Caption = 'Clear'
    TabOrder = 6
    OnClick = Button3Click
  end
end
// --- main form: codice ------
unit ufrmMain;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
  Dialogs, StdCtrls, ComCtrls;
type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Edit1: TEdit;
    ListView1: TListView;
    ListBox1: TListBox;
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private    { Private declarations }
    fComponentsToStream: TStringList;
    fn: TFilename;
    procedure ComponentToIni(aComp: TComponent; propName: string; out
dest: TStrings);
    procedure CollectionToIni(aColl: TPersistent; dest: TStrings);
    procedure FromIniToComponent(aComp: TComponent; aProp: string;
Value: string);
    procedure FromIniToCollection(aColl: TPersistent; Values: TStrings);
  public    { Public declarations }
    procedure ClearAll;
    procedure SaveToIni(const dest: TFilename);
    procedure LoadFromIni(const src: TFilename);
  end;
var
  Form1: TForm1;
implementation
uses IniFiles, TypInfo;
{$R *.dfm}
procedure TForm1.CollectionToIni(aColl: TPersistent; dest: TStrings);
var i, j, cnt: integer;
    li: TListItem;
    sl: TStringList;
begin
  if aColl is TStrings then begin
    cnt := TStrings(aColl).Count;
    dest.Add('Count=' + inttostr(cnt));
    for i := 0 to cnt-1 do
      dest.Add('Item' + inttostr(i) + '=' + TStrings(aColl)[i]);
  end
  else if aColl is TListItems then begin
    cnt := TListItems(aColl).Count;
    dest.Add('Count=' + inttostr(cnt));
    sl := TStringList.Create;
    try
      for i := 0 to cnt - 1 do begin
        sl.Clear;
        li := TListItems(aColl).Item[i];
        sl.Add(li.Caption);
        for j := 0 to li.SubItems.Count-1 do
          sl.Add(li.SubItems[j]);
        dest.Add('Item' + inttostr(i) + '=' + sl.CommaText);
      end;
    finally
      sl.Free;
    end;
  end;
end;
procedure TForm1.ComponentToIni(aComp: TComponent; propName: string;
  out dest: TStrings);
begin
  dest.Clear;
  dest.Add('[' + aComp.Name + ']');
  // metodo rozzo e insicuro per distinguere collezioni da proprieta'
singole
  if propName[Length(propName)] = 's' then begin
    CollectionToIni(TPersistent(GetObjectProp(aComp, propName,
TPersistent)), dest);
  end
  else begin
    dest.Add(propName + '=' + GetStrProp(aComp, propName));
  end;
end;
procedure TForm1.FromIniToCollection(aColl: TPersistent; Values:
TStrings);
var i, j, cnt: integer;
    sl: TStringList;
begin
  cnt := StrToInt(Values.Values['Count']);
  if aColl is TStrings then begin
    TStrings(aColl).Capacity := cnt;
    for i := 0 to cnt - 1 do
      TStrings(aColl).Add(Values.Values['Item' + inttostr(i)]);
  end
  else if aColl is TListItems then begin
    sl := TStringList.Create;
    try
      for i := 0 to cnt - 1 do begin
        sl.CommaText := Values.Values['Item' + inttostr(i)];
        with TListItems(aColl).Add do begin
          Caption := sl[0];
          for j := 1 to sl.Count -1 do
            SubItems.Add(sl[j]);
        end;
      end;
    finally
      sl.Free;
    end;
  end;
end;
procedure TForm1.FromIniToComponent(aComp: TComponent; aProp: string;
Value: string);
begin
  SetStrProp(aComp, aProp, Value);
end;
procedure TForm1.SaveToIni(const dest: TFilename);
var Buffer: TStringList;
    SecList: TStringList;
    i: integer;
begin
  Buffer := TStringList.Create;
  try
    SecList := TStringList.Create;
    try
      for i := 0 to fComponentsToStream.Count-1 do begin
        ComponentToIni(TComponent(fComponentsToStream.Objects[i]),
          fComponentsToStream[i], TStrings(SecList));
        Buffer.AddStrings(SecList);
        Buffer.Add('');
      end;
    finally
      SecList.Free;
    end;
    Buffer.SaveToFile(dest);
  finally
    Buffer.Free;
  end;
end;
procedure TForm1.LoadFromIni(const src: TFilename);
var Ini: TMemIniFile;
    CompL, ValL: TStringList;
    i: integer;
    Cmp: TComponent;
    Coll: TPersistent;
begin
  Ini := TMemIniFile.Create(src);
  try
    CompL := TStringList.Create;
    try
      Ini.ReadSections(CompL);
      ValL := TStringList.Create;
      try
        for i := 0 to CompL.Count - 1 do begin
          Cmp := FindComponent(CompL[i]);
          if not Assigned(Cmp) then begin
            // log error or show it
            Continue;
          end;
          Ini.ReadSectionValues(CompL[i], ValL);
          if ValL.Names[0] = 'Count' then begin
            Coll := TPersistent(GetObjectProp(Cmp, 'Items',
TPersistent));
            FromIniToCollection(Coll, ValL);
          end
          else
            FromIniToComponent(Cmp, ValL.Names[0],
ValL.Values[ValL.Names[0]])
        end;
      finally
        ValL.Free
      end;
    finally
      CompL.Free;
    end;
  finally
    Ini.Free;
  end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
  fn := ExtractFilePath(ParamStr(0)) + 'TextFromComp.txt';
  fComponentsToStream := TStringList.Create;
  fComponentsToStream.AddObject('Caption', Label1);
  fComponentsToStream.AddObject('Caption', Label2);
  fComponentsToStream.AddObject('Text', Edit1);
  fComponentsToStream.AddObject('Items', ListView1);
  fComponentsToStream.AddObject('Items', ListBox1);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
  fComponentsToStream.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  SaveToIni(fn);
  Memo1.Lines.LoadFromFile(fn);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
  ClearAll;
  Memo1.Lines.LoadFromFile(fn);
  LoadFromIni(fn);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
  ClearAll;
end;
procedure TForm1.ClearAll;
begin
  Label1.Caption := '';
  Label2.Caption := '';
  Edit1.Text := '';
  ListView1.Clear;
  ListBox1.Clear;
  Memo1.Clear;
end;
end.