AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials Delphi Formulare mit Eigenschaften und Komponenten ausstatten

Formulare mit Eigenschaften und Komponenten ausstatten

Ein Tutorial von Stevie · begonnen am 7. Okt 2004 · letzter Beitrag vom 21. Jan 2005
Antwort Antwort
Benutzerbild von Stevie
Stevie
Registriert seit: 12. Aug 2003
Hi Leute,

wenn man eine Anwendung schreibt, die aus einer größeren Anzahl von Formularen besteht, dann möchte man sie unter Umständen mit eigenen Eigenschaften und Komponenten, die auf jedem Form nötig sind (z.B. TActionList), ergänzen. Dies ist nicht ganz einfach, denn es reicht nicht einfach, einige published properties in die Deklaration zu schreiben, das Formular in die Objektablage zu bringen und dann von diesem abzuleiten. Es ist nötig, diese Formulare zu registrieren, damit die Eigenschaften auch im ObjektInseptor sichtbar sind.

WICHTIG: Ich habe das ganze nur unter Delphi6Pro und Delphi7Pro getestet. Die vorherigen Version hatten meines Wissens eine etwas andere Architekur, was die DesignTime-Unterstützung angeht. Aber ich denke, es dürfte auch dort funktionieren.

Unser Ziel ist es nun, ein Formular zu erstellen, dass über eine zusätzliche Eigenschaft und eine Komponente verfügt.
Dazu erstellen wir uns zuerst ein neues Package (Datei->Neu->Weitere...). Danach erstellen wir ein neues Formular.
Wichtig ist hierbei, dass wir auf diesem Formular keine Komponenten plazieren dürfen. Warum, wird später klar werden. Dieses Formular dient uns nur dazu, neue Eigenschaften für den Objektinspektor bereitzustellen. Dazu erweitern wir die Deklaration unseres Formulares um eine Eigenschaft. Wir erstellen eine Eigenschaft, die SingleInstance lautet und vom Typ Boolean ist. Damit könnte festgelegt werden, dass dieses Formular nur einmal aufgerufen werden darf (die Implementierung spar ich mir mal). Außerdem ändern wir den Klassennamen, indem wir den Namen des Formulars ändern (ich hab CustomFormEx genommen, "Custom" in Anlehnung an die nicht visuellen Klassen in der VCL und "Ex", weil es eine Erweiterunng ist). Die Deklaration unseres Formulars sieht jetzt wie folgt aus:
Delphi-Quellcode:
type
  TCustomFormEx = class(TForm)
  private
    FSingleInstance: Boolean;
  public
  published
    property SingleInstance: Boolean read FSingleInstance write FSingleInstance;
  end;
Würden wir dieses Formular jetzt ableiten, hätten wir zwar die zusätzliche Eigenschaft SingleInstance, aber könnten sie nicht im Objektinspektor sehen. Deshalb müssen wir dieses Formular noch registrieren. Das machen wir über die Methode Register (wie beim Erstellen einer neuen Komponente). Dazu benutzen wir zwei Funktionen aus der Unit DesignIntf:
Delphi-Quellcode:
procedure Register;
begin
  RegisterCustomModule(TCustomFormEx, TCustomModule);
  RegisterPropertyInCategory(sLayoutCategoryName, 'SingleInstance');
end;
Die erste wird zumindest bei mir nicht in der Hilfe dokumentiert, aber sind nicht gerade die undokumentierten Methoden zumeist die interessantesten?
Diese Methode registriert das Fenster, damit wir die Eigenschaften, die wir hinzugefügt haben, auch im Objektinspektor sehen können. Die zweite Funktion könnten wir uns sparen, aber dann würde die Eigenschaften in der Kategorie Verschiedene landen. Das möchten wir aber nicht, sondern sie soll in der Kategorie Layout stehen. Dazu müssen wir die Kategorie und den Eigenschaftsnamen übergeben. Der Lokalisationsmöglichkeit halber habe ich hier einen resourcestring aus der Unit DesignIntf gewählt, damit auch jemand, der Delphi in einer anderen Sprache benutzt, die richtigen Kategorienamen erhält. Weitere sind:
Delphi-Quellcode:
resourcestring
  sActionCategoryName = 'Aktion';
  sDataCategoryName = 'Daten';
  sDatabaseCategoryName = 'Datenbank';
{$IFDEF MSWINDOWS}
  sDragNDropCategoryName = 'Drag, Drop und Docking';
{$ENDIF}
{$IFDEF LINUX}
  sDragNDropCategoryName = 'Drag und Drop';
{$ENDIF}
  sHelpCategoryName = 'Hilfe und Hinweise';
  sLayoutCategoryName = 'Layout';
  sLegacyCategoryName = 'Legacy';
  sLinkageCategoryName = 'Linkage';
  sLocaleCategoryName = 'Länderkennung';
  sLocalizableCategoryName = 'Übersetzungsrelevant';
  sMiscellaneousCategoryName = 'Verschiedene';
  sVisualCategoryName = 'Visuell';
  sInputCategoryName = 'Eingabe';
Jetzt müssen nur noch die Prozedur Register im interface-Teil der Unit deklariert und die beiden Units DesignIntf, DesignEditors der uses im implementation-Teil hinzugefügt werden. Wenn wir dann die Dateien speichern (ich hab die FormularUnit frCustomFormEx genannt) und das Package installieren, dann wird das Formular und die von uns hinzugefügte Eigenschaft registriert und wir können sie im ObjektInspektor benutzen. Es kann vorkommen, dass die beiden Design-Units nicht gefunden werden. In diesem Fall müsst ihr, den Ordner $(DELPHI)\Source\ToolsAPI zu den Bibliothekspfaden hizufügen. Der Frage, ob andere Packages hinzugefügt werden sollen, stimmmen wir zu.
Schauen wir uns das Ergibnis doch gleich einmal an und kommen damit auch gleich zum 2.Schritt - das Formular mit Komponenten erweitern.

Dazu erstellen wir ein von TCustomFormEx abgeleitetes Form, indem wir über Datei->Neu-Weitere... auf dem Reiter der unseren Package-Namen trägt (das Package muss noch offen und ausgewählt sein) CustomFormEx auswählen (es dürfte nur Vererben auswählbar sein). Wenn wir jetzt im ObjektInspektor nachsehen müsste dort die Eigenschaft SingleInstance vorhanden sein. Wer einem Formular nur zusätzliche Eigenschaften im ObjektInspektor hinzufügen möchte, ist hier fertig. Aber wir möchten ja zusätzlich noch eine Komponente - wir nehmen eine ActionList - auf dem Formular plazieren. Nachdem wir das getan haben, können wir zum Beispiel noch einige EventHandler definieren, was wir jetzt aber nicht tun. Nachdem wir den Namen des Formulars auf FormEx geändert haben, und somit der Klassenname TFormEx lautet, können wir die Unit unter dem Namen frFormEx speichern. Wir haben jetzt über die Objektablage (Datei->Neu->Weitere...) die Möglichkeit, von beiden Formularen abzuleiten, aber wir möchten, dass man nur von TFormEx ableiten kann. Wie machen wir das?

Zunächst entfernen wir die Zeile {$R *.dfm} in der pas-Datei (sie ist dafür zuständig, dass die gleichnamige dfm-Datei geladen und somit ein Formular erzeugt wird). Dann lassen wir uns den Quelltext des Packages anzeigen und löschen in er contains-Klausel den Teil in den geschweiften Klammern hinter frCustomFormEx in 'frCustomFormEx.pas', speichern das Package und löschen zum Schluss auch noch die dfm-Datei. Oben hatte ich erwähnt, dass wir keine Komponenten auf dem ersten Form plazieren wollen, hier wisst ihr jetzt, warum. Ein Aufmerksamer Beobachter wird sicherlich bemerkt haben, dass jetzt nur noch das Symbol für eine pas-Datei im Package zu sehen ist im Gegensatz zu der Unit frFormEx. Jetzt ist unser Formular mit Komponenten und Eigenschaften im Objektinspektor fertig und kann nochmals kompiliert werden. Vorher sollte aber zur Sicherheit die Unit frFormEx geschlossen werden, da es zu Fehlern kommen kann. Dies ist vor allem wichtig, wenn in der Unit frCustomFormEx Änderungen vorgenommen werden. Es kann schonmal zu Fehlern führen, wenn Nachfolger dieses Formulars geöffnet sind.

Somit haben wir jetzt ein Package erstellt, in welchem wir die Basis-Formulare für unsere Anwendung haben. Dieses Package muss immer in diesen Anwendungen vorhanden sein - entweder als bpl, wenn mit Laufzeit-Packages aktualisiert wird oder in die Anwendung hineinkompiliert.

Für Fragen und konstruktive Kritik zu meinem ersten Tutorial bedanke ich mich jetzt schon bei euch.
Angehängte Dateien
Dateityp: zip sourcecode.zip (8,4 KB, 83x aufgerufen)
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
 
Benutzerbild von Dani
Dani

 
Turbo Delphi für Win32
 
#2
  Alt 7. Okt 2004, 15:45
Hi,

erstmal vielen Dank für dieses Tutorial
Ich hab da eine Frage: beim Compilieren erhalte ich diesen Fehler: [Fehler] Undefinierter Bezeichner: 'TCustomModule'

Die Unit DesignIntf habe ich unter implementation eingebunden, die Unit DesignEditors aufgrund des Proxies.dcu-Fehlers nicht. Das Package wird für Design-und Laufzeit verwendet. Was mache ich da falsch? Kann ich auch etwas anderes als TCustomModule angeben (z.B. nil)?
Dani H.
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

 
Delphi 10.1 Berlin Enterprise
 
#3
  Alt 7. Okt 2004, 16:11
Ach, den blöden Fehler hab ich schon ganz verdrängt...
Die Frage wurde schon öfter's auf diesem Forum diskutiert, und es gibt verschiedene Workarounds, weswegen ich dich einfach mal an die Suche verweise (Hier im Forum suchenproxies).
Stefan
  Mit Zitat antworten Zitat
Benutzerbild von MaBuSE
MaBuSE

 
Delphi 10 Seattle Enterprise
 
#4
  Alt 21. Jan 2005, 13:20
Zitat von Stevie:
Ach, den blöden Fehler hab ich schon ganz verdrängt...
Die Frage wurde schon öfter's auf diesem Forum diskutiert, und es gibt verschiedene Workarounds, weswegen ich dich einfach mal an die Suche verweise (Hier im Forum suchenproxies).
Bzw. auf das Tutorial: Lösung: das leidige Problem mit der dsgnintf bzw. proxy.dcu
  Mit Zitat antworten Zitat
Themen-Optionen Tutorial durchsuchen
Tutorial durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz