Die erste MDI-Anwendung

Laut Rahmenplanvorgabe soll in die Programmierung anhand eines komplexeren Programms eingeführt werden. Bei der prozedural-orientierten Programmierung wurde dazu oftmals ein Programm benutzt, welches viele Prozeduren verwendete, möglichst auf viele Units verteilt. Selbiges Prinzip lässt sich auf Delphi übertragen und unter einem objektorientierten Paradigma fortführen. Ein Programm wird erstellt, welches aus möglichst vielen Objekten besteht. Jedes Objekt wird in einer Unit gespeichert und schon sind die Parallelen mehr als überdeutlich.

In beiden Fällen wird davon ausgegangen, dass ein "einfaches" Programm, welches ohne selbstgeschriebene Prozeduren oder Objekte auskommt, als simpel angesehen wird. Komplexität entsteht durch Aufspaltung des Quellcodes auf viele Unterroutinen. Betrachtet man Delphi stellt man schnell fest, dass selbst ein einfaches Programm sehr komplex ist, wenn man die Anzahl der benötigten Dateien zur Realisierung als Maß nimmt. Auch wenn nur ein Formular verwendet wird und nicht - wie gemäß gutem Stil üblich - eine eigene Unit für die Verarbeitungsmethoden gestaltet sondern der Code direkt in die GUI-Methoden implementiert wird, benötigt man die Projekt-Dateien, die Form1-Dateien, die .dcu und die .cfg Dateien, dazu mitunter Grafiken usw. Dazu kommen noch die Backup-Dateien, so dass schnell ein Dutzend Dateien zusammenkommen.

Komplexität lässt sich aber auch einfacher erreichen: eine MDI-Applikation bietet eine gute Lösung. Das Konzept möchte ich anhand eines Beispiels genauer erläutern und die Realisierung vorstellen. Vorher führe ich aber noch einige kurze Erklärungen an. Abschließend gehe ich auf den Einsatz im Unterricht ein.

Normalerweise besteht eine Delphi-Programm aus verschiedenen Formularen. Alle Formulare werden bei Programmstart automatisch einmal generiert und verbleiben dann im Speicher. Das erste Fenster bietet dem Benutzer die Möglichkeit, die anderen Fenster aufzurufen. Der Aufruf erfolgt entweder modal oder nichtmodal, was bedeutet, dass das neue Formular entweder über dem aufrufenden Formular erscheint und verbleibt oder dass es dort nur erscheint und von einem anderen überdeckt werden kann. Jedes Formular darf aber nur einmal existieren. Das Anlegen und Entfernen aus dem Speicher ist dabei durch Delphi automatisiert. Diese Einstellungen sind die Standart-Einstellungen von Delphi.

Ein MDI-Programm funktioniert ein wenig anders. Zunächst gibt es ein Formular, welches als MDI-Parent unter FormStyle deklariert wird. Nach Windows-Spezifikation besteht das Programm aus einem Menü und einer möglichst großen Arbeitsfläche, dazu eventuell einer Toolbox und/oder verschiedener Iconleisten. Beispiele dafür wären moderne Textverarbeitungsprogramme wie Word oder Word Pro oder Grafiksoftware wie Paintshop. Alle weiteren Formulare (oder zumindest die meisten anderen, oft sind Infoscreens klassische Showmodals) werden als MDI-Childs unter Formstyle deklariert. Diese Fenster werden dann innerhalb der Arbeitsfläche angezeigt, nachdem sie per Icon oder Menü-Eintrag erzeugt (!) und aufgerufen wurden. Werden die Fenster verkleinert, erscheinen sie als Balken unten in der Arbeitsfläche, maximiert nehmen sie nur die komplette Arbeitsfläche ein. Beim Schließen eines Fensters muss sich dieses selbst zerstören. Der große Vorteil dabei ist, dass mehrere Fenster eines Typs gleichzeitig angezeigt und abwechselnd bearbeitet werden können (etwa mehrere Texte unter Word). Dazu müssen aber auch einige Projekteinstellungen unter Delphi geändert werden (siehe unten).

Als kleiner Ausblick sei angemerkt, dass jedes Formular ein Objekt ist, mehrere Instanzen erzeugt werden können, der Objekt-Charakter sichtbar wird, obwohl fast kein Code programmiert werden muss. Komplexität entsteht durch Objektverwaltung bei minimalem Quellcode. Es geht weniger um viele Befehle als um komplexe Konzepte (dazu mehr bei der Betrachtung möglicher Unterrichtssituationen).

Bevor ich auf die Vor- und Nachteile im Unterricht zu sprechen komme, möchte ich das Beispielprogramm vorstellen und die Realisierung erklären. Anhand dessen sollte es möglich sein, das Beispielprogramm im Unterricht zu benutzen oder ein eigenes zu erstellen.

Es wird ein Programm erzeugt, welches eine leere Arbeitsfläche anbietet und ein Hauptmenü, über welches drei Fenster aufgerufen werden können. Eins stellt nur Text dar, eins zeigt ein Bild und das dritte erlaubt das Lösen einer einfachen Rechenaufgabe. Dazu verwendet dieses dritte Fenster eine Routine, welche in einer Code-Unit beinhaltet ist. Die beiden anderen Units benutzen ausschließlich ihre eigene Form-Unit, die die GUI-Abfragen behandelt, die dritte besitzt natürlich ebenfalls eine Form-Unit.

Zunächst wird das Hauptformular erstellt und die FormStyle-Property in fsMDIForm geändert. Einzige Komponente des Hauptfensters ist ein Menü. Das Datei-Menü besitzt nur einen Eintrag zum Beenden, das Ansicht-Menü beinhaltet jeweils einen Eintrag zum Aufrufen einer Instanz eines Child-Forms. Das Fenster-Menü beinhaltet schließlich Anordnungsbefehle.

Anschließend werden alle zukünftigen Child-Formulare ganz normal gestaltet, sie können auch Code-Units oder Objekt-Units verwenden oder auf andere Units zugreifen.

Mit dem Befehl TFormX.Create(Self) wird eine Instanz eines Formularobjektes erzeugt. Am besten wird dieser Befehl unter der entsprechenden Hauptmenü-Methode eingefügt. Natürlich müssen vorher die entsprechenden Units implementiert werden, das automatisierte Einfügen während der Compilierung funktioniert aber aufgrund der geänderten Projekteinstellungen (siehe unten) nicht mehr.

Diese Einstellungen lassen sich über das Menü Projekt->Optionen aufrufen. Dort wird das Register Formulare aufgerufen. Das Hauptformular muss das MDI-Parent-Form sein. Es wird außerdem automatisch erstellt, also unter Autom. Formularerstellung aufgeführt. Die MDI-Childs werden als Verfügbare Formulare geführt. Entsprechende Einstellungen müssen hier von Hand vorgenommen werden.

Wird das Programm jetzt compiliert, werden die Formulare angezeigt, sobald der entsprechende Menüeintrag angewählt wird. Die Child-Formulare können aber noch nicht geschlossen oder angeordnet werden.

Um die Formulare aus dem Speicher zu entfernen, benötigt man lediglich einen Befehl an der richtigen Stelle. Jedes Formular besitzt das Ereignis OnClose. Die passende Botschaft wird gesendet, wenn das Formular geschlossen werden soll (durch Anklicken des Close-X oder durch Aufruf des Befehls close). Die behandelnde Methode heißt TFormX.FormClose. Dort muss die Speicherfreigabe angeordnet werden. Der Befehl lautet: Action:=caFree; Wird dieser Befehl weggelassen, schließen die Child-Forms nicht sondern werden lediglich als Symbol unten links auf der Arbeitsfläche angeordnet.

Sehr kurz lassen sich die Anordnungsbefehle erklären. tile ordnet alle Child-Forms nebeneinander an, cascade überlappend. Mit arrangeicons werden alle Symbole unten links angeordnet. Diese Befehle sind in keinster Weise entscheidend, es hat sich aber als Standard etabliert, dieses Menü dem Anwender anzubieten.

Eine MDI-Applikation als Einführungsprogramm ist zugegebenermaßen durchaus mit Vorsicht zu genießen, kann meiner Meinung nach aber sehr erfolgreich sein, wenn man seinem Plan treu bleibt und sich nicht zu früh in Details verliert.

Das erste Problem ergibt sich aus der komplexen Oberfläche. Es bietet sich an, nach dem Start von Delphi nicht sofort das Programm aufzurufen. Zunächst sollte erklärt werden, was auf dem Bildschirm sichtbar ist, dass heißt sowohl die obere Leiste, der Objektinspektor mit Properties und Ereignissen aber auch die Arbeitsfläche und der Quelltexteditor müssen den Schülern vermittelt werden. Dabei sollten aber noch nicht die einzelnen Buttons oder Funktionen erläutert werden, der Zweck des Bereiches sollte zunächst ausreichen. Probehalber können die Schüler nun einen Button anlegen, der nichts weiter macht, als das Fenster zu beenden. Er bekommt die Caption beenden, das Ereignis OnClick und dazu den Befehl close. Wird die Taste F9 gedrückt, startet das Programm. Damit haben die Schüler das Grundprinzip bereits einmal angewendet.

Wird jetzt das Projekt geladen, können die Schüler die Properties des ersten Formulars erkunden. Auch das Menü und die damit verbundenen Ereignisse und Einträge können betrachtet werden. An dieser Stelle bietet sich die erste selbständige Gruppenarbeit an. Vorher halte ich das "Erkunden auf eigene Faust" für problematisch, verlieren sich Ungeübte doch zu schnell in den Tiefen der Delphi-Oberfläche. Daher würde ich zunächst auf relativ viel Lehrergespräch setzen, das Erstellen des ersten "Ich schließe mich selber"-Programmes könnte mit einem Arbeitsblatt geleitet werden.

Die Arbeit am Projekt würde meines Erachtens nach durch die oben beschriebene kurze Vorarbeit sehr erleichtert werden. Zwar ließe sich das erste Programm auch weglassen und die Oberfläche parallel zum Projekt erklären, doch würde das die Schüler zu noch mehr Passivität zwingen. Wissen die Schüler aber bereits um die Umsetzung der Konzepte "Oberflächenobjekte sind existent, besitzen Eigenschaften zur Gestaltung und erlauben die Abarbeitung eines Quelltextes, wenn eine Ereignis (das Anklicken) eintritt", dann lassen sich die Konzepte nun am Programm selbst sehr viel einfacher erarbeiten. Um Missverständnisse noch einmal auszuräumen: das erste Programm soll die Schüler nur dazu bringen, bestimmte Konzepte anzuwenden, ohne von diesen bereits zu wissen. Das MDI-Projekt soll die Möglichkeit bieten, die Konzepte zu erkennen und durch den Wiedererkennungseffekt die Sicherheit zu stärken und die Scheu vor ihnen zu verlieren.

Nach dem Laden des Projektes erscheint zunächst das erste Formular. Die Schüler werden feststellen, dass das Formular über dieselben Eigenschaften verfügt, diesen aber andere Werte zugeordnet sind. Als wichtige Erkenntnis daraus ergibt sich, dass Formulare Gebilde gleichen Typs sind, deren Aussehen durch Eigenschaften gesteuert wird. Die Begriffe Objekt und Attribut können hier bereits eingeführt werden. Betrachtet man anschließend die Menü-Komponente wird deutlich, dass auch diese ein Objekt ist, allerdings ein Objekt eines anderen Typs. Es folgt die Erkenntnis: Formular und Menü sind unterschiedliche Objekte mit unterschiedlichen Attributen. Betrachtet man das Menü weiter, fallen schnell die Aufrufmethoden auf. Es ergibt sich: Wird ein Objekt vom Benutzer oder vom Programm in irgendeiner Weise manipuliert, tritt ein Ereignis auf. Botschaften sollten an dieser Stelle noch nicht behandelt werden, können aber später diese Stelle wieder aufgreifen. Dieses Ereignis führt in der Regel dazu, dass entweder nichts passiert oder ein Stück Quellcode abgearbeitet wird.

Jetzt ist der Zeitpunkt gekommen, den Quelltexteditor aufzurufen und erneut den close-Befehl zu suchen. Grundsätze des Quellcodes wie das Abarbeiten Befehl nach Befehl etc. können jetzt angesprochen werden, jedenfalls soweit sie nachvollzogen werden können. Suchen die Schüler im Quelltext weiter, werden die Create aufrufe zu Fragen führen: Was wird dort aufgerufen?

Die anderen Formulare können jetzt geladen werden. Eine Betrachtung der Formulare führt zu folgender Erkenntnis: Formular1 und Formular2 sind Instanzen eines Objektes mit gleichen Attributen aber unterschiedlichen Attribut-Werten. Starten die Schüler das Programm, erkennen sie vermutlich sogar, dass das Programm durchaus erlaubt, mehrere Instanzen eines Objektes aufzurufen.

Zugegebenermaßen sind Formulare als Objekte relativ komplex. Zieht man aber die oben angeführten Parallelen zu Word und erinnert daran, dass Texte auch Objekte waren, die bearbeitet wurden und Eigenschaften oder Attribute besaßen, können die Schüler sehr gut nachvollziehen, was sich hinter dem Objektgedanken bei der OOP verbirgt.

Wie schnell man an dieser Stelle fortfahren kann, ob man die Konzepte vertieft, Oberflächenobjekte wie Buttons oder Labels einführt, sich in den Quellcode weiter vertieft, oder sich der Oberfläche widmet, sei jedem selbst überlassen. Abhängig ist dies sicherlich vom weiteren Vorgehen, den Schülern und der Zeit. Das Projekt bietet sich auch sehr gut an, sich in verschiedene Richtungen zu orientieren und stückweise das Wissen der Schüler auf- und auszubauen. Natürlich kann das Programm auch zunächst beiseite gelegt werden und später immer wieder als Bezugspunkt herausgesucht werden, wenn etwas Neues erarbeitet wurde.

Im vorgestellten Stoffverteilungsplan begleitet das Programm die Schüler zu Beginn, hauptsächlich sollen die Schüler aber anhand von Arbeitsaufträgen gezielt manipulieren können. So könnten Beschriftungen, Farben oder Größen geändert werden. Nachdem der Umgang mit dem Quelltexteditor angesprochen wurde, könnte auch die Aufgabe gestellt werden, die Rechenaufgabe zu verändern (weshalb auf die sqr-Funktion verzichtet wurde, um das Manipulieren für Anfänger zu erleichtern). Spätestens an diesem Punkt taucht die Frage auf, wieso sich der entsprechende Quelltext in einer anderen Unit befindet. Die Konzepte "Grafische Oberfläche über der Unit zur Problemlösung" und "Grafische Objekte als Darstellungslösung für Problembeschreibungen und -lösungen" können jetzt behandelt werden. Das erste bedeutet, dass die eigentlichen Problemlösungen in einer Unit gekapselt werden, die mit der Darstellung dieser Lösungen nichts zu tun hat. Das zweite bedeutet, dass GUI-Objekte zur Variableneingabe und -ausgabe dienen, das heißt, dass sie Problemstellungen oder -lösungen darstellen können. Sie sind quasi Werkzeuge mit der Aufgabe, das Wirken anderer Werkzeuge darzustellen und deren Bedienung zu ermöglichen.

Ein wichtiger Punkt mag an dieser Stelle noch der MDI-Charakter sein. Die ersten Schülerprogramme werden vermutlich nur ein Formular benutzen, ein eventuelles zweites Formular wird wahrscheinlich mit showmodal aufgerufen. Dementsprechend sollte das MDI-Konzept noch nicht vertieft werden. Beim Thema Datenbanken könnten MDI-Anwendungen aber wieder aktuell werden, ein Rückgriff auf das "gute alte erste Projekt" würde sich in diesem Fall wohl sehr anbieten.


MDI-Programm (ZIP-Download 193kb)

zurück zur Erläuterung des Gesamtkonzeptes
zurück zur Gesamtübersicht