Working With String Lists in Delphi
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
- Creating a new string list
- Manipulating strings in a list
- Associating objects with a string list
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.
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.
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.
- Construct the string-list object.
- In the try part of a try...finally block, use the string list.
- In the finally part, free the string-list object.
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.
- In the unit file for your application’s main form, add a field of type TStrings to the form’s declaration.
- Write an event handler for the main form’s OnCreate event that executes before the form appears. It should create a string list and assign it to the field you declared in the first step.
- Write an event handler that frees the string list for the form’s OnClose event.
Operations commonly performed on string lists include:
- Counting the strings in a list - The read-only Count property returns the number of strings in the list. Since string lists use zero-based indexes, Count is one more than the index of the last string.
- Accessing a particular string - The Strings array property contains the strings in the list, referenced by a zero-based index. Because Strings is the default property for string lists, you can omit the Strings identifier when accessing the list; thus
StringList1.Strings[0] := 'This is the first string.'; is equivalent to StringList1[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 –1 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('TargetFileName') > -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.
- 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.
- 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.
- 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’t 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.
- 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.
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.