Tutorial Komponentenentwicklung: Unterschied zwischen den Versionen

Aus DGL Wiki
Wechseln zu: Navigation, Suche
(Angefangen mein Komponenten Tutorial ins Wiki zu uebertragen)
 
(Komponenten Tutorial)
Zeile 2: Zeile 2:
  
 
==Einleitung==
 
==Einleitung==
Erst mal Wilkommen bei meinem Komponeten Tutorial. Ich möchte in diesem Tutorial nicht absolutes Basiswissen über die Komponetnen-Programmierung unter Delphi vermitteln, sondern denjenigen, die schon entsprechende Einsteigertutorials gelesen haben (wie etwa das auf Delphi-Treff.de) noch etwas tiefer in die Materie einführen.
+
Erst mal willkommen bei meinem Komponeten-Tutorial. Ich möchte in diesem Tutorial nicht absolutes Basiswissen über die Komponenten-Programmierung unter Delphi vermitteln, sondern denjenigen, die schon entsprechende Einsteigertutorials gelesen haben (wie etwa das auf Delphi-Treff.de) noch etwas tiefer in die Materie einführen.
  
 
== Eigene Visuelle Komponeten ==
 
== Eigene Visuelle Komponeten ==
Wenn man seine Komponente komplett selber zeichnen möchte, so empfiehlt es sich diese von '''TGraphicControl''' oder '''TCustomControl''' abzuleiten. TCustomControl ist im Gegensatzt zu TGrapicControl ein Nachfahr von TWinControl, und erbt von ihm ein (Fenster-) Handle. Dieses Handle ist eine Nummer, welche Komponenten von Windows erhält um sie eindeutig zu bezeichnet. Nur wenn die Komponente ein Handle hat, kann Windows mit ihr etwas anfangen.
+
Wenn man seine Komponente komplett selber zeichnen möchte, so empfiehlt es sich diese von '''TGraphicControl''' oder '''TCustomControl''' abzuleiten. TCustomControl ist im Gegensatz zu TGrapicControl ein Nachfahre von TWinControl, und erbt von ihm ein (Fenster-) Handle. Dieses Handle ist eine Nummer, welche Komponenten von Windows erhalten um sie eindeutig zu bezeichnen. Nur wenn die Komponente ein Handle hat, kann Windows mit ihr etwas anfangen.
  
Möchte man nur statisch etwas anzeigen, wie etwa ein Label, so kann man auch nur TGraphicControl als Vorfahren wählen. Solche Komponenten ohne Handle werden von Windows nicht unterstützt, und sind nur eine Technik von Delphi, um dem Entwickler einfachere Gestalltungsmöglichkeiten zu bieten. Es ist ja schließlich viel einfacher eine Komponente auf der Form zu plazieren, als diese mit Zeichenbefehlen selbst zu zeichnen.
+
Möchte man nur statisch etwas anzeigen, wie etwa ein Label, so kann man auch nur TGraphicControl als Vorfahren wählen. Solche Komponenten ohne Handle werden von Windows nicht unterstützt, und sind nur eine Technik von Delphi, um dem Entwickler einfachere Gestaltungsmöglichkeiten zu bieten. Es ist ja schließlich viel einfacher, eine Komponente auf der Form zu platzieren, als diese mit Zeichenbefehlen selbst zu zeichnen.
  
Um selbst festzulegen wie die Komponente gezeichent wird, kann man bei Nachfahren von TGraphicControl oder TCustomControl ganz einfach die '''procedure Paint''' überschreiben.
+
Um selbst festzulegen, wie die Komponente gezeichnet wird, kann man bei Nachfahren von TGraphicControl oder TCustomControl ganz einfach die '''procedure Paint''' überschreiben.
<pascal>
+
<pascal>TMeineKomponente = class(TGraphicControl)
TMeineKomponente = class(TGraphicControl)
 
 
protected
 
protected
 
   procedure Paint; override;  
 
   procedure Paint; override;  
 
</pascal>
 
</pascal>
  
Gezeichnet wird dann über die Canvas Eigenschaft der Komponente. Dabei sollte man nicht vergessen mit inherited die Paint Procedure des Vorfahren aufzurufen.
+
Gezeichnet wird dann über die Canvas-Eigenschaft der Komponente. Dabei sollte man nicht vergessen mit inherited die Paint Procedure des Vorfahren aufzurufen.
  
<pascal>
+
<pascal>procedure TMeineKomponente.Paint;
procedure TMeineKomponente.Paint;
 
 
begin
 
