Komponente schreiben, Teil 1

Komponente schreiben, Teil 1


Zuerst in einer dreiteiligen Serie Bedeckung Komponente in Delphi schreiben.




Dieser Artikel erschien ursprünglich in Delphi-Entwickler



Copyright Pinnacle Publishing, Inc. Alle Rechte vorbehalten.







Dieser erste Teil veranschaulicht einige der besten Ansätze zu Bauteilen und gleichzeitig bietet Tipps zur Entscheidung über die beste Basisklasse erben, mit Hilfe von virtuellen Declarations, den Prozess der überschreiben, und so weiter.



Die ersten beiden Dinge zu Fragen sind warum Sie vornehmen sollten, verwenden der Komponente schreiben, und wann sollten Sie eine Komponente schreiben müssen. Die erste Frage ist leicht zu beantworten, in der Tat, es hat viele Antworten.


  • Anwenderfreundlichkeit: gekapselte Code bedeutet, dass Sie einfach dieselbe Komponente auf verschiedene Formulare wieder ablegen können ohne eine einzige Zeile Code zu schreiben.

  • Zum Debuggen: Zentralisierte Code erleichtert, eine gesamte Anwendung (oder eine Reihe von Anwendungen) durch das Beheben eines Fehlers in einer einzigen Komponente und neu kompilieren zu reparieren.

  • Geld: Es gibt viele Firmen, die nur allzu gerne für das Privileg, nicht das Rad neu erfinden zu zahlen sind.



Die zweite Frage ist nicht allzu schwer, entweder zu beantworten. Wann immer Sie sich finden dasselbe Schreiben Code mehr als einmal ist es eine gute Idee, eine Komponente zu schreiben, vor allem, wenn der Code anders führt basiert auf den angegebenen Parametern.



Erstellung von Komponenten

Der erste Schritt ist die Basisklasse entscheiden, Sie die Komponente aus abgeleitet werden müssen. Wenn Sie von einer anderen Klasse ableiten, erben Sie Eigenschaft / Methode und das Ereignis, das die Komponente besitzt. Unten ist ein Beispiel wie man welche Klasse entscheiden, Sie Vererben sollten, wenn Sie Ihre eigene Komponente zu schreiben.



(Klicken für Vollansicht)



Click to view full size



Im Falle von Methode A und Methode B vermuten Sie, dass die betreffende Komponente TMemo ist.










MethodeLösung




A




Leiten von TMemo







B




Leiten von TCustomMemo







C




Leiten von TCustomControl







D




TGraphicControl abgeleitet







E




TComponent abgeleitet









Dies kann ein wenig kompliziert erscheinen, lassen Sie mich erklären, den Prozess.



A: Wann müssen Sie einfach zusätzliche Funktionen zu einer vorhandenen Komponente hinzuzufügen Sie von dieser Komponente leiten. Dies wird der neuen Komponente automatisch alle vorhandenen Funktionen und Eigenschaften der vorhandenen Komponente geben.



B: manchmal müssen Sie nicht nur Funktionalität hinzufügen, aber du musst es gleichzeitig zu entfernen. Die Norm üben, wenn eine Komponente geschrieben wird zunächst eine TCustomXXXXX-Komponente zu schreiben wo alle Eigenschaften / Ereignisse und Methoden innerhalb des geschützten Abschnitts der Komponente deklariert werden. Die eigentliche Komponente wird von dieser Basisklasse abgeleitet. Der Trick ist daher nicht ausblenden, Funktionalität, sondern zu 'Benutzerdefiniert' Version der Komponente die Komponente abgeleitet und veröffentlichen nur die Eigenschaften, die Sie behalten möchten (effektiv entfernen unerwünschte Eigenschaften / Ereignisse).



C: alle Komponenten, die den Fokus erhalten soll, braucht ein Fensterhandle. TWinControl ist, wo dieses Handle zuerst eingeführt wird. TCustomControl ist einfach ein TWinControl mit eigener Canvas-Eigenschaft.



D: TGraphicControl verfügt nicht über ein Fensterhandle und daher nicht Fokus erhalten. Komponenten wie TLabel werden von dieser Basisklasse abgeleitet.



E: einige Komponenten werden nicht erstellt, GUI Interaktivität, sondern Ihr Leben einfacher machen. Alles von TComponent abgeleitet wird nur zur Entwurfszeit angezeigt. Eine typische Verwendung dieser Art von Komponente ist für Datenbankverbindungen, Timer etc..



Sobald wir entschieden haben, was unsere Basisklasse sein sollte, ist der nächste Schritt zum Erstellen der Komponente. Im Menü Komponente sehen neue Komponente auswählen und Sie den folgenden Dialog.



New component







Vorgängertyp




Dies ist der Basistyp, dem wir von abstammen müssen







Klassenname




Dies ist der Klassenname unserer neuen Komponente

(mit dem Präfix mit dem Buchstaben 'T')







Farbpalette-Seite




Dies ist die Registerkarte auf der Komponenten-Palette Sie möchten Ihre

Komponente auf, erscheint eine nicht vorhandene Registerkarte Eingabe wird sagen

Delphi, die Sie eine neue Registerkarte erstellt gern.







Schreiben von code

Schon ist es Zeit für uns, etwas zu schreiben. In diesem erste Beispiel müssen nützt überhaupt außer zeigen einige grundlegende Konzepte der Komponente schreiben.



Zunächst wählen Sie die Komponente aus dem Delphi-Hauptmenü und wählen Sie dann neue Komponente. Geben Sie TComponent als 'Vorgängertyp' und TFirstComponent wie der Name der Komponente. Klicken Sie die Schaltfläche 'Installieren'.



An dieser Stelle können Sie die neue Komponente in ein vorhandenes Paket (ein Paket hält eine Sammlung von Komponenten) installieren oder in ein neues Paket installieren. Klicken Sie auf 'in neue Paket', und klicken Sie auf 'Durchsuchen'.



Install component



Einmal haben Sie einen Pfad und einen Dateinamen für das neue Paket ausgewählt und eingegeben eine Beschreibung klicken Sie auf 'OK'. Im nächsten Dialogfeld (gefragt, ob Sie Ihr Paket kompilieren möchten) klicken Sie auf 'Ja'. Nachdem das Paket kompiliert und installiert ist, speichern Sie Ihr Paket und Einheit.



