Hi
DP-ler,
lang ist es her, aber jetzt kann ich mich auch mal wieder diesem Tutorial ein wenig widmen. Seit dem letzten Mal ist nun auch Delphi 7 auf dem Markt und deshalb möchte ich, neben der normalen Komponentenerstellung auch ModelMaker etwas genauer unter die Lupe nehmen.
ModelMaker ist bereits seit mehreren Jahren verfügbar und liefert für Delphi ab Version 1 die Möglichkeit
UML für Delphi zu erstellen, Projekte zu verwalten und sogar automatisch Hilfedateien für erstellte Komponenten zu erzeugen. Es wird also interessant. Für diejenigen, welche ein "ältere" Delphiversion nutzen, empfehle ich einen Besuch bei
www.modelmakertools.com, dort könnt ihr u.a. eine Evaluierungsversion heruntersaugen.
Hinweis: Dieses Mal werde ich keine Neuerungen in der Komponentenenticklung zeigen, sondern lediglich unsere letzte Komponente (TSenselessSample) noch einmal erstellen und Zurhilfenahme von ModelMaker.
Let's get started
Startet also Delphi und aus der Delphi
IDE heraus Modelmaker. Wer zwei Monitore an seinem Rechner hat, ist jetzt klar im Vorteil.

Setzt Delphi auf die linke Seite und ModelMaker auf die rechte Seite. Ein Monitor: immer schön hin und her wechseln (Alt+Tab).
In ModelMaker wählt aus dem Menü
File, den zweiten Punkt
New from Default. Wie Ihr merkt, ich habe mal wieder die englische Delphiversion bestellt. Aber die mit der deutschen Variante werdens schon schaffen.
What you see is what you get
oder so ähnlich. Auf der linken Seite von ModelMaker seht ihr oben die verschiedenen Design-Module (Ansicht DM), welche Euch zur Verfügung stehen. Darunter befinden sich die Deklarationen (Ansicht Dekl) innerhalb der aktuell ausgewählten Klasse. Rechts ist die Arbeitsfläche.
Die Darstellung der Arbeitsfläche hängt generell von der aktuellen Aufgabe ab. Nach dem Laden des "Default Templates" seht ihr normalerweise ein einfaches Diagramm, welches die wichtigsten Klassen für Delphi Projekte darstellt.
Let's get started with working
Als wir die Komponente in Delphi erstellt haben, haben wir im Dial
Neu den Punkt
Component ausgewählt. Anschließend haben wir als Ancestor den Typ
TComponent ausgewählt, den Namen unserer Komponente auf
TSenselessSample gestzt, eine Quelldatei festgelegt, und ausgesucht, auf welcher Palettenseite die Komponente installiert wird. Diese Schritte werden wir jetzt in ModelMaker nachvollziehen.
In der Ansicht DM wählt die Klasse
TComponent aus, drückt die rechte Maustaste und wählt den Menüpunkt
Add Descendant, setzt den Namen auf
TSenselessSample. ModelMaker fügt die neue Komponente automatisch an der richtigen Stelle in der Hierarchie ein. Via Drag-n-Drop zieht die neue Komponente in das Standard Diagramm. ModelMaker erkennt automatisch die Beziehung zur Basiskomponente und erstellt einen visuellen Link.
Übung
Ändert manuell den visuellen Link und beobachtet, wie sich die Struktur der Klassenübersicht automatisch anpasst.
Erstellen der Unit für die Komponente
Wählt in der Ansicht DM den Reiter
Units aus. Im Bereich
Classes not assigned to units ist unsere Komponente
TSenselessSample zu sehen. Klickt mit der rechten Maustaste in die Ansicht und wählt
Add Unit aus dem Kontextmenü.
Wählt einen
neuen Namen und Ordner für die
Unit aus. Im unteren Bereich fügt Ihr die
TSenselessSample Komponente zur
Unit hinzu und definiert auf welcher Palettenseite diese dargestellt werden soll. Soweit, so gut!
Automatisches erstellen der Unit
In der oberen Toolbar seht Ihr neben den Standard Neu, Laden, Speichern, ... Buttons ein geöffnetes und ein geschlossenes Schloss. Klickt auf das geöffnete Schloss, um ModelMaker zu erlauben, den Source Code zu generieren.
In der Ansicht DM, im Bereich Units, wählt die neue
Unit aus, klickt mit der rechten Maustaste auf den entsprechenden Eintrag und wählt den Menüpunkt
Enable Auto Generation. Ein grüner Pfeil ist davor zu sehen.
Im Hauptmenü klickt jetzt auf den Punkt
Delphi und selektiert den Eintrag
Open Unit. Jetzt könnte Ihr den erzeugten Quellcode in Delphi sehen. Sehr ähnlich dem Quellcode, wie wir ihn auch das letzte Mal erstellt haben. Aber noch ist nicht annähernd die Funktionalität vorhanden, wie wir diese bei der letzten Version von
TSenselessSample hatten.
Erstellen der Properties
Ob Ihr jetzt in der Ansicht DM :: Classes, oder Ansicht DM :: Units arbeitet ist gar nicht so wichtig, wichtig ist jedoch, dass Ihr sicher stellt, dass unsere Komponente
TSenselessSample ausgewählt ist.
Im unteren Bereich seht die Ansicht Dekl (Deklarationen). Die ersten vier Icons stehen für die Funktionen
- Feld (Klassenvariable) hinzufügen
- Methode hinzufügen
- Property hinzufügen
- Event hinzufügen
Über das dritte Icon fügen wir jetzt sechs Eigenschaften (Properties) hinzu.
Name: X
Visibility: published
Data type: Double
Read Access: Field
Write Access: Method
Write Code: Check
Ext Write Code: Check
Name: Y
Visibility: published
Data type: Double
Read Access: Field
Write Access: Method
Write Code: Check
Ext Write Code: Check
Name: Result_Add
Visibility: published
Data type: User defined
Data type Name: TLabel
Read Access: Field
Write Access: Method
Write Code: Check
Ext Write Code: Check
Name: Result_Sub
Visibility: published
Data type: User defined
Data type Name: TLabel
Read Access: Field
Write Access: Method
Write Code: Check
Ext Write Code: Check
Name: Result_Mul
Visibility: published
Data type: User defined
Data type Name: TLabel
Read Access: Field
Write Access: Method
Write Code: Check
Ext Write Code: Check
Name: Result_Div
Visibility: published
Data type: User defined
Data type Name: TLabel
Read Access: Field
Write Access: Method
Write Code: Check
Ext Write Code: Check
Wenn Ihr Euch jetzt den Source Code in Delphi anschaut, dann ist dieser jetzt bereits erheblich angewachsen. Alle Deklarationen sind bereits eingefügt und die wichtigsten Code Einträge (SetXXX) sind auch schon da.
Nur compilieren würde zur Zeit nicht gehen, da wir im Code auf den Datentyp (Klassentyp)
TLabel verweisen. Deshalb müssen wir eine manuelle Anpassung im Code vornehmen. Diese
darf aber nicht in Delphi geschehen, sondern muss in ModelMaker geschehen, da sonst bei der nächsten Erstellung des Source Codes die Änderung wieder verloren wäre.
Hinweis: Es gibt auch die Möglichkeit Code nach ModelMaker zu re-importieren, aber das gehört jetzt nicht zu diesem Kurs. Genaueres dazu findet Ihr auf der Companion Tools CD 1, bei den Dokumentationen. Da ist auch das komplette Handbuch für ModelMaker als PDF, mit knapp 120 Seiten Umfang.
Ändern des Unit Source Codes
Wählt in der Ansicht DM :: Units unsere
Unit aus. Auf der Arbeitsfläche müsst Ihr, sofern es nicht bereits geschehen ist, oben den Reiter
Unit Code anwählen. Jetzt seht Ihr den
Unit Code, welcher als Vorlage für unsere Komponente dient. Dort seht Ihr auch diese uses Klausel, welche angepasst werden muss, wie auch schon im letzten Beitrag geschehen.
Code:
[b]uses[/b]
SysUtils, Windows, Messages, Classes, Graphics, Controls,
Forms, Dialogs;
[color=#0000FF] // wird zu // [/color]
[b]uses[/b]
SysUtils, Windows, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
Jetzt können wir den nächsten Schritt nehmen.
Die Methode UpdateLabels
Um für alle Labels Ergebnisse anzeigen zu können, fügen wir die Methode
UpdateLabels zum Model. Anstatt das Icon Property in der Ansicht Dekl zu nutzen, klicken wir dieses Mal auf des zweite Icon (Methode). Der Dialog unterscheidet sich nur geringfügig von der letzten Version. Folgende Einstellungen sind vorzunehmen
Name: UpdateLabels
Visibility: private
Data type: Void
Jetzt müssen wir noch den Code einfügen, welcher ausgeführt werden soll. Dazu klickt in der Arbeitsfläche auf den Reiter
Implementation und fügt den folgenden Code ein.
Code:
[color=#000080]// summe ermitteln und darstellen[/color]
[b]if[/b] Assigned(FResult_Add) [b]then[/b]
[b]try[/b]
[color=#000080]// label für summe wurde zugewiesen[/color]
FResult_Add.Caption := FloatToStr(FX + FY);
[b]except[/b]
[b]on[/b] E:
Exception [b]do[/b]
[color=#000080]// oops[/color]
FResult_Add.Caption := E.Message;
[b]end[/b];
[color=#000080]// differenz ermitteln und darstellen[/color]
[b]if[/b] Assigned(FResult_Sub) [b]then[/b]
[b]try[/b]
[color=#000080]// label für differenz wurde zugewiesen[/color]
FResult_Sub.Caption := FloatToStr(FX - FY);
[b]except[/b]
[b]on[/b] E:
Exception [b]do[/b]
[color=#000080]// oops[/color]
FResult_Sub.Caption := E.Message;
[b]end[/b];
[color=#000080]// produkt ermitteln und darstellen[/color]
[b]if[/b] Assigned(FResult_Mul) [b]then[/b]
[b]try[/b]
[color=#000080]// label für produkt wurde zugewiesen[/color]
FResult_Mul.Caption := FloatToStr(FX * FY);
[b]except[/b]
[b]on[/b] E:
Exception [b]do[/b]
[color=#000080]// oops[/color]
FResult_Mul.Caption := E.Message;
[b]end[/b];
[color=#000080]// quotient ermitteln und darstellen[/color]
[b]if[/b] Assigned(FResult_Div) [b]then[/b]
[b]try[/b]
[color=#000080]// label für quotient wurde zugewiesen[/color]
FResult_Div.Caption := FloatToStr(FX / FY);
[b]except[/b]
[b]on[/b] E:
Exception [b]do[/b]
[color=#000080]// oops[/color]
FResult_Div.Caption := E.Message;
[b]end[/b];
Putting UpdateLabels to work
Jetzt müssen wir noch einstellen, das UpdateLabels immer aufgerufen wird, wenn sicher einer der Parameter (Werte, Labels) ändert. Dazu müsst Ihr jetzt in der Ansicht für jede der Zugriffsmethoden (
Access Methods) (SetResult_Add, SetResult_Div, SetResult_Mul, SetResult_Sub, SetX, SetY) folgende Aufgaben erledigen.
Zugriffsmethode in der Ansicht Dekl markieren (auswählen). In der Arbeitsfläche den Reiter
Implemantation auswählen. Links unten seht Ihr jetzt die aktuellen Code Abschnitte, in logische Bereiche getrennt.
Code:
[color=#FF0000]// Abschnitt 1[/color]
if FResult_Add <> Value then
begin
[color=#FF0000]// Abschnitt 2[/color]
FResult_Add := Value;
[color=#FF0000]// Abschnitt 3[/color]
end;
Zwischen Abschnitt 2 und Abschnitt 3 müssen wir jetzt unseren Aufruf zur Methode
UpdateLabels plazieren. Klickt dazu mit der rechten Maustaste in den linken unteren Bereich und wählt den Menüpunkt
Add Section. Anschließend zieht diesen per Drag-n-Drop zwischen den zweiten und den dritten Bereich.
Im Vergleich zu den anderen Bereichen ist dieser nicht "rot-weiss" markiert, sonder grün. Grüne Bereiche sind User-Code, die "rot-weissen" Bereiche werden durch ModelMaker verwaltet. In unseren Bereich fügen wir jetzt einfach den Aufruf zur Methode
UpdateLabels; ein.
Diesen Vorgang jetzt für die restlichen Zugriffsmethoden ausführen
Und nun noch die Methode Notification
Gleich der Methode UpdateLabels wird diese mit folgenden Paramtern eingerichtet.
Name: Notification
Visibility: protected
Call inherited: Checked
Inheritance restricted: Checked
Das Häckchen "Call inherited" fügt den Aufruf zur vorhergehenden Instanz der Methode ein.
Code:
[b]inherited[/b] Notification(aComponent, Operation);
Das Häckchen "Inheritance restricted" bewirkt, dass alle Einstellungen der Methode von der vorhergehenden Definition (TComponent) übernommen wird.
Jetzt müssen wir noch ein wenig User Code einpflegen. Also wieder in der Arbeitsfläche den Reiter
Implementation auswählen, "Add Section" im Kontextmenü auswählen und den folgenden Code mit Copy & Paste einfügen.
Code:
[b]if[/b] (Operation = opRemove) [b]then[/b]
[b]begin[/b]
[b]if[/b] aComponent = FResult_Add [b]then[/b]
FResult_Add := [b]nil[/b];
[b]if[/b] aComponent = FResult_Sub [b]then[/b]
FResult_Sub := [b]nil[/b];
[b]if[/b] aComponent = FResult_Mul [b]then[/b]
FResult_Mul := [b]nil[/b];
[b]if[/b] aComponent = FResult_Div [b]then[/b]
FResult_Div := [b]nil[/b];
[b]end[/b];
Fertig! Jetzt die Komponente, wie bereits im letzten Teil des Kurses beschrieben, installieren und glücklich sein.
Anbei ist das ModelMaker Projekt als Download. Mit dieser Datei könnt Ihr die Komponente vollständig erstellen.
Viel Spass,
bis bald.
...

...