Table of Contents

Storing and looking up strings

Not every translatable string belongs to a control. Validation messages, dialog prompts, status-bar text, and captions your code builds at runtime all need translations too, but there is no form property to attach them to. The string catalog is where those strings live: each entry is a name paired with a value, the translations are produced per language just like control captions, and your code reads a value back by name in whatever language is currently active. This guide covers adding entries, looking them up, enumerating the collection, and keeping code-driven text in sync when the language changes. If you have not added the component yet, start with Getting started.

Adding entries

Entries live in the catalog's Strings collection. Add them at design time through the collection editor — give each a stable Name (the key your code will use) and a default Value (the source-language text) — or add them in code with Strings.Add. Keep the Name values stable: they are the lookup keys, so renaming one means updating every GetByName call that uses it.

Looking up and enumerating strings

Call GetByName with an entry's name to get its value in the active language; it returns an empty string for an unknown name, so guard important lookups with a fallback. To inspect or export everything the catalog holds, walk the Strings collection directly:

procedure TForm1.ShowValidationError;
begin
  { GetByName returns '' for an unknown name, so fall back gracefully. }
  if StringCatalog.GetByName('ErrRequired') <> '' then
    lblError.Text := StringCatalog.GetByName('ErrRequired')
  else
    lblError.Text := 'This field is required.';
end;

procedure TForm1.DumpCatalog;
var
  I: Integer;
  Entry: TTMSFNCLocalizationString;
begin
  { Enumerate every stored entry through the Strings collection. }
  for I := 0 to StringCatalog.Strings.Count - 1 do
  begin
    Entry := StringCatalog.Strings[I];
    Memo1.Lines.Add(Entry.Name + ' = ' + Entry.Value);
  end;
end;

Keeping code-driven text in sync

When the user switches language, the localizer updates the catalog's stored values along with the rest of the application. Controls you assigned from the catalog are not re-assigned automatically — your code set them once, so your code must set them again. Re-read the entries in the localizer's OnLanguageChange handler — see Putting it together below for the wired-up version.

Putting it together: catalog and localizer

The complete pattern combines the catalog (storage and lookup) with the localizer (the change notification) so that text your code renders always matches the active language:

procedure TForm1.FormCreate(Sender: TObject);
begin
  { The localizer updates the catalog's stored values on a language change; use
    its event to re-read the strings your code displays. }
  Localizer.OnLanguageChange := HandleLanguageChange;
  RefreshTexts;
end;

procedure TForm1.HandleLanguageChange(Sender: TObject);
begin
  RefreshTexts;
end;

procedure TForm1.RefreshTexts;
begin
  { Re-read catalog entries so code-driven captions follow the active language. }
  lblWelcome.Text := StringCatalog.GetByName('Welcome');
  btnSave.Text := StringCatalog.GetByName('SaveButton');
end;

Common pitfalls

  • Look-ups are by name, and unknown names return ''. A typo in the name yields an empty string, not an error — always provide a fallback for user-facing text.
  • Code-assigned text does not refresh itself. The localizer updates the stored values, but anything your code already pushed into a control must be re-read on OnLanguageChange.
  • Keep entry names stable. The Name is the contract between the catalog and your code; treat it like a resource key.

See also