An dieser Stelle haben wir unsere Basisklasse, und auch unsere neue Klassenname angegeben. Wir haben ein neues Paket um unsere Komponente enthalten und wurden mit einem Skelett Klassenstruktur dargestellt von Delphi erstellt.



Schaut man sich den Quellcode zur Verfügung gestellt von Delphi sehen Sie jetzt die Private, Protected, Public und veröffentliche Abschnitte.



Kapselung

Kapselung ist ein einfaches Konzept zu begreifen, aber äußerst wichtige Komponente schreiben. Kapselung erfolgt mit dem Einsatz von vier reservierte Wörter: Private, Protected, Publicund veröffentlicht, Sie werden sehen, das Delphi hat diese Abschnitte automatisch in den Quellcode für die neue Komponente enthalten.











































AbschnittBarrierefreiheit
PrivateMethoden, Eigenschaften und Ereignisse, die in diesem Abschnitt deklariert werden nur

zugänglich für die Einheit die Komponente enthalten ist

innerhalb. Komponenten in derselben Einheit können jeder zugreifen

anderen privaten Elemente.
GeschütztMethoden, Eigenschaften und Ereignisse, die in diesem Abschnitt deklariert werden auch

für jede Klasse zugänglich stammte aus dieser Klasse.
ÖffentlichkeitMethoden, Eigenschaften und Ereignisse erklärt hier von überall her zugänglich.
VeröffentlichtIn diesem Abschnitt können Sie Eigenschaften deklarieren / Ereignisse, die in angezeigt werden die

Objektinspektor. Diese Einstellungen sind Design-Time-Werte

die mit Ihrem Projekt gespeichert werden. (Nicht alle Typen sind

unterstützt, sind Arrays beispielsweise nicht).







Unsere Komponente zu schreiben beginnen

Delphi muss jetzt alles über unsere neue Komponente wissen. Geben Sie den folgenden Code in den Quelltext der Komponente.











Private

{Private Deklarationen}

FStartTime,

FStopTime: DWord;

geschützt

{Protected Deklarationen}

Funktion GetElapsedTime: String; virtuelle;

öffentliche

{Public Deklarationen}

Verfahren Start; virtuelle;

Verfahren Stop; virtuelle;



Eigenschaft StartTime:DWord FStartTime Lesen ;

Eigenschaft StopTime:DWord FStopTime Lesen ;

Eigenschaft ElapsedTime: string Lesen GetElapsedTime;

veröffentlicht

{Published Deklarationen}

end;





Was wir hier getan haben, wird zwei Variablen FStartTime und FStopTime (es ist standard zu sezten Variablennamen mit dem Buchstaben F) hinzugefügt. Es gibt zwei Methoden zum Steuern dieser Variablen Start und Stop. Wir haben eine GetElapsedTime-Funktion hinzugefügt, die FStopTime - FStartTime als Zeichenfolge zurückgibt. Schließlich haben wir drei schreibgeschützte Eigenschaften hinzugefügt.



Drücken Sie UMSCHALT-STRG-C und Delphi wird automatisch vervollständigen den Code für die Klasse (oder klicken Sie die Rechte Maustaste und wählen Sie 'Complete Klasse am Cursor'). Geben Sie den folgenden Code für jede entsprechende Methode.













{TFirstComponent}

Funktion TFirstComponent.GetElapsedTime: String;

beginnen

Ergebnis: = IntToStr (FStopTime - FStartTime);

end;



Verfahren TFirstComponent.Start;

beginnen

FStartTime: = GetTickCount;

end;



Verfahren TFirstComponent.Stop;

beginnen

FStopTime: = GetTickCount;

end;



end.





Testfahrt

Speichern Sie Ihre Einheit, und öffnen Sie Ihr Paket (Datei, Projekt öffnen aus dem Menü, und wählen Sie 'Delphi-Paket' für den Dateityp), sobald Ihr Paket geöffnet ist klicken Sie auf 'Compile'. Sie können Ihr Paket auch öffnen, indem Sie im Hauptmenü und dann installieren Pakete Komponente auswählen. Wählen Sie Ihr Paket und klicken Sie auf die Schaltfläche 'Bearbeiten'.



Sie können jetzt droppen ein TFirstComponent in ein Formular, in der Tat, Sie ablegen können, so viele wie Sie möchten. Fügen Sie zwei Schaltflächen (BtnStart und BtnStop) und fügen Sie folgenden Code in das Formular, und führen Sie dann Ihre Test-app'.













Verfahren TForm1.btnStartClick(Sender: TObject);

beginnen

FirstComponent1.Start;

end;



Verfahren TForm1.btnStopClick(Sender: TObject);

beginnen

FirstComponent1.Stop;

Bildunterschrift: = FirstComponent1.ElapsedTime;

end;





Durch Klicken auf die Schaltfläche 'Start' wird die Startzeit markieren (GetTickCount ist ein WinAPI-Befehl, der gibt die Anzahl der Millisekunden seit dem Start von Windows).



Sie auf die Schaltfläche 'Stop' wird die Stillstandszeit zu markieren und ändern Sie die Beschriftung des Formulars.



Virtuelle, dynamische, Abstract und Override

Sie können virtuelle Erklärung nach Start, Stop und GetElapsedTime aufgefallen. In der folgende Übung werden ihre Verwendung erklären.



Eine neue Komponente erstellen, leiten Sie diese Komponente von TFirstComponent (nennen Sie es TSecondComponent) und installieren Sie es.



Die Virtual und Dynamic-IDs sind eine Komponente des Schriftstellers von Delphi zu sagen, dass die Methode in einer untergeordneten Klasse ersetzt werden kann. Wenn wir eine Methode in einer Klasse zu überschreiben, wird unsere neue Code anstelle der ursprünglichen Code ausgeführt.













geschützt

{Protected Deklarationen}

Funktion GetElapsedTime: String; außer Kraft setzen;





Wir implementieren Sie dann den obigen Code wie folgt.