begin
 
   inherited;//Paint Procedure des Vorfarhen aufrufen.
 
   inherited;//Paint Procedure des Vorfarhen aufrufen.
Zeile 27: Zeile 25:
 
Eine Abfrage der Eigenschaft ComponentState ermöglicht es uns, die Komponente zur Entwickungszeit anders zu zeichnen.
 
Eine Abfrage der Eigenschaft ComponentState ermöglicht es uns, die Komponente zur Entwickungszeit anders zu zeichnen.
  
<pascal>
+
<pascal>procedure TMeineKomponente.Paint;
procedure TMeineKomponente.Paint;
 
 
begin
 
begin
 
   inherited;//Zeichen Procedure des Vorfahren aufrufen.
 
   inherited;//Zeichen Procedure des Vorfahren aufrufen.
Zeile 41: Zeile 38:
 
     canvas.TextOut((width - Canvas.TextWidth(Name)) div 2,(height - Canvas.TextHeight(Name)) div 2,name);
 
     canvas.TextOut((width - Canvas.TextWidth(Name)) div 2,(height - Canvas.TextHeight(Name)) div 2,name);
  
     {Keine weitern Zeichnungen mehr ausführen }
+
     {Keine weitern Zeichnungen mehr ausführen}
 
     exit;//Verlässt die Procedure
 
     exit;//Verlässt die Procedure
 
   end;
 
   end;
Zeile 50: Zeile 47:
 
== Eigenschafts-Editoren ==
 
== Eigenschafts-Editoren ==
  
Als erstes sollten wir der Frage nachgehen was ein Eigenschaftseditor überhaupt ist : Wie schon fast zu erraten ist, handelt es sich hierbei um eine Möglichkeit eine als veröffentlicht (published) deklariete Eigenschaft im Objektinspektor zu bearbeiten. In Delphi sind schon diverse Eigenschaftseditoren vorhanden um die häufigsten Eigenschaftstypen abzudecken. Wenn ihr einer Komponente eine als published deklarierte Eigenschaft vom Typ Integer verpasst, so wird standardgemäß der Editor "TIntegerProperty" genutzt um die Eigenschaft im Objektinspektor darzustellen. Dieser Editor ist ein Eingabefeld für Zahlen.
+
Als erstes sollten wir der Frage nachgehen, was ein Eigenschaftseditor überhaupt ist : Wie schon fast zu erraten, handelt es sich hierbei um eine Möglichkeit, eine als veröffentlicht (published) deklarierte Eigenschaft im Objektinspektor zu bearbeiten. In Delphi sind schon diverse Eigenschaftseditoren vorhanden um die häufigsten Eigenschaftstypen abzudecken. Wenn ihr einer Komponente eine als published deklarierte Eigenschaft vom Typ Integer verpasst, so wird standardgemäß der Editor "TIntegerProperty" genutzt um die Eigenschaft im Objektinspektor darzustellen. Dieser Editor ist ein Eingabefeld für Zahlen.
  
Eigenschaftseditoren können aber nicht nur solche Eingabefelder sein, sondern können auch eine ganze Reiche anderer Bearbeitungsmöglichkeiten bieten. Ein richtig multifunktionaler Eigenschaftseitor ist zum Beispiel "TColorProperty". So kann man entweder eine hexadezimale Zahl oder einen Farbnamen eingeben, die entsprechende Farbe über eine Liste auswählen oder gar per Doppelklick einen Farbdialog öffenen.
+
Eigenschaftseditoren können aber nicht nur solche Eingabefelder sein, sondern können auch eine ganze Reihe anderer Bearbeitungsmöglichkeiten bieten. Ein richtig multifunktionaler Eigenschaftseditor ist zum Beispiel "TColorProperty". So kann man entweder eine hexadezimale Zahl oder einen Farbnamen eingeben, die entsprechende Farbe über eine Liste auswählen oder gar per Doppelklick einen Farbdialog öffenen.
  
Ein solcher Eigenschaftseditor ist programmiertechnisch gesehen nichts anderes als ein Nachfahr der Klasse "TPropertyEditor", welcher in einer Register-Prozedur in Delphi eingebunden wurde. Den Code von einem solchen Eigenschaftseditor sollte man in eine Unit packen, welche nur von Delphi genutzen Code enthält. Für das beiliegende Beispiel TFilePropertyEditor nehmen wir direkt TPropertyEditor als Vorfahren.  
+
Ein solcher Eigenschaftseditor ist programmiertechnisch gesehen nichts anderes als ein Nachfahre der Klasse "TPropertyEditor", welcher in einer Register-Prozedur in Delphi eingebunden wurde. Den Code von einem solchen Eigenschaftseditor sollte man in eine Unit packen, welche nur von Delphi genutzen Code enthält. Für das beiliegende Beispiel TFilePropertyEditor nehmen wir direkt TPropertyEditor als Vorfahren.  
  
