title: How can I pass the name of a stringlist as a parameter
body: <p>I have written a unit to save multiple stringlists.  Each TStrings item is stored as a record containing the text and an integer value representing the object.  The whole is written to a binary file.  Below is the routine which writes the data.</p>
  
  <pre><code>function AddToStream(Stream: TStream; Const pList: TStringList):Boolean;
  Var idy: Integer;
      TmpItem: tItemRec;
  begin
    TmpItem.pText := pList.ClassName;       // Set up the Header
    TmpItem.pObj := pList.Count * SizeOf(TmpItem);  // Calc the # bytes for Stringlist
    Stream.WriteBuffer(TmpItem, SizeOf(TmpItem));   // Write it to the Stream
    for idy := 0 to plist.Count -1 do begin         // Cycle through StringList
          TmpItem.pText := pList[idy];                  // Get the Text part
          TmpItem.pObj := Integer(pList.Objects[idy]);  // Get the Object part
          Stream.WriteBuffer(TmpItem, SizeOf(TmpItem)); // Write record to stream
    end;
  end;
  </code></pre>
  
  <p>The first record writen to the stream is intended to carry a name identifying the stringlist and the number of bytes in the subsequent file.  Obviously in the code above the ClassName returns TStringList, how can I obtain the variable name of the stringlist passed, i.e. MyStringList.  </p>
  
  <p>Is it possible to derive it from the standard stringlist passed or do I have to subclass the stringlist and add a VariableName property to the list.</p>
  
  <p>Perhaps I should have shown all of my code. Apart from my original issue I believe I have the code working at least for single TStringLists.  Until I have a decided what to do re the naming issue I haven't tested for multiple Stringlists.  So below is the full unit.</p>
  
  <pre><code>unit MultiFileUtils;
  
  interface
  
  Uses
  System.SysUtils, System.Variants, System.Classes, Vcl.Dialogs, system.UITypes;
  
  
  {This unit enables Multiple stringlist to be saved with objects to a single file
   and reloaded the into the stringlists retaining their originla object value.
   The stringlists you reload to should have classname as the stringlist you saved from
   The data is held in a  binary file, each string list has a aheader which holds
   the ClassName of the stringlist and the length of the file. The text portion
   of each entry in the stringlist should not exceed 255 characters.
  
   Save functions return true if OK, AllowOverWrite doesn't check file already exists.
   Read function returns true if OK, false if file not found or classname not found in file}
  
  Function SaveLists(Const pLists: Array of TStringList; const pFileName: String; AllowOverwrite: Boolean): Boolean;
  Function SaveList(Const pList: TStringList; const pFileName: String; AllowOverwrite: Boolean):Boolean;
  Function ReadList(Const pFileName: String; Var pList: TStringList): Boolean;
  
  procedure LoadTestData;
  procedure SetUpTests;
  procedure TestSave;
  procedure TestRead;
  Procedure ClearTests;
  
  implementation
  
  
  Type
    tItemRec = record
      pText: String[255];
      pObj: Integer;
    end;
  
  {$ifDef Debug}
  Var StrList1: TStringlist;
      StrList2: TStringlist;
  {$EndIf}
  
  function CheckFileExists(pFileName: String):Boolean;
  begin
    if FileExists(pFileName) then
      Result := (MessageDlg(pFileName + ' already exists, do you want to overwrite file?',
                            mtConfirmation, [mbYes,mbNo],0) = mrYes);
  end;
  
  function AddToStream(Stream: TStream; Const pList: TStringList):Boolean;
  Var
    idy: Integer;
    TmpItem: tItemRec;
  begin
    TmpItem.pText := pList.ClassName;               // Set up the Header
    TmpItem.pObj := pList.Count * SizeOf(TmpItem);  // Calc the # bytes for Stringlist
    Stream.WriteBuffer(TmpItem, SizeOf(TmpItem));   // Write it to the Stream
    for idy := 0 to plist.Count -1 do begin         // Cycle through StringList
      TmpItem.pText := pList[idy];                  // Get the Text part
      TmpItem.pObj := Integer(pList.Objects[idy]);  // Get the Object part
      Stream.WriteBuffer(TmpItem, SizeOf(TmpItem)); // Write record to stream
    end;
  end;
  
  function SaveLists(Const pLists: Array of TStringList; Const pFileName: String;
                     AllowOverwrite: Boolean): Boolean;
  Var
    idx: Integer;
    Stream: TStream;
  begin
    if AllowOverwrite then
      Result := true
    else
      Result := CheckFileExists(pFileName);
    if Result then begin
      Stream := TFileStream.Create(pFileName, fmCreate); // Set up a fileStream
      try
        for idx := 0 to Length(plists) do           // Loop through array of stringlists
          AddToStream(Stream, pLists[idx]);         // Add each Stringlist
      finally
        Stream.Free;                                // Write to disk and free Stream
      end;
    end;
  end;
  
  function SaveList(Const pList: TStringList; const pFileName: String;
                    AllowOverwrite: Boolean): Boolean;
  Var
    idx: Integer;
    Stream: TStream;
  begin
    If AllowOverwrite then
      result := true
    else
      Result := CheckFileExists(pFileName);
    if Result then begin
      Stream := TFileStream.Create(pFileName, fmCreate); // Set up filestream
      try
        AddToStream(Stream, pList);                 // Add Stringlist to stream
      finally
        Stream.Free;                                // Write to disk and free Stream
      end;
    end;
  end;
  
  function ReadList(Const pFileName: String; var pList: TStringList): Boolean;
  Var idx: Integer;
    Stream: TStream;
    TmpItem: tItemRec;
  
    Function NotEos: Boolean;
    begin
      Result := Stream.Position &lt; Stream.Size;
    end;
  
  begin
    Result := false;
    if FileExists(pFileName) then begin
      Stream := TFileStream.Create(pFileName, fmOpenRead);
      Stream.Seek(0, soBeginning);
      while NotEos do begin
        if Stream.Read(TmpItem, SizeOf(TmpItem)) = SizeOf(TmpItem) then  // Read Header
          if TmpItem.pText = pList.ClassName then begin
            Result := True;                         // Found header so file looks OK
            idx := TmpItem.pObj;                    // Get the byte count
            while (idx &gt; 0) And NotEos do begin
              Stream.ReadBuffer(TmpItem, SizeOf(TmpItem));
              pList.AddObject(Trim(TmpItem.pText), Pointer(TmpItem.pObj));
              Dec(idx);
            end;
            break;
          end;
      end;
      Stream.Free;
    end;
  end;
  
  {$ifDef Debug}
  Procedure LoadTestData;
  Var i: Integer;
  begin
    for i := 0 to 20 do begin
      StrList1.AddObject('StrLst1 Data' + IntToStr(i), Pointer(i+1000));
      StrList2.AddObject('StrLst2 Data' + IntToStr(i), pointer(i+2000));
    end;
  end;
  
  procedure SetUpTests;
  begin
    StrList1 := TStringList.Create;
    StrList2 := TStringList.Create;
    LoadTestData;
  end;
  
  Procedure TestSave;
  begin
    SaveList(StrList1, 'MyTestFile.dat', true);
  end;
  
  Procedure TestRead;
  begin
    StrList1.Clear;
    ReadList('MyTestFile.dat', StrList1);
  end;
  
  procedure ClearTests;
  begin
    StrList1.Free;
    StrList2.Free;
  end;
  {$endif}
  
  end.
  </code></pre>