jQT - Wie funktioniert die BCB-Hilfe?

Was soll das?
Nachdem ich nun schon mehrfach feststellen musste, dass viele die Borland Hilfe als zu kompliziert bezeichnen, mache ich mir die Mühe und versuche anhand der Klasse TMemo ein Beispiel zu machen. Ich werde auch versuchen, das Ganze mit Bildern etwas zu illustrieren, damit auch jeder begreift was ich meine (-;

Ich habe diese Arbeit (es waren doch 2.5h) auf mich genommen, damit die, die vielleicht die Borland Hilfe noch nicht ganz begriffen haben, bzw. sie als lästig empfinden, einen Anhaltspunkt für die Suchmethodik innerhalb der Borlandhilfe bekommen. Die welche sich ab und zu etwas ungerecht von mir behandelt fühlen, weil ich sie im Forum einfach kalt und ohne weiteren Anhaltspunkt auf die Borlandhilfe verweise, möchte ich um Verständnis bitten. Ich bin wahrscheinlich nicht der Einzige der sich über Fragen nervt, welche man, ohne eine Ahnung vom Thema zu haben, einfach mit ein paar Klicksern durch die Borland Hilfe, beantworten kann.

Ja, ich hör schon die ersten schreien: "Aber woher soll ich wissen wonach ich suchen soll?" Jungs: Übung macht den Meister. Ich selber habe insgesamt 3 Jahre gebraucht, um eine gewisse Intuition zu entwickeln, wo ich was finde. Aber das hab ich bestimmt nicht hingekriegt, indem ich bei jeder Frage in ein Forum gepostet habe. Das Suchen in der Hilfe hat zweierlei Vorteile: zum Einen gewöhnt man sich schnell an das Navigieren innerhalb dieses genialen Hilfesystems, zum Andern sieht man beim Suchen haufenweise Dinge, welche man vielleicht nicht für den Moment brauchen kann, aber an die man sich vielleicht später mal erinnert. "Wunschdenken" höre ich da aus der Menge der Lesenden. Ich kann aus Erfahrung sagen, dass ich Tausende von dingen schon gesehen habe, und schon x-fach in Foren genau auf diese erinnerungen gestützt, ohne einmal die Hilfe zur Hand zu nehmen eine Lösungsansatz liefern konnte. Und wenn es nur ein Satz war wie "Ich hab mal ne Funktion gesehen die hiess irgendwas mit Screensaver". Meist kann man dann z.B. bei groups.google.com genau einen Term in dieser Art benutzen um eine Lösung oder einen Newsgroup-Beitrag zu finden welcher dieses Problem behandelt.

Nun aber genug der beLEERenden Worte. Sit back and enjoy
Euer junix

Die (Un-)Logik in der Hilfe
Ja, ich kenne das. Auch ich hatte das Problem, dass mir zu Beginn die Hilfe ausgesprochen unlogisch vorkam. Ich hab geflucht und gezetert. Allerdings lag das weniger daran, dass das Hilfesystem nicht durchdacht war, als vielmehr daran, dass ich einfach den Witz des Hilfesystems nicht begriffen hatte. Gundsätzlich ist das Hilfesystem exakt wie auch C++ Hiarchisch aufgebaut. Jedes Objekt (Klasse) wird in der selben Darstellungsweise beschrieben.

Das Hauptfenster
Öffnet man eine Klassenbeschreibung, begegnet man zuerst dem Hauptfenster dieses Hilfekapitels. Aus dem Hauptfenster interessieren uns nebst der Beschreibung im Wesentlichen die drei folgenden Elemente:

Der Titel enthält im aktuellen Fall den Klassennamen weist uns darauf hin, um welche Klasse es eigentlich geht, sprich welchen Typ-Identifier wir letztendlich im Code brauchen.

Die Navigationsleiste hilft uns dabei, die zu der Klasse gehörenden Informationen wie Eigenschaften, Methoden und - sofern vorhanden - Ereignisse zu finden. Klickt man auf einen dieser Links (abgesehen von Hierarchie), öffnet sich ein weiteres Fenster, in welchem eine Linkliste mit den Eigenschafts-, Methoden- oder Ereignissnamen.
Wenn man auf "Hierarchie" klickt, so erscheint eine Art Popup, welche Links zu sämtlichen Mutterklassen bietet.
Jeder dieser Links in den neu geöffneten Fenstern führt dazu, dass sich im Hauptfenster der Inhalt entsprechend ändert.

Die Headerangabe ist besonders dann interessant, wenn wir uns nicht ganz sicher sind, welche Headerfiles man includen muss. Das kann dann der Fall sein, wenn wir z.B. ein TMemo über den Code erstellen wollen. Fügt man ein TMemo zur Entwurfszeit ins Formular ein, so wird der Header automatisch eingebunden. Wenn das nicht der Fall ist, wäre es im konkreten Fall nötig, im Formularheader die Zeile #include <stdctrls.hpp> einzufügen. (Wer sich bei der Endung nicht sicher ist, sollte auf der Festplatte nach "stdctrls" suchen)


Abb. 1


Abb. 2

Das Popup-Fenster
Grundsätzlich ist es egal ob nun Eigenschaften, Methoden oder sogar Ereignisse. Die Popupfenster sind alle gleich aufgebaut. Ihr einziger Inhalt sind Links, welche so benannt sind, wie der Member von TMemo heisst (Der Einfachheit halber, verwende ich für die Aufzählung "Eigenschaft, Methode oder Ereigniss" den Überbegriff "Member"). Mit einem einzigen Klick veranlasst man das Hauptfenster das wir oben bereits kennengelernt haben dazu, dass es Details zum gewählten Member anzeigt. (Vgl. Abb 3)

Der Link in die Zugehörige Klasse sorgt dafür, dass man das Hauptfenster wieder bequem auf die "Startseite", der wir oben bereits begegnet sind, zurücksetzen kann.

Eine Eigenschaft im Detail
Klickt man nun auf die Eigenschaft Lines, die ich oben bereits markiert habe, dann verändert sich wie versprochen der Inhalt des Hauptfensters.
Der geneigte Leser erkentt sofort, dass sich die Aufteilung des Hauptfensters nicht gross geändert hat. nach wie vor ist die Navigationsleiste vorhanden und auch der Titel hat sich nur geringfügig verändert. Wer sich wundert, wieso da plötzlich TCustomMemo steht, sollte vielleicht nochmal einen Blick auf das Eigenschaftsfenster werfen und sein Augenmerk auf die Zeile "Abgeleitet von..." richten. Oftmals wird eine fertige Komponente von einer Klasse TCustomXXX abgeleitet. Das soll uns hier aber nicht weiter stören.
Wie auch beim Obigen Hauptfenster ist wieder eine Beschreibung vorhanden. Das Einzige was neu ist, ist die Deklaration des Members, die uns hier mitgeteilt wird. Diese Deklaration ist sehr interessant, wenn man mit diesem Member arbeiten will. Sie gibt auskunft über die Datentypen welche der Member verwendet.
Auch hier wird wieder mit einem Link auf den Datentyp verwiesen. Dieser Links beeinflusst wieder das Hauptfenster. Im konkreten Beispiel würde die Klasse TStrings im Hauptfenster erscheinen und das komplette Spiel würde wieder von Vorne beginnen.


Abb. 3

Ein Fallbeispiel

Um das ganze Geschwafel etwas zu verdeutlichen, möchte ich an dieser Stelle ein Beispiel für die Herleitung einer Anweisung machen. Konkret geht es darum, eine Zeile zu einem Control mit dem Namen Memo1 hinzuzufügen. Das Control ist vom Typ TMemo um den obigen Beispielen treu zu bleiben.

Programmzeile: Form1->Memo1 //-- Mehr wissen wir zu diesem Zeitpunkt noch nicht.

Der erste Schritt ist bestimmt der, dass wir uns in der Hilfe mal schlau machen, welche Eigenschaft für den Inhalt im Memo1 verantwortlich ist. Geht man die Eigenschaften von TMemo durch, wird man schnell über die Eigenschaft Lines stossen, deren Beschreibung eigentlich genau das verspricht, was wir suchen:

Beschreibung
Mit Hilfe der Eigenschaft Lines kann der Text in einem Memofeld zeilenweise bearbeitet werden. Lines ist ein TStrings-Objekt, so daß die TStrings-Methoden für Lines verwendet werden können, um Bearbeitungen wie Zählen der Textzeilen sowie Hinzufügen, Löschen und Ersetzen von Zeilen durchführen zu können.

Was wir also sicher entnehmen können ist, dass wir auf die Eigneschaft "Lines" zugreifen müssen. Diese Aussage löst zwar noch nicht unser Problem, aber immerhin kommen wir in unserer Programmzeile einen Schritt weiter:

Programmzeile: Form1->Memo1->Lines

Wie kommen wir nun aber soweit, dass wir einen String hinzufügen können? Die Eigenschaft "Lines" ist vom Typ "TStrings". Die Jungs von Borland waren so clever, aus TStrings bereits einen Link zu machen. Also klicken wir mal drauf. Es eröffnet sich uns ein vertrautes Bild. Wir durchsuchen sämtliche Methoden und Eigenschaften von TStrings, bis wir über eine interessante Memberfunktion stolpern:

Mit der Methode Add läßt sich ein String am Ende der String-Liste anfügen.

virtual int __fastcall Add(const System::AnsiString S);

Das bringt uns nun wirklich weiter. Ein Versuch ists wert. Wir ergänzen die Programmzeile also um den String "Add("Test");" um auszuprobieren obs denn nun wirklich so klappt.

Programmzeile: Form1->Memo1->Lines->Add("Test");

Ein Test wirds zeigen, es funktioniert. Das Ende einer Odysee (:

Zurück zur Übersicht