<pascal>
+
<pascal>TFileNameProperty = class (TPropertyEditor)
TFileNameProperty = class (TPropertyEditor)
 
 
   {...}
 
   {...}
 
end;
 
end;
Zeile 72: Zeile 68:
 
</pascal>
 
</pascal>
  
Dem Eigenschatseditor werde ich nun zusätzlich, zu dem Standardeingabefeld noch per '''paDialog''' die Möglichkeit geben, auf Doppelklicks, oder einen (nun evtl. erschienen) Buttonklick zu reagieren. '''paMultiSelect''' bewirkt schlussendlich noch dass die Eigenschaft auch noch sichtbar ist, wenn mehre Komponenten ausgewählt sind. Weitere mögliche Parameter sind der Delphi Hilfe zu entnehmen.
+
Dem Eigenschatseditor werde ich nun zusätzlich zu dem Standardeingabefeld noch per '''paDialog''' die Möglichkeit geben, auf Doppelklicks oder einen (nun evtl. erschienen) Buttonklick zu reagieren. '''paMultiSelect''' bewirkt schlussendlich noch, dass die Eigenschaft auch noch sichtbar ist, wenn mehre Komponenten ausgewählt sind. Weitere mögliche Parameter sind der Delphi Hilfe zu entnehmen.
  
<pascal>
+
<pascal>function TFileNameProperty.GetAttributes: TPropertyAttributes;
function TFileNameProperty.GetAttributes: TPropertyAttributes;
 
 
begin
 
begin
 
   Result := [paMultiSelect, paDialog];
 
   Result := [paMultiSelect, paDialog];
Zeile 83: Zeile 78:
 
Um auf das neu geschaffene Editierereignis zu reagieren, überschreiben wir die '''Procedure Edit;'''
 
Um auf das neu geschaffene Editierereignis zu reagieren, überschreiben wir die '''Procedure Edit;'''
  
<pascal>
+
<pascal>procedure TFileNameProperty.Edit;
procedure TFileNameProperty.Edit;
 
 
var
 
var
 
   OpenDialog:TOpenDialog;
 
   OpenDialog:TOpenDialog;

Version vom 28. November 2005, 12:08 Uhr

Komponenten Tutorial

Einleitung

Erst mal willkommen bei meinem Komponeten-Tutorial. Ich möchte in diesem Tutorial nicht absolutes Basiswissen über die Komponenten-Programmierung unter Delphi vermitteln, sondern denjenigen, die schon entsprechende Einsteigertutorials gelesen haben (wie etwa das auf Delphi-Treff.de) noch etwas tiefer in die Materie einführen.

Eigene Visuelle Komponeten

Wenn man seine Komponente komplett selber zeichnen möchte, so empfiehlt es sich diese von TGraphicControl oder TCustomControl abzuleiten. TCustomControl ist im Gegensatz zu TGrapicControl ein Nachfahre von TWinControl, und erbt von ihm ein (Fenster-) Handle. Dieses Handle ist eine Nummer, welche Komponenten von Windows erhalten um sie eindeutig zu bezeichnen. Nur wenn die Komponente ein Handle hat, kann Windows mit ihr etwas anfangen.

Möchte man nur statisch etwas anzeigen, wie etwa ein Label, so kann man auch nur TGraphicControl als Vorfahren wählen. Solche Komponenten ohne Handle werden von Windows nicht unterstützt, und sind nur eine Technik von Delphi, um dem Entwickler einfachere Gestaltungsmöglichkeiten zu bieten. Es ist ja schließlich viel einfacher, eine Komponente auf der Form zu platzieren, als diese mit Zeichenbefehlen selbst zu zeichnen.

Um selbst festzulegen, wie die Komponente gezeichnet wird, kann man bei Nachfahren von TGraphicControl oder TCustomControl ganz einfach die procedure Paint überschreiben.

TMeineKomponente = class(TGraphicControl)
protected
  procedure Paint; override; 

Gezeichnet wird dann über die Canvas-Eigenschaft der Komponente. Dabei sollte man nicht vergessen mit inherited die Paint Procedure des Vorfahren aufzurufen.

procedure TMeineKomponente.Paint;
begin
  inherited;//Paint Procedure des Vorfarhen aufrufen.
  Canvas.//irgendwas