Funktion TSecondComponent.GetElapsedTime: String;

var

S: String;

beginnen

S: = GetElapsedTime; geerbt

Ergebnis: = S + ' Millisekunden oder ' +

Format ('%.2f Sekunden',

[(StopTime-StartTime) / 1000]);

end;





Unsere neue Code heißt jetzt anstelle des ursprünglichen GetElapsedTime, auch für Verbindungen in der TFirstComponent GetElapsed Zeit implementiert jetzt rufen unsere neuen Code (wenn wir eine Instanz des TSecondComponent, die ist erstellt haben). Der ursprüngliche Code wird mithilfe des Befehls Inherited aufgerufen.



Hinweis: Wenn Sie nicht 'eine Basismethode überschreiben' (da die Basis nicht als virtual deklariert wurde oder weil Sie vergessen haben). TSecondComponent wird den neuen Code aufrufen, Code implementiert in TFirstComponent noch weiterhin den ursprünglichen Code von TFirstComponent aufgerufen.



Der abstrakte Bezeichner erzählt Delphi nicht zu keinen Code für die benannte Methode zu erwarten. Sie sollten eine Instanz eines Objekts nicht mit abstrakten Methoden in ihnen (z. B. TStrings) erstellen. Die Norm üben ist ein Nachkomme einer solchen Klasse erstellen und alle abstrakte Methoden überschreiben (z. B. TStringList tut).



Dynamische Vs virtuell ist einfach eine Frage der Geschwindigkeit Vs Größe. Eine dynamische Methode führt jede Instanz einer Klasse erfordern weniger Speicher, wohingegen eine virtuelle Methode schneller, um den Preis ein wenig zusätzlichen Speicher ausgeführt wird.



Es gibt ein paar einfache Schritte, um Ereignisse an die Komponente hinzufügen. Ereignisse ermöglichen die Komponente, mit der Anwendung zu kommunizieren, um zu benachrichtigen, wenn etwas wichtiges passiert ist. Ein Ereignis ist lediglich ein lesen / Schreib-Eigenschaft, anstatt einen einfachen Variablentyp (z. B. String, Ganzzahl etc.) ist es, eine Prozedur oder Funktion.



Erstellen Sie eine neue Komponente, gehen sie auf TSecondComponent und nennen Sie es TThirdComponent. Speichern der Einheit, installieren Sie die Komponente, und fügen Sie folgenden Code.











Typ

TState = (StStarted, StStopped);

TStateChangeEvent = Verfahren Sender: TObject; Zustand: TState) des Objekts;



TThirdComponent = Klasse(TSecondComponent)

private

{Private Deklarationen}

FState: TState;

FOnStart,

FOnStop: TNotifyEvent;

FOnStateChange: TStateChangeEvent;

geschützt

{Protected Deklarationen}

öffentliche

{Public Deklarationen}

Konstruktor Create(AOwner: TComponent); außer Kraft setzen;

Destruktor Zerstören; außer Kraft setzen;

Verfahren Start; außer Kraft setzen;

Verfahren Stop; außer Kraft setzen;

Eigenschaft Zustand: TState Lesen FState;

veröffentlicht

{Published Deklarationen}

Eigenschaft OnStart: TNotifyEvent Lesen FOnStart FOnStart Schreiben ;

Eigenschaft OnStateChange: TStateChangeEvent Lesen , FOnStateChange

Schreiben FOnStateChange;

Eigenschaft OnStop: TNotifyEvent Lesen FOnStop FOnStop Schreiben ;

end;





Ereignisse werden nur Prozeduren oder Funktionen (selten), die zu einer Klasse gehören (daher die Klausel 'des Objekts' Sie sehen in der TStateChangeEvent). Z. B. TNotifyEvent ist ein standard-Ereignis-Typ implementiert von Delphi, das nur das Objekt übergibt, der das Ereignis ausgelöst, es ist immer gut, 'Selbst' zu senden (Sender: TObject) als ersten Parameter eines beliebigen Ereignisses als das gleiche Ereignis Code für mehrere Komponenten verwendet werden kann.



TNotifyEvent ist definiert als











Typ

TNotifyEvent = Prozedur (Sender: TObject) des Objekts;





Um ein Ereignis von innerhalb einer Komponente aufzurufen ist nur ein Fall von überprüft wird, ob das Ereignis zugewiesen wurde, und wenn ja, nennen es. Ich haben die Start- und Stop-Methoden der TSecondComponent überschrieben, um diese Ereignisse auslösen wie folgt.













Verfahren TThirdComponent.Start;

beginnen

geerbt; //This Anrufe TSecondComponent.Start

FState: = StStarted;

if Assigned(OnStart) dann OnStart(Self);

if Assigned(OnStateChange) dann OnStateChange (Self, Staat);

end;



Verfahren TThirdComponent.Stop;

beginnen

geerbt; //This Anrufe TSecondComponent.Stop

FState: = StStopped;

if Assigned(OnStop) dann OnStop(Self);

if Assigned(OnStateChange) dann OnStateChange (Self, Staat);

end;



Konstruktor TThirdComponent.Create(AOwner: TComponent);

beginnen

geerbt;

Ist //This waren Sie initialisieren Eigenschaften erstellen und

//and Objekten, die von der Komponente intern verwendet werden kann

FState: = StStopped;

end;



Destruktor TThirdComponent.Destroy;

beginnen

//This ist, wo Sie zerstören würde

alle erstellten Objekte


erbte;

end;





Ihr Paket kompilieren (vergessen Sie nicht, Ihr Paket zu speichern, wann immer Sie eine neue Komponente hinzufügen). Nach Ablegen Ihrer neue Komponente auf dem Formular werden Sie feststellen, dass drei Ereignisse. OnStartund OnStop, OnStateChange. Schaut man sich Demo3 sehen Sie, wie ich diese Ereignisse verwendet haben.



OnStart legt die Beschriftung auf 'Gestartet'

OnStop zeigt die verstrichene Zeit

OnStateChange aktiviert / deaktiviert den entsprechenden Start / Stopp-Taste













Verfahren TForm1.ThirdComponent1Start(Sender: TObject);

beginnen

