tstringlist

This article give you descriptions to the TCollection, TStringList and THashedStringList in Delphi / C++Builder. These base vcl/clx component are very useful in programming.

TCollection

TCollection is a container for TCollectionItem objects.

TCollection is in Unit Classes.

Description

Each TCollection holds a group of TCollectionItem descendants. TCollection maintains an index of the collection items in its Items array. The Count property contains the number of items in the collection. Use the Add and Delete methods to add items to the collection and delete items from the collection.

Objects descended from TCollection can contain objects descended from TCollectionItem. Thus, for each TCollection descendant, there is a corresponding TCollectionItem descendant. The following table lists some typical descendants of TCollection with the corresponding TCollectionItem descendant and the component that uses each pair.

TCollection descendant
TCollectionItem descendant
Component
TAggregates TAggregate TClientDataSet
TCookieCollection TCookie TWebResponse
TDBGridColumns TColumn TDBGrid
TFieldDefs TFieldDef TDataSet
THeaderSections THeaderSection THeaderControl
TListColumns TListColumn TListView
TParams TParam many datasets
TStatusPanels TStatusPanel TStatusBar

The controls that use TCollection and TCollectionItem descendants have a published property that holds a collection. (For example, the Panels property of TStatusBar holds a TStatusPanels.) A standard property editor, referred to generically as the Collection editor, can be invoked from the Object Inspector to edit the items in the collection.

Note: When writing a TCollection descendant that is used by another control, be sure to override the protected GetOwner method of the collection so that it can appear in the Object Inspector.

TStringList

TStringList maintains a list of strings.

TStringList is in Unit Classes.

Description

Use a string list object to store and manipulate a list of strings. TStringList implements the abstract properties and methods introduced by TStrings, and introduces new properties, events, and methods to

Sort the strings in the list.
Prohibit duplicate strings in sorted lists.
Respond to changes in the contents of the list.
Control whether strings are located, sorted, and identified as duplicates in a case-sensitive or case-insensitive manner.

THashedStringList

THashedStringList maintains a list of strings using an internal hash table.

THashedStringList is in Unit IniFiles.

Description

THashedStringList is a string list that uses a hash table internally to speed the process of locating strings. It is used internally by TMemIniFile to manage the strings from an INI file, but can be used in the same way as any other string list. By using THashedStringList instead of TStringList, you can improve performance when the list contains a large number of strings.

 

Once you have graphical images in an application, you can associate them with the strings in a string list. You can either add the objects at the same time as the strings, or associate objects with existing strings. The preferred method is to add objects and strings at the same time, if all the needed data is available.
The following example shows how you might want to add images to a string list. This is part of a file manager application where, along with a letter for each valid drive, it adds a bitmap indicating each drive's type. The OnCreate event handler looks like this:

void __fastcallTFMForm::FormCreate(TObject *Sender)
{
  int AddedIndex;
  char DriveName[4] = "A:\\";
  for (char Drive = 'A'; Drive <= 'Z'; Drive++) // try all possible drives
  {
    DriveName[0] = Drive;
    switch(GetDriveType(DriveName))
    {
      case DRIVE_REMOVABLE: // add a list item
        DriveName[1] = '\0'; // temporarily make drive letter into string
        AddedIndex = DriveList->Items->AddObject(DriveName,
           Floppy->Picture->Graphic);
        DriveName[1] = ':'; // replace the colon

        break;
      case DRIVE_FIXED: // add a list item
        DriveName[1] = '\0'; // temporarily make drive letter into string
        AddedIndex = DriveList->Items->AddObject(DriveName,
           Fixed->Picture->Graphic);
        DriveName[1] = ':'; // replace the colon
        break;
      case DRIVE_REMOTE: // add a list item
        DriveName[1] = '\0'; // temporarily make drive letter into string
        AddedIndex = DriveList->Items->AddObject(DriveName,

           Network->Picture->Graphic);
        DriveName[1] = ':'; // replace the colon
        break;
    }
    if ((int)(Drive - 'A') == getdisk()) // current drive?
      DriveList->ItemIndex = AddedIndex; // then make that the current list item
  }
}

Note: To run this sample codes, you need to include "dir.h" in your header, like this:

#include
#pragma hdrstop

#include "Unit1.h"
#include "dir.h"    //This is the line you need to add in your program.
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

 

Operations commonly performed on string lists include:

Counting the strings in a list

The Strings array property contains the strings in the list, referenced by a zero-based index.

StringList1->Strings[0] = "This is the first string.";

Accessing a particular string

The Strings array property contains the strings in the list, referenced by a zero-based index.

StringList1->Strings[0] = "This is the first string.";

Finding the position of a string in the list

To locate a string in a string list, use the IndexOf method. IndexOf returns the index of the first string in the list that matches the parameter passed to it, and returns ? if the parameter string is not found. IndexOf finds exact matches only; if you want to match partial strings, you must iterate through the string list yourself.
For example, you could use IndexOf to determine whether a given file name is found among the Items of a list box:

if (FileListBox1->Items->IndexOf("WIN.INI") > -1) ...

Iterating through strings in a list

To iterate through the strings in a list, use a for loop that runs from zero to Count ?1.
This example converts each string in a list box to uppercase characters.

void __fastcallTForm1::Button1Click(TObject *Sender)

{
  for (int i = 0; i Items->Count; i++)
    ListBox1->Items->Strings[i] = UpperCase(ListBox1->Items->Strings[i]);
}

Adding a string to a list

To add a string to the end of a string list, call the Add method, passing the new string as the parameter. To insert a string into the list, call the Insert method, passing two parameters: the string and the index of the position where you want it placed. For example, to make the string 揟hree?the third string in a list, you would use:

StringList1->Insert(2, "Three");

To append the strings from one list onto another, call AddStrings:

StringList1->AddStrings(StringList2);  // append the strings from StringList2 to StringList1

Moving a string within a list

To move a string in a string list, call the Move method, passing two parameters: the current index of the string and the index you want assigned to it. For example, to move the third string in a list to the fifth position, you would use:

StringListObject->Move(2, 4);

Deleting a string from a list

To delete a string from a string list, call the list's Delete method, passing the index of the string you want to delete. If you don抰 know the index of the string you want to delete, use the IndexOf method to locate it. To delete all the strings in a string list, use the Clear method.
This example uses IndexOf and Delete to find and delete a string:

int BIndex = ListBox1->Items->IndexOf("bureaucracy");

if (BIndex > -1)
  ListBox1->Items->Delete(BIndex);

Copying a complete string list

You can use the Assign method to copy strings from a source list to a destination list, overwriting the contents of the destination list. To append strings without overwriting the destination list, use AddStrings. For example,

Memo1->Lines->Assign(ComboBox1->Item)s;       //overwrites original strings

copies the lines from a combo box into a memo (overwriting the memo), while

Memo1->Lines->AddStrings(ComboBox1->Items);    //appends strings to end

appends the lines from the combo box to the memo.
When making local copies of a string list, use the Assign method. If you assign one string-list variable to another?

StringList1 = StringList2;

--the original string-list object will be lost, often with unpredictable results.

 

One of the most commonly used types of list is a list of character strings. Examples include items in a combo box, lines in a memo, names of fonts, and names of rows and columns in a string grid. BaseCLX provides a common interface to any list of strings through an object called TStrings and its descendants such as TStringList and THashedStringList. TStringList implements the abstract properties and methods introduced by TStrings, and introduces properties, events, and methods to

  • Sort the strings in the list.
  • Prohibit duplicate strings in sorted lists.
  • Respond to changes in the contents of the list.

In addition to providing functionality for maintaining string lists, these objects allow easy interoperability; for example, you can edit the lines of a memo (which are a TStrings descendant) and then use these lines as items in a combo box (also a TStrings descendant).
A string-list property appears in the Object Inspector with TStrings in the Value column. Double-click TStrings to open the String List editor, where you can edit, add, or delete lines.

You can also work with string-list objects at runtime to perform such tasks as

Loading and Saving String Lists.

String-list objects provide SaveToFile and LoadFromFile methods that let you store a string list in a text file and load a text file into a string list. Each line in the text file corresponds to a string in the list. Using these methods, you could, for example, create a simple text editor by loading a file into a memo component, or save lists of items for combo boxes.
The following example loads a copy of the WIN.INI file into a memo field and makes a backup copy called WIN.BAK.

void __fastcall EditWinIniFile()
{
  AnsiString FileName = "C:\\WINDOWS\\WIN.INI"; // set the file name
  Form1->Memo1->Lines->LoadFromFile(FileName);      // load from file
  Form1->Memo1->Lines->SaveToFile(ChangeFileExt(FileName, ".BAK"));  // save to backup
}

Creating a New String List.

A string list is typically part of a component. There are times, however, when it is convenient to create independent string lists, for example to store strings for a lookup table. The way you create and manage a string list depends on whether the list is short-term (constructed, used, and destroyed in a single routine) or long-term (available until the application shuts down). Whichever type of string list you create, remember that you are responsible for freeing the list when you finish with it.

Short-term string lists

If you use a string list only for the duration of a single routine, you can create it, use it, and destroy it all in one place. This is the safest way to work with string lists. Because the string-list object allocates memory for itself and its strings, you should use a try...__finally block to ensure that the memory is freed even if an exception occurs.

1 Construct the string-list object.
2 In the try part of a try...__finally block, use the string list.
3 In the __finally part, free the string-list object.

The following event handler responds to a button click by constructing a string list, using it, and then destroying it.

void __fastcall TForm1::ButtonClick1(TObject *Sender)

{
   TStringList *TempList = new TStringList; // declare the list
   try{
      //use the string list
   }
   __finally{
    delete TempList; // destroy the list object
   }
}

Long-term string lists

If a string list must be available at any time while your application runs, construct the list at start-up and destroy it before the application terminates.

1 In the unit file for your application's main form, add a field of type TStrings to the form's declaration.
2 Write a constructor for the main form that executes before the form appears. It should create a string list and assign it to the field you declared in the first step.
3 Write an event handler that frees the string list for the form's OnClose event.

This example uses a long-term string list to record the user's mouse clicks on the main form, then saves the list to a file before the application terminates.

//---------------------------------------------------------------------------

#include
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
   ClickList = new TStringList;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
   ClickList->SaveToFile(ChangeFileExt(Application->ExeName, ".LOG"));//Save the list
   delete ClickList;
}
//---------------------------------------------------------------------------
void __fastcallTForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
   TVarRec v[] = {X,Y};
   ClickList->Add(Format("Click at (%d, %d)",v,ARRAYSIZE(v) - 1));//add a string to the list
}

Associating Objects With a String List.

In addition to the strings stored in its Strings property, a string list can maintain references to objects, which it stores in its Objects property. Like Strings, Objects is an array with a zero-based index. The most common use for Objects is to associate bitmaps with strings for owner-draw controls.
Use the AddObject or InsertObject method to add a string and an associated object to the list in a single step. IndexOfObject returns the index of the first string in the list associated with a specified object. Methods like Delete, Clear, and Move operate on both strings and objects; for example, deleting a string removes the corresponding object (if there is one).

To associate an object with an existing string, assign the object to the Objects property at the same index. You cannot add an object without adding a corresponding string.

 

A sample to use TStringList in C++Builder. The TStringList is very useful in some cases to manage the text list or objects.

Create a new project, put a button on your form. Double click the button, assign the following codes in its onClick event handler.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    //Create a TStringList object and adding text list to it.
    TStringList *pList = new TStringList;
    pList->Add("Here is a sample");
    pList->Add("On how to use TStringList");
    pList->Add("We first create a new stringlist");
    pList->Add("then adding text list to it");
    pList->Add("What's the following thing?");
    pList->Add("Show the text statements one by one.");
    pList->Add("At last, we save it to a file.");
    pList->Add("under your root of partition c.");
    pList->Add("then delete this stringlist.");
    pList->Add("Thank you for visiting http://codeback.net");

    //Show the list we have stored in the pList
    for (int i = 0; i Count; i++)
        ShowMessage(pList->Strings[i]);

    //Save the list contents to a file
    pList->SaveToFile("c:\\sampleList.txt");

    //Delete the list from memory.
    delete pList;
}

The TStringList object can store not only strings, but also objects in its list. While store the object type of list, you need to use the addobject method, and you have to specify what kind of object it is when visit the list menbers. See below:

TButton *pBtn = new TButton(this);
pBtn->Caption = "list button";
pList->AddObject("my button", pBtn);
TButton *pButton = (TButton*)pList->Objects[0];
ShowMessage(pButton->Caption);
delete pBtn;

See more articles on C++Builder programs:

How to Start Program With Delphi/C++Builder? Delphi/C-Builder's Integrated Development Environment Introduction .
An example on using scanline to access bitmap pixels in C-Builder .
How to use an ini file in C++Builder .
How to convert an icon to a bitmap in C++Builder .
How to hide the 3D border of TPageControl in Delphi?
Using TBlobField and TBlobStream in C++Builder .
An example on how to use GetFormImage() and Assign() functions in C++Builder .
How to capture a web page's content and save it to an image .