Eine Abfrage der Eigenschaft ComponentState ermöglicht es uns, die Komponente zur Entwickungszeit anders zu zeichnen.

procedure TMeineKomponente.Paint;
begin
  inherited;//Zeichen Procedure des Vorfahren aufrufen.
  if csDesigning in ComponentState then //Wenn sich die Komponente in Entwicklung befindet.
  begin
    {Zeichung eines gestrichelten Rahmens}
    Canvas.Brush.style := bsClear;//Durchsichtiges Rechteck
    Canvas.Pen.style := psDashDot;//Gestrichelte Linen
    Canvas.Rectangle(0,0,width,height);//Rechteck zeichnen

    {Namen der Komponente in die Mitte schreiben}
    canvas.TextOut((width - Canvas.TextWidth(Name)) div 2,(height - Canvas.TextHeight(Name)) div 2,name);

    {Keine weitern Zeichnungen mehr ausführen}
    exit;//Verlässt die Procedure
  end;
  //Normale Zeichen-Anweisungen
end;

Eigenschafts-Editoren

Als erstes sollten wir der Frage nachgehen, was ein Eigenschaftseditor überhaupt ist : Wie schon fast zu erraten, handelt es sich hierbei um eine Möglichkeit, eine als veröffentlicht (published) deklarierte Eigenschaft im Objektinspektor zu bearbeiten. In Delphi sind schon diverse Eigenschaftseditoren vorhanden um die häufigsten Eigenschaftstypen abzudecken. Wenn ihr einer Komponente eine als published deklarierte Eigenschaft vom Typ Integer verpasst, so wird standardgemäß der Editor "TIntegerProperty" genutzt um die Eigenschaft im Objektinspektor darzustellen. Dieser Editor ist ein Eingabefeld für Zahlen.

Eigenschaftseditoren können aber nicht nur solche Eingabefelder sein, sondern können auch eine ganze Reihe anderer Bearbeitungsmöglichkeiten bieten. Ein richtig multifunktionaler Eigenschaftseditor ist zum Beispiel "TColorProperty". So kann man entweder eine hexadezimale Zahl oder einen Farbnamen eingeben, die entsprechende Farbe über eine Liste auswählen oder gar per Doppelklick einen Farbdialog öffenen.

Ein solcher Eigenschaftseditor ist programmiertechnisch gesehen nichts anderes als ein Nachfahre der Klasse "TPropertyEditor", welcher in einer Register-Prozedur in Delphi eingebunden wurde. Den Code von einem solchen Eigenschaftseditor sollte man in eine Unit packen, welche nur von Delphi genutzen Code enthält. Für das beiliegende Beispiel TFilePropertyEditor nehmen wir direkt TPropertyEditor als Vorfahren.

TFileNameProperty = class (TPropertyEditor)
  {...}
end;

In welcher Form der Eigenschaftseditor angezeigt wird, bestimmt der Rückgabewert der Funktion GetAttributes. Um diese zu ändern überschreiben wir die Funktion einfach.

TFileNameProperty = class (TPropertyEditor)
public
  function GetAttributes: TPropertyAttributes; override;
  {...}
end;

Dem Eigenschatseditor werde ich nun zusätzlich zu dem Standardeingabefeld noch per paDialog die Möglichkeit geben, auf Doppelklicks oder einen (nun evtl. erschienen) Buttonklick zu reagieren. paMultiSelect bewirkt schlussendlich noch, dass die Eigenschaft auch noch sichtbar ist, wenn mehre Komponenten ausgewählt sind. Weitere mögliche Parameter sind der Delphi Hilfe zu entnehmen.

function TFileNameProperty.GetAttributes: TPropertyAttributes;
begin
  Result := [paMultiSelect, paDialog];
end;

Um auf das neu geschaffene Editierereignis zu reagieren, überschreiben wir die Procedure Edit;

procedure TFileNameProperty.Edit;
var
  OpenDialog:TOpenDialog;
begin
  OpenDialog := TOpenDialog.create(Application);//Den OpenDialog erstellen
  try
    //Den akuellen Wert übergeben
    OpenDialog.FileName := GetStrValue;
    //Anzeigen und bei Erfolg Wert übernehmen
    if OpenDialog.Execute then SetStrValue(OpenDialog.FileName);
  finally
    OpenDialog.Free; //Den OpenDialog freigeben.
  end;
end;

Mit GetStrValue und SetStrValue kann der Wert einer Stringeigenschaften gelesen und geschrieben werden. Für andere Eigenschaftstypen stehen andere Funktionen zur Verfügung. An dieser Stelle können natürlich auch eigene Formulare eingeblendet werden.