C++ Builder Snippets  


Ressource String Dateien (*.RES) in einem C++ Builder Projekt verwenden:
von Klaus Helmut Renders
 
Siehe auch Einbinden von Bitmap-, Cursor- und Sound-Ressourcen in BCB-Anwendungen.

Es gibt einen recht einfachen Weg, Ressource String Dateien in ein Borland C++ Builder Projekt einzubinden und zu verwenden. Hierzu legt man sich zunächst eine String-Tabelle in einer Text Datei an, indem man im IDE Editor mittels Objektgalerie ein Text-Objekt als neue leere Seite öffnet.

In diesem Text-Objekt legt man nun die eigentliche String-Tabelle wie hier gezeigt an:
STRINGTABLE
BEGIN
  5100   "Die Datei\n %s\n wurde nicht gefunden!";
  5110   "Die Datei\n %s\nexistiert bereits!";
  5120   "Die Datei\n %s\nenthält keine Datensätze.";
  5130   "Die Datei\n %s\n ist bereits geöffnet!";
  5132   "Soll diese Datei geschlossen werden?";
  5140   "Soll die geöffnete Datei\n %s\ngeschlossen und hierfür die Datei\n %s\ngeöffnet werden?";
  ...
  ...
  ...
END
Die Einleitung einer String Tabelle bildet immer das Schlüsselwort STRINGTABLE gefolgt von den Schlüsselworten BEGIN und END zwischen denen die eigentlichen Tabellenzeilen stehen. Jede Tabellenzeile beginnt mit einer im Projekt einmaligen Integerzahl , gefolgt von dem eigentlichen in doppelten Anführungszeichen stehenden String in einer Zeile. Der String kann beliebige gültige Formatierungszeichen enthalten. Jede Zeile muß mit einem Simikolon (;) abgeschlossen sein. Die führende Integerzahl ist die Identifikation (ID) des auf sie folgenden Strings und darf zwischen 0 und max. 65535 liegen. Die Integer sollten aufsteigend sortiert sein.

Diese Textdatei wird unter einem zum Projekt passenden Namen mit der Dateierweiterung RC (*.RC) gespeichert.


Einbinden der *.RC Datei in das Projekt

Dies geschieht - wie wohl bekannt - auf sehr einfache Weise mit Hilfe der Projektverwaltung. Man fügt einfach die Datei *.RC zu seinem Projekt hinzu. Bei der nächsten Kompilierung wird nun automatisch der Borland Ressourcen-Compiler im Hintergrund aufgerufen, welcher mit Hilfe der Datei *.RC eine Ressourcen-Datei *.RES erstellt. Diese wird - das sie ja zum Projekt gehört - vom Linker automatisch zum Projekt hinzugebunden. Nun kann aus dem Code heraus auf die einzelnen Strings über deren jeweilige ID zugegriffen werden.

AnsiString MsgBuff;

if (AFilespec == FFilespec)
{
  // Datei bereits geöffnet
  MsgBuff = AnsiString::FmtLoadStr(5130, ARRAYOFCONST((AFilespec)));
  ShowMessage(MsgBuff);
}
else
{
  // geöffnete Datei schließen und neue Datei öffnen?
  MsgBuff = AnsiString::FmtLoadStr(5140, ARRAYOFCONST((FFilespec, AFilespec)));
  if(ShowRdsMsg(rdsConfirm, MsgBuff.c_str(), rdbYesNo) == rdrYes)
  {
    CloseFile();
    OpenFile(AFilespec);
  }
}
Sie sollten die freien Routinen LoadStr() oder - wenn Formatierungszeichen im String enthalten sind - FmtLoadStr() der Unit AnsiString verwenden, da die entsprechenden AnsiString-Methoden nicht zuverlässig arbeiten.

Achtung: Beachten Sie bitte bei der Verwendung des Macros ARRAYOFCONST, dass - im Gegensatz zu den Erläuterungen in der Borland Hilfe die innerhalb der Klammern stehenden Parameter noch zusätzlich geklammert werden müssen (siehe die Anzahl der Klammern im vorstehenden Codefragment).


Die Verwendung von Defines

Die String-ID sind leider nicht sehr aussagekräftig. Aus diesem Grunde ist es empfehlenswert, an Stelle der ID ein entsprechendes Define zu verwenden. Hierzu erstellt man eine zusätzliche Headerdatei, in welcher man die Preprozessor Definitionen unterbringt:
#define FFS_FL_NOTF_INF   5100
#define FFS_FL_EXSTS_INF  5110
#define FFS_FL_EMPTY_INF  5120
#define FFS_FL_ISOPEN_INF 5130
#define FFS_FL_CLOSE_QST  5132
#define FFS_FL_CHANGE_QST 5140
...
...
Mittels #include "...h" läd man diese Headerdatei ebenfalls in das entsprechende Code Modul und kann dann an Stelle der Integer ID die aussagekräftigeren Defines benutzen.
if (AFilespec == FFilespec)
{
  // Datei bereits geöffnet
  MsgBuff = AnsiString::FmtLoadStr(FFS_FL_ISOPEN_INF, ARRAYOFCONST((AFilespec)));
  ShowRdsMsg(MsgBuff.c_str());
}
else
{
  // geöffnete Datei schließen und neue Datei öffnen?
  MsgBuff = AnsiString::FmtLoadStr(FFS_FL_CHANGE_QST, ARRAYOFCONST((FFilespec, AFilespec)));
  if (ShowRdsMsg(rdsConfirm, MsgBuff.c_str(), rdbYesNo) == rdrYes)
  {
    CloseFile();
    OpenFile(AFilespec);
  }
}
Autor: Klaus Helmut Renders

© '99-2002 by S. Kreutzmann