Caption: = 'Start';

end;



Verfahren TForm1.ThirdComponent1Stop(Sender: TObject);

beginnen

Bildunterschrift: = ThirdComponent1.ElapsedTime;

end;



Verfahren TForm1.ThirdComponent1StateChange (Sender: TObject; Zustand: TState);

beginnen

btnStart.Enabled: = ThirdComponent1.State = StStopped;

btnStop.Enabled: = ThirdComponent1.State = StStarted;

end;





Standards in der Komponente schreiben

Schließlich umfassen wir einigen Bemerkungen über Komponente schreiben, einschließlich einige bestehenden Methoden der Basiskomponenten und Standards für das Schreiben.



Erstellen und zerstören von der Komponente:

Objekte über einen Konstruktor erstellt und durch einen Destruktor zerstört. Der Zweck der Überschreiben eines Konstruktors ist dreifach


  1. Alle Objekte erstellen, die es in sich (Sub-Objekte) enthält

  2. Werte der Klasse (Eigenschaften usw.) zu initialisieren

  3. Eine Ausnahme auslösen und beenden die Klasse erstellt wird.



Es ist standard auf den geerbten Konstruktor von innerhalb Ihrer eigenen Konstruktor aufrufen, sodass die Elternklasse seiner Initialisations durchführen kann, obwohl es nicht notwendig, dies zu tun, um die Komponente zu erstellen ist. (Die Komponente wird erstellt, sobald Ihr Konstruktor beendet ist, es nicht erstellt wird, indem Sie den geerbten Konstruktor aufrufen)



Überschreiben eines Destruktors dient einfach um Ressourcen freizugeben, die während der Lebensdauer der Komponente zugeordnet wurden. Rufen Sie geerbte erst, nachdem Sie diese Ressourcen befreit haben.



Standardkomponente Teile:

Farbe:

Sie können diese Methode, um eigene benutzerdefinierte Zeichnung Ihrer Komponente bieten überschreiben.



Geladen:

Dies wird von Delphi aufgerufen, sobald alle seine Eigenschaften abgeschlossen haben, wird festgelegt, wenn das übergeordnete Formular erstellt wird. Sie können diese Methode überschreiben, um keine Aktionen ausführen, die eine Gruppe von Eigenschaften allen Seins abhängen Satz.



Invalidate: Wenn eine Eigenschaft geändert wird, die die visuelle Darstellung einer Komponente betrifft, sollten Sie diese Methode aufrufen.



ComponentState: Diese Eigenschaft ist sehr nützlich, wenn Sie müssen überprüfen, ob die Komponente zur Gestaltung/Laufzeit derzeit vorhanden ist, oder wenn seine Eigenschaften durch ein streaming Verfahren derzeit gelesen werden.



Die Komponente Kapseln richtig

Es ist standard auf Ihre Komponente als TCustomMyClass zu schreiben und dann die Komponente von dieser Basisklasse ableiten. Die 'benutzerdefinierte' Komponente, die Sie schreiben, haben die meisten (wenn nicht sogar alle) seiner Eigenschaften / Methoden deklariert innerhalb seiner Protected-Abschnitt.



Wenn Sie 'Benutzerdefiniert' Klassenwahl absteigen zu deklarieren Sie einfach Ihre Eigenschaften in den Bereichen Public oder veröffentlicht.













Typ

TCustomMyClass = Klasse(TComponent)

private

FSomeString: String;

geschützt

Verfahren SetSomeString (const Value: String); virtuelle;

Eigenschaft SomeString: string Lesen FSomeString SetSomeString Schreiben ;

end;



TMyClass = Klasse(TCustomMyClass)

veröffentlicht

Eigenschaft SomeString;

end;





Dies ist good practice, wie andere Leute ihre eigenen Komponenten, basierend auf Ihrem ermöglicht ihnen, bestimmte Eigenschaften zu entfernen abgeleitet werden können.



Beachten Sie, wie SetSomeString im geschützten Bereich als virtual deklariert wurde. Dies ist auch gute Umgangsformen, da es abstammen Klassen erlaubt, reagieren auf Änderungen im Eigenschaftswerte durch Überschreiben der Prozedur, die sie unterscheidet. Dies gilt auch für Veranstaltungen, wo man ein OnStateChange-Ereignis sehen, werden Sie oft finden zum Beispiel eine DoStateChange-Methode:













Typ

TCustomMyClass = Klasse(TComponent)

private

FOnStateChange: TStateChangeEvent;

geschützt

Verfahren DoStateChange(State: TState); virtuelle;

veröffentlicht

Eigenschaft OnStateChange: TStateChangeEvent Lesen , FOnStateChange

Schreiben FOnStateChange;

end;



Verfahren TCustomMyClass.DoStateChange(State: TState);

beginnen

if Assigned(OnStateChange) dann

OnStateChange (Self, Staat);

end;





Anstatt die 'Wenn assigned(OnStateChange) dann' code jedes Mal, wenn der Zustand ändert, Sie einfach 'DoStateChange(NewState)' nennen würde. Abgesehen davon, dass kleinere schreiben, können sie auch untergeordnete Klassen, DoStateChange und Trigger erforderlichen Code in Reaktion auf ein Ereignis zu überschreiben.



Zusammenfassung

In diesem ersten Artikel haben wir die Verwendung der Komponente schreiben gesehen. Wir haben auch gesehen, wie unsere Komponenten schreiben und welche Originalklasse auf unsere Komponenten basieren. Wir diskutierten darüber virtuellen / dynamische Methoden und wie man sie benutzt, um 'Komponente Etikette' umzusetzen.



Im zweiten Teil dieses Artikels werden wir lernen, wie Sie benutzerdefinierte Eigenschaften, z. B. binäre Daten, Sammlungen, Mengen und erweiterbare Untereigenschaften zu schreiben.



Nächster Artikel >>





Der Quellcode zu diesem Artikel begleiten kann heruntergeladen werden, indem Sie hier klicken.








Komponente schreiben, Teil 1


Komponente schreiben, Teil 1 : Mehreren tausend Tipps, um Ihr Leben einfacher machen.


Zuerst in einer dreiteiligen Serie Bedeckung Komponente in Delphi schreiben.




Dieser Artikel erschien ursprünglich in Delphi-Entwickler



Copyright Pinnacle Publishing, Inc. Alle Rechte vorbehalten.







Dieser erste Teil veranschaulicht einige der besten Ansätze zu Bauteilen und gleichzeitig bietet Tipps zur Entscheidung über die beste Basisklasse erben, mit Hilfe von virtuellen Declarations, den Prozess der überschreiben, und so weiter.



Die ersten beiden Dinge zu Fragen sind warum Sie vornehmen sollten, verwenden der Komponente schreiben, und wann sollten Sie eine Komponente schreiben müssen. Die erste Frage ist leicht zu beantworten, in der Tat, es hat viele Antworten.


  • Anwenderfreundlichkeit: gekapselte Code bedeutet, dass Sie einfach dieselbe Komponente auf verschiedene Formulare wieder ablegen können ohne eine einzige Zeile Code zu schreiben.

  • Zum Debuggen: Zentralisierte Code erleichtert, eine gesamte Anwendung (oder eine Reihe von Anwendungen) durch das Beheben eines Fehlers in einer einzigen Komponente und neu kompilieren zu reparieren.

  • Geld: Es gibt viele Firmen, die nur allzu gerne für das Privileg, nicht das Rad neu erfinden zu zahlen sind.



Die zweite Frage ist nicht allzu schwer, entweder zu beantworten. Wann immer Sie sich finden dasselbe Schreiben Code mehr als einmal ist es eine gute Idee, eine Komponente zu schreiben, vor allem, wenn der Code anders führt basiert auf den angegebenen Parametern.



Erstellung von Komponenten

Der erste Schritt ist die Basisklasse entscheiden, Sie die Komponente aus abgeleitet werden müssen. Wenn Sie von einer anderen Klasse ableiten, erben Sie Eigenschaft / Methode und das Ereignis, das die Komponente besitzt. Unten ist ein Beispiel wie man welche Klasse entscheiden, Sie Vererben sollten, wenn Sie Ihre eigene Komponente zu schreiben.



(Klicken für Vollansicht)



Click to view full size



Im Falle von Methode A und Methode B vermuten Sie, dass die betreffende Komponente TMemo ist.










MethodeLösung




A




Leiten von TMemo







B




Leiten von TCustomMemo







C




Leiten von TCustomControl







D




TGraphicControl abgeleitet







E




TComponent abgeleitet









Dies kann ein wenig kompliziert erscheinen, lassen Sie mich erklären, den Prozess.



A: Wann müssen Sie einfach zusätzliche Funktionen zu einer vorhandenen Komponente hinzuzufügen Sie von dieser Komponente leiten. Dies wird der neuen Komponente automatisch alle vorhandenen Funktionen und Eigenschaften der vorhandenen Komponente geben.



B: manchmal müssen Sie nicht nur Funktionalität hinzufügen, aber du musst es gleichzeitig zu entfernen. Die Norm üben, wenn eine Komponente geschrieben wird zunächst eine TCustomXXXXX-Komponente zu schreiben wo alle Eigenschaften / Ereignisse und Methoden innerhalb des geschützten Abschnitts der Komponente deklariert werden. Die eigentliche Komponente wird von dieser Basisklasse abgeleitet. Der Trick ist daher nicht ausblenden, Funktionalität, sondern zu 'Benutzerdefiniert' Version der Komponente die Komponente abgeleitet und veröffentlichen nur die Eigenschaften, die Sie behalten möchten (effektiv entfernen unerwünschte Eigenschaften / Ereignisse).



C: alle Komponenten, die den Fokus erhalten soll, braucht ein Fensterhandle. TWinControl ist, wo dieses Handle zuerst eingeführt wird. TCustomControl ist einfach ein TWinControl mit eigener Canvas-Eigenschaft.



D: TGraphicControl verfügt nicht über ein Fensterhandle und daher nicht Fokus erhalten. Komponenten wie TLabel werden von dieser Basisklasse abgeleitet.



E: einige Komponenten werden nicht erstellt, GUI Interaktivität, sondern Ihr Leben einfacher machen. Alles von TComponent abgeleitet wird nur zur Entwurfszeit angezeigt. Eine typische Verwendung dieser Art von Komponente ist für Datenbankverbindungen, Timer etc..



Sobald wir entschieden haben, was unsere Basisklasse sein sollte, ist der nächste Schritt zum Erstellen der Komponente. Im Menü Komponente sehen neue Komponente auswählen und Sie den folgenden Dialog.



New component







Vorgängertyp




Dies ist der Basistyp, dem wir von abstammen müssen







Klassenname




Dies ist der Klassenname unserer neuen Komponente

(mit dem Präfix mit dem Buchstaben 'T')







Farbpalette-Seite




Dies ist die Registerkarte auf der Komponenten-Palette Sie möchten Ihre

Komponente auf, erscheint eine nicht vorhandene Registerkarte Eingabe wird sagen

Delphi, die Sie eine neue Registerkarte erstellt gern.







Schreiben von code

Schon ist es Zeit für uns, etwas zu schreiben. In diesem erste Beispiel müssen nützt überhaupt außer zeigen einige grundlegende Konzepte der Komponente schreiben.



Zunächst wählen Sie die Komponente aus dem Delphi-Hauptmenü und wählen Sie dann neue Komponente. Geben Sie TComponent als 'Vorgängertyp' und TFirstComponent wie der Name der Komponente. Klicken Sie die Schaltfläche 'Installieren'.



An dieser Stelle können Sie die neue Komponente in ein vorhandenes Paket (ein Paket hält eine Sammlung von Komponenten) installieren oder in ein neues Paket installieren. Klicken Sie auf 'in neue Paket', und klicken Sie auf 'Durchsuchen'.



Install component



Einmal haben Sie einen Pfad und einen Dateinamen für das neue Paket ausgewählt und eingegeben eine Beschreibung klicken Sie auf 'OK'. Im nächsten Dialogfeld (gefragt, ob Sie Ihr Paket kompilieren möchten) klicken Sie auf 'Ja'. Nachdem das Paket kompiliert und installiert ist, speichern Sie Ihr Paket und Einheit.



An dieser Stelle haben wir unsere Basisklasse, und auch unsere neue Klassenname angegeben. Wir haben ein neues Paket um unsere Komponente enthalten und wurden mit einem Skelett Klassenstruktur dargestellt von Delphi erstellt.



Schaut man sich den Quellcode zur Verfügung gestellt von Delphi sehen Sie jetzt die Private, Protected, Public und veröffentliche Abschnitte.



Kapselung

Kapselung ist ein einfaches Konzept zu begreifen, aber äußerst wichtige Komponente schreiben. Kapselung erfolgt mit dem Einsatz von vier reservierte Wörter: Private, Protected, Publicund veröffentlicht, Sie werden sehen, das Delphi hat diese Abschnitte automatisch in den Quellcode für die neue Komponente enthalten.











































AbschnittBarrierefreiheit
PrivateMethoden, Eigenschaften und Ereignisse, die in diesem Abschnitt deklariert werden nur

zugänglich für die Einheit die Komponente enthalten ist

innerhalb. Komponenten in derselben Einheit können jeder zugreifen

anderen privaten Elemente.
GeschütztMethoden, Eigenschaften und Ereignisse, die in diesem Abschnitt deklariert werden auch

für jede Klasse zugänglich stammte aus dieser Klasse.
ÖffentlichkeitMethoden, Eigenschaften und Ereignisse erklärt hier von überall her zugänglich.
VeröffentlichtIn diesem Abschnitt können Sie Eigenschaften deklarieren / Ereignisse, die in angezeigt werden die

Objektinspektor. Diese Einstellungen sind Design-Time-Werte

die mit Ihrem Projekt gespeichert werden. (Nicht alle Typen sind

unterstützt, sind Arrays beispielsweise nicht).







Unsere Komponente zu schreiben beginnen

Delphi muss jetzt alles über unsere neue Komponente wissen. Geben Sie den folgenden Code in den Quelltext der Komponente.











Private

{Private Deklarationen}

FStartTime,

FStopTime: DWord;

geschützt

{Protected Deklarationen}

Funktion GetElapsedTime: String; virtuelle;

öffentliche

{Public Deklarationen}

Verfahren Start; virtuelle;

Verfahren Stop; virtuelle;



Eigenschaft StartTime:DWord FStartTime Lesen ;

Eigenschaft StopTime:DWord FStopTime Lesen ;

Eigenschaft ElapsedTime: string Lesen GetElapsedTime;

veröffentlicht

{Published Deklarationen}

end;





Was wir hier getan haben, wird zwei Variablen FStartTime und FStopTime (es ist standard zu sezten Variablennamen mit dem Buchstaben F) hinzugefügt. Es gibt zwei Methoden zum Steuern dieser Variablen Start und Stop. Wir haben eine GetElapsedTime-Funktion hinzugefügt, die FStopTime - FStartTime als Zeichenfolge zurückgibt. Schließlich haben wir drei schreibgeschützte Eigenschaften hinzugefügt.



Drücken Sie UMSCHALT-STRG-C und Delphi wird automatisch vervollständigen den Code für die Klasse (oder klicken Sie die Rechte Maustaste und wählen Sie 'Complete Klasse am Cursor'). Geben Sie den folgenden Code für jede entsprechende Methode.













{TFirstComponent}

Funktion TFirstComponent.GetElapsedTime: String;

beginnen

Ergebnis: = IntToStr (FStopTime - FStartTime);

end;



Verfahren TFirstComponent.Start;

beginnen

FStartTime: = GetTickCount;

end;



Verfahren TFirstComponent.Stop;

beginnen

FStopTime: = GetTickCount;

end;



end.





Testfahrt

Speichern Sie Ihre Einheit, und öffnen Sie Ihr Paket (Datei, Projekt öffnen aus dem Menü, und wählen Sie 'Delphi-Paket' für den Dateityp), sobald Ihr Paket geöffnet ist klicken Sie auf 'Compile'. Sie können Ihr Paket auch öffnen, indem Sie im Hauptmenü und dann installieren Pakete Komponente auswählen. Wählen Sie Ihr Paket und klicken Sie auf die Schaltfläche 'Bearbeiten'.



Sie können jetzt droppen ein TFirstComponent in ein Formular, in der Tat, Sie ablegen können, so viele wie Sie möchten. Fügen Sie zwei Schaltflächen (BtnStart und BtnStop) und fügen Sie folgenden Code in das Formular, und führen Sie dann Ihre Test-app'.













Verfahren TForm1.btnStartClick(Sender: TObject);

beginnen

FirstComponent1.Start;

end;



Verfahren TForm1.btnStopClick(Sender: TObject);

beginnen

FirstComponent1.Stop;

Bildunterschrift: = FirstComponent1.ElapsedTime;

end;





Durch Klicken auf die Schaltfläche 'Start' wird die Startzeit markieren (GetTickCount ist ein WinAPI-Befehl, der gibt die Anzahl der Millisekunden seit dem Start von Windows).



Sie auf die Schaltfläche 'Stop' wird die Stillstandszeit zu markieren und ändern Sie die Beschriftung des Formulars.



Virtuelle, dynamische, Abstract und Override

Sie können virtuelle Erklärung nach Start, Stop und GetElapsedTime aufgefallen. In der folgende Übung werden ihre Verwendung erklären.



Eine neue Komponente erstellen, leiten Sie diese Komponente von TFirstComponent (nennen Sie es TSecondComponent) und installieren Sie es.



Die Virtual und Dynamic-IDs sind eine Komponente des Schriftstellers von Delphi zu sagen, dass die Methode in einer untergeordneten Klasse ersetzt werden kann. Wenn wir eine Methode in einer Klasse zu überschreiben, wird unsere neue Code anstelle der ursprünglichen Code ausgeführt.













geschützt

{Protected Deklarationen}

Funktion GetElapsedTime: String; außer Kraft setzen;





Wir implementieren Sie dann den obigen Code wie folgt.













Funktion TSecondComponent.GetElapsedTime: String;

var

S: String;

beginnen

S: = GetElapsedTime; geerbt

Ergebnis: = S + ' Millisekunden oder ' +

Format ('%.2f Sekunden',

[(StopTime-StartTime) / 1000]);

end;





Unsere neue Code heißt jetzt anstelle des ursprünglichen GetElapsedTime, auch für Verbindungen in der TFirstComponent GetElapsed Zeit implementiert jetzt rufen unsere neuen Code (wenn wir eine Instanz des TSecondComponent, die ist erstellt haben). Der ursprüngliche Code wird mithilfe des Befehls Inherited aufgerufen.



Hinweis: Wenn Sie nicht 'eine Basismethode überschreiben' (da die Basis nicht als virtual deklariert wurde oder weil Sie vergessen haben). TSecondComponent wird den neuen Code aufrufen, Code implementiert in TFirstComponent noch weiterhin den ursprünglichen Code von TFirstComponent aufgerufen.



Der abstrakte Bezeichner erzählt Delphi nicht zu keinen Code für die benannte Methode zu erwarten. Sie sollten eine Instanz eines Objekts nicht mit abstrakten Methoden in ihnen (z. B. TStrings) erstellen. Die Norm üben ist ein Nachkomme einer solchen Klasse erstellen und alle abstrakte Methoden überschreiben (z. B. TStringList tut).



Dynamische Vs virtuell ist einfach eine Frage der Geschwindigkeit Vs Größe. Eine dynamische Methode führt jede Instanz einer Klasse erfordern weniger Speicher, wohingegen eine virtuelle Methode schneller, um den Preis ein wenig zusätzlichen Speicher ausgeführt wird.



Es gibt ein paar einfache Schritte, um Ereignisse an die Komponente hinzufügen. Ereignisse ermöglichen die Komponente, mit der Anwendung zu kommunizieren, um zu benachrichtigen, wenn etwas wichtiges passiert ist. Ein Ereignis ist lediglich ein lesen / Schreib-Eigenschaft, anstatt einen einfachen Variablentyp (z. B. String, Ganzzahl etc.) ist es, eine Prozedur oder Funktion.



Erstellen Sie eine neue Komponente, gehen sie auf TSecondComponent und nennen Sie es TThirdComponent. Speichern der Einheit, installieren Sie die Komponente, und fügen Sie folgenden Code.











Typ

TState = (StStarted, StStopped);

TStateChangeEvent = Verfahren Sender: TObject; Zustand: TState) des Objekts;



TThirdComponent = Klasse(TSecondComponent)

private

{Private Deklarationen}

FState: TState;

FOnStart,

FOnStop: TNotifyEvent;

FOnStateChange: TStateChangeEvent;

geschützt

{Protected Deklarationen}

öffentliche

{Public Deklarationen}

Konstruktor Create(AOwner: TComponent); außer Kraft setzen;

Destruktor Zerstören; außer Kraft setzen;

Verfahren Start; außer Kraft setzen;

Verfahren Stop; außer Kraft setzen;

Eigenschaft Zustand: TState Lesen FState;

veröffentlicht

{Published Deklarationen}

Eigenschaft OnStart: TNotifyEvent Lesen FOnStart FOnStart Schreiben ;

Eigenschaft OnStateChange: TStateChangeEvent Lesen , FOnStateChange

Schreiben FOnStateChange;

Eigenschaft OnStop: TNotifyEvent Lesen FOnStop FOnStop Schreiben ;

end;





Ereignisse werden nur Prozeduren oder Funktionen (selten), die zu einer Klasse gehören (daher die Klausel 'des Objekts' Sie sehen in der TStateChangeEvent). Z. B. TNotifyEvent ist ein standard-Ereignis-Typ implementiert von Delphi, das nur das Objekt übergibt, der das Ereignis ausgelöst, es ist immer gut, 'Selbst' zu senden (Sender: TObject) als ersten Parameter eines beliebigen Ereignisses als das gleiche Ereignis Code für mehrere Komponenten verwendet werden kann.



TNotifyEvent ist definiert als











Typ

TNotifyEvent = Prozedur (Sender: TObject) des Objekts;





Um ein Ereignis von innerhalb einer Komponente aufzurufen ist nur ein Fall von überprüft wird, ob das Ereignis zugewiesen wurde, und wenn ja, nennen es. Ich haben die Start- und Stop-Methoden der TSecondComponent überschrieben, um diese Ereignisse auslösen wie folgt.













Verfahren TThirdComponent.Start;

beginnen

geerbt; //This Anrufe TSecondComponent.Start

FState: = StStarted;

if Assigned(OnStart) dann OnStart(Self);

if Assigned(OnStateChange) dann OnStateChange (Self, Staat);

end;



Verfahren TThirdComponent.Stop;

beginnen

geerbt; //This Anrufe TSecondComponent.Stop

FState: = StStopped;

if Assigned(OnStop) dann OnStop(Self);

if Assigned(OnStateChange) dann OnStateChange (Self, Staat);

end;



Konstruktor TThirdComponent.Create(AOwner: TComponent);

beginnen

geerbt;

Ist //This waren Sie initialisieren Eigenschaften erstellen und

//and Objekten, die von der Komponente intern verwendet werden kann

FState: = StStopped;

end;



Destruktor TThirdComponent.Destroy;

beginnen

//This ist, wo Sie zerstören würde

alle erstellten Objekte


erbte;

end;





Ihr Paket kompilieren (vergessen Sie nicht, Ihr Paket zu speichern, wann immer Sie eine neue Komponente hinzufügen). Nach Ablegen Ihrer neue Komponente auf dem Formular werden Sie feststellen, dass drei Ereignisse. OnStartund OnStop, OnStateChange. Schaut man sich Demo3 sehen Sie, wie ich diese Ereignisse verwendet haben.



OnStart legt die Beschriftung auf 'Gestartet'

OnStop zeigt die verstrichene Zeit

OnStateChange aktiviert / deaktiviert den entsprechenden Start / Stopp-Taste













Verfahren TForm1.ThirdComponent1Start(Sender: TObject);

beginnen

Caption: = 'Start';

end;



Verfahren TForm1.ThirdComponent1Stop(Sender: TObject);

beginnen

Bildunterschrift: = ThirdComponent1.ElapsedTime;

end;



Verfahren TForm1.ThirdComponent1StateChange (Sender: TObject; Zustand: TState);

beginnen

btnStart.Enabled: = ThirdComponent1.State = StStopped;

btnStop.Enabled: = ThirdComponent1.State = StStarted;

end;





Standards in der Komponente schreiben

Schließlich umfassen wir einigen Bemerkungen über Komponente schreiben, einschließlich einige bestehenden Methoden der Basiskomponenten und Standards für das Schreiben.



Erstellen und zerstören von der Komponente:

Objekte über einen Konstruktor erstellt und durch einen Destruktor zerstört. Der Zweck der Überschreiben eines Konstruktors ist dreifach


  1. Alle Objekte erstellen, die es in sich (Sub-Objekte) enthält

  2. Werte der Klasse (Eigenschaften usw.) zu initialisieren

  3. Eine Ausnahme auslösen und beenden die Klasse erstellt wird.



Es ist standard auf den geerbten Konstruktor von innerhalb Ihrer eigenen Konstruktor aufrufen, sodass die Elternklasse seiner Initialisations durchführen kann, obwohl es nicht notwendig, dies zu tun, um die Komponente zu erstellen ist. (Die Komponente wird erstellt, sobald Ihr Konstruktor beendet ist, es nicht erstellt wird, indem Sie den geerbten Konstruktor aufrufen)



Überschreiben eines Destruktors dient einfach um Ressourcen freizugeben, die während der Lebensdauer der Komponente zugeordnet wurden. Rufen Sie geerbte erst, nachdem Sie diese Ressourcen befreit haben.



Standardkomponente Teile:

Farbe:

Sie können diese Methode, um eigene benutzerdefinierte Zeichnung Ihrer Komponente bieten überschreiben.



Geladen:

Dies wird von Delphi aufgerufen, sobald alle seine Eigenschaften abgeschlossen haben, wird festgelegt, wenn das übergeordnete Formular erstellt wird. Sie können diese Methode überschreiben, um keine Aktionen ausführen, die eine Gruppe von Eigenschaften allen Seins abhängen Satz.



Invalidate: Wenn eine Eigenschaft geändert wird, die die visuelle Darstellung einer Komponente betrifft, sollten Sie diese Methode aufrufen.



ComponentState: Diese Eigenschaft ist sehr nützlich, wenn Sie müssen überprüfen, ob die Komponente zur Gestaltung/Laufzeit derzeit vorhanden ist, oder wenn seine Eigenschaften durch ein streaming Verfahren derzeit gelesen werden.



Die Komponente Kapseln richtig

Es ist standard auf Ihre Komponente als TCustomMyClass zu schreiben und dann die Komponente von dieser Basisklasse ableiten. Die 'benutzerdefinierte' Komponente, die Sie schreiben, haben die meisten (wenn nicht sogar alle) seiner Eigenschaften / Methoden deklariert innerhalb seiner Protected-Abschnitt.



Wenn Sie 'Benutzerdefiniert' Klassenwahl absteigen zu deklarieren Sie einfach Ihre Eigenschaften in den Bereichen Public oder veröffentlicht.













Typ

TCustomMyClass = Klasse(TComponent)

private

FSomeString: String;

geschützt

Verfahren SetSomeString (const Value: String); virtuelle;

Eigenschaft SomeString: string Lesen FSomeString SetSomeString Schreiben ;

end;



TMyClass = Klasse(TCustomMyClass)

veröffentlicht

Eigenschaft SomeString;

end;





Dies ist good practice, wie andere Leute ihre eigenen Komponenten, basierend auf Ihrem ermöglicht ihnen, bestimmte Eigenschaften zu entfernen abgeleitet werden können.



Beachten Sie, wie SetSomeString im geschützten Bereich als virtual deklariert wurde. Dies ist auch gute Umgangsformen, da es abstammen Klassen erlaubt, reagieren auf Änderungen im Eigenschaftswerte durch Überschreiben der Prozedur, die sie unterscheidet. Dies gilt auch für Veranstaltungen, wo man ein OnStateChange-Ereignis sehen, werden Sie oft finden zum Beispiel eine DoStateChange-Methode:













Typ

TCustomMyClass = Klasse(TComponent)

private

FOnStateChange: TStateChangeEvent;

geschützt

Verfahren DoStateChange(State: TState); virtuelle;

veröffentlicht

Eigenschaft OnStateChange: TStateChangeEvent Lesen , FOnStateChange

Schreiben FOnStateChange;

end;



Verfahren TCustomMyClass.DoStateChange(State: TState);

beginnen

if Assigned(OnStateChange) dann

OnStateChange (Self, Staat);

end;





Anstatt die 'Wenn assigned(OnStateChange) dann' code jedes Mal, wenn der Zustand ändert, Sie einfach 'DoStateChange(NewState)' nennen würde. Abgesehen davon, dass kleinere schreiben, können sie auch untergeordnete Klassen, DoStateChange und Trigger erforderlichen Code in Reaktion auf ein Ereignis zu überschreiben.



Zusammenfassung

In diesem ersten Artikel haben wir die Verwendung der Komponente schreiben gesehen. Wir haben auch gesehen, wie unsere Komponenten schreiben und welche Originalklasse auf unsere Komponenten basieren. Wir diskutierten darüber virtuellen / dynamische Methoden und wie man sie benutzt, um 'Komponente Etikette' umzusetzen.



Im zweiten Teil dieses Artikels werden wir lernen, wie Sie benutzerdefinierte Eigenschaften, z. B. binäre Daten, Sammlungen, Mengen und erweiterbare Untereigenschaften zu schreiben.



Nächster Artikel >>





Der Quellcode zu diesem Artikel begleiten kann heruntergeladen werden, indem Sie hier klicken.

Komponente schreiben, Teil 1

Komponente schreiben, Teil 1 : Mehreren tausend Tipps, um Ihr Leben einfacher machen.
Komponente schreiben, Teil 1
Wiezutun
Freunden empfehlen
  • gplus
  • pinterest

Kommentar

Einen Kommentar hinterlassen

Wertung