![]() |
Komponente entwickeln mit TCollection, TCollectionItem PropertyEditor
Hallo Leute,
ich steige gerade in das Thema Komponenten entwickeln ein. Ist es machbar bzw. sinnvoll eine Komponente zu entwickeln, die per eigens entwickelten PropertyEditor eine Form, ein Frame oder ein Panel annehmen kann? Ich plane so eine Authorisationkomponente zu entwickeln die verschlüsselte Passwörter beispielsweise aus einer Datenbank oder einen FileStream holt, mit dem UserInput abgleicht und die dann entweder gewährt oder eben nicht gewährt. Dazu hab ich mir gedacht das es zwei Komponenten gibt. Eine eben mit den Verschlüsselungs -und Auswärtungs Methoden und eine Komponente die nur eine Form, ein Frame, oder ein Panel darstellt zur Gestaltungsmöglichkeit eines eigenen Abfragedialogs. Diesen Abfragedialog bindet man dann nach der Gestaltung mit der ersten Komponente. Der Abfragedialog sollte natürlich zur Designzeit editierbar sein. So brauche ich an geeigneter Stelle nur diese beiden Komponenten auf die Form ziehen, den Dialog editieren und die Properties der Komponenten einstellen und fertig. Dann muss ich mir bei der nächsten Implementierung keine Gedanken mehr zu Verschlüsselung, Entschlüsselung, Datenbankabfragen etc. machen. Ich habe mir schon Diverse Tuts und HowTo´s angesehen. Aber keins geht so richtig auf dieses spezielle Thema mit einer Formbindnung zur Designzeit ein. Habt ihr da Ideen, links, Beispielsource oder andere Vorstellungen zur Realiserung. Ich hoffe ich hab mir nicht zu viel vorgenommen?! :wink: Gruß [Edit] P.S.: Vielleicht kann MaBuSE ja mal was zu diesem Thema schreiben. Der hat schon bereits schöne Beispiele gepostet (TPerson Component) :thumb: [/Edit] |
AW: Komponente entwickeln mit TCollection, TCollectionItem PropertyEditor
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hatte
![]() Das Video (ist nicht wirklich gut, sollte aber den Weg durchaus zeigen) könnte ich nochmal bei Bedarf neu verlinken. Im Wiki ist das aber auch ganz gut erklärt: ![]() Man unterscheidet zwischen "Komponentenditor" (gestartet durch Doppelklick auf eine Komponente in der IDE) und Propertyeditor (Eintrag im Objektinspektor z.B. mit einem Elips-Button). Zu letzerem wollte ich demnächst nochmal etwas im o.g. Thread schreiben (oder ein Video machen), da ich das gestern gerade umgesetzt habe (siehe Bild). |
AW: Komponente entwickeln mit TCollection, TCollectionItem PropertyEditor
Liste der Anhänge anzeigen (Anzahl: 1)
Irgendwie stehe ich auf dem Schlauch... :?
Ich habe jetzt in den Properties eine Form und kann dort auch die Eigenschaften bearbeiten. Aber wie könnte ich mir diese in den Designer holen? Ist das so überhaupt machbar? Wenn ich mir die Kompo auf eine Form ziehe und nicht vor dem schließen des Projekts runter nehme, dann bekomme ich auch eine invalid Pointer Exception!? @stahli: Wäre gut wenn der Link zu dem Video erneuert würde. Hier einwenig Code und im Anhang das Package (in D7 erstellt)
Code:
package MyFormCompo; {$R *.res} {$ALIGN 8} {$ASSERTIONS ON} {$BOOLEVAL OFF} {$DEBUGINFO ON} {$EXTENDEDSYNTAX ON} {$IMPORTEDDATA ON} {$IOCHECKS ON} {$LOCALSYMBOLS ON} {$LONGSTRINGS ON} {$OPENSTRINGS ON} {$OPTIMIZATION ON} {$OVERFLOWCHECKS OFF} {$RANGECHECKS OFF} {$REFERENCEINFO ON} {$SAFEDIVIDE OFF} {$STACKFRAMES OFF} {$TYPEDADDRESS OFF} {$VARSTRINGCHECKS ON} {$WRITEABLECONST OFF} {$MINENUMSIZE 1} {$IMAGEBASE $400000} {$DESCRIPTION 'TmyFormComponent mit PropertyEditor'} {$IMPLICITBUILD OFF} requires designide, vcl, rtl, vclactnband, vclx; contains myFormComponent_dsgn in 'myFormComponent_dsgn.pas', myFormComponent in 'myFormComponent.pas'; end.
Code:
unit myFormComponent_dsgn; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, DesignIntf, DesignEditors, myFormComponent; type TmyFormPropEditor = class(TClassProperty) protected FForm: TMyForm; function GetForm: TMyForm; procedure SetForm(const Value: TMyForm); public procedure Edit; override; function GetAttributes: TPropertyAttributes; override; end; procedure Register; implementation procedure Register; begin RegisterPropertyEditor(TypeInfo(TMyForm), TmyFormComponent, 'Form', TmyFormPropEditor); end; { TmyFormPropEditor } procedure TmyFormPropEditor.Edit; begin inherited; if GetForm = nil then begin FForm := TMyForm.create(nil); SetForm(FForm); end; with TmyFormPropEditor.Create(nil, 0) do try finally Free; end; end; function TmyFormPropEditor.GetAttributes: TPropertyAttributes; begin Result := inherited GetAttributes + [paDialog]; end; function TmyFormPropEditor.GetForm: TMyForm; begin if GetOrdValue <> 0 then begin Result := TMyForm(GetOrdValue); end else begin Result := nil; end; end; procedure TmyFormPropEditor.SetForm(const Value: TMyForm); begin SetOrdValue(Longint(Value)); end; end.
Code:
unit myFormComponent; interface uses SysUtils, Classes, Controls, StdCtrls, forms; type TMyForm = class(TForm) public function getDisplayValue: string; end; TMdMyItem = class (TCollectionItem) private FCode: Integer; FForm: TCustomForm; procedure SetForm(const Value: TCustomForm); published property Form: TCustomForm read FForm write SetForm; end; TMdMyCollection = class (TCollection) private FComp: TComponent; FCollString: string; public constructor Create (CollOwner: TComponent); function GetOwner: TPersistent; override; procedure Update(Item: TCollectionItem); override; end; TmyFormComponent = class(TComponent) private FForm: TMyForm; FColl: TMdMyCollection; function GetCollString: string; procedure SetMoreData(const Value: TMdMyCollection); protected public constructor Create(AOwner: TComponent); override; destructor Destroy; override; published property Form: TMyForm read FForm write FForm; property MoreData: TMdMyCollection read FColl write SetMoreData; property CollString: string read GetCollString; end; procedure Register; implementation procedure Register; begin RegisterComponents('Beispiele', [TmyFormComponent]); end; { TMyForm } function TMyForm.getDisplayValue: string; begin result := TMyForm.ClassName; end; { TMdMyCollection } constructor TMdMyCollection.Create (CollOwner: TComponent); begin inherited Create (TMdMyItem); FComp := CollOwner; end; function TMdMyCollection.GetOwner: TPersistent; begin Result := FComp; end; procedure TMdMyCollection.Update(Item: TCollectionItem); var str: string; i: Integer; begin inherited; // update everything in any case... str := ''; for i := 0 to Count - 1 do begin str := str + (Items [i] as TMdMyItem).ClassName; if i < Count - 1 then str := str + '-'; end; FCollString := str; end; { TMdMyItem } procedure TMdMyItem.SetForm(const Value: TCustomForm); begin end; { TmyFormComponent } constructor TmyFormComponent.Create(AOwner: TComponent); begin inherited; FForm := TMyForm.Create(AOwner); FColl := TMdMyCollection.Create(Self); end; destructor TmyFormComponent.Destroy; begin FForm.Free; FForm := nil; FColl.Free; inherited; end; procedure TmyFormComponent.SetMoreData(const Value: TMdMyCollection); begin FColl.Assign(Value); end; function TmyFormComponent.GetCollString: string; begin Result := FColl.FCollString; end; end. |
AW: Komponente entwickeln mit TCollection, TCollectionItem PropertyEditor
Du haust Da noch zu viel durcheinander.
Erst mal erstellst Du ein normales Laufzeitpackage und erstellt darin Deine Komponente, so dass die korrekt funktioniert. Falls Du auch während der Laufzeit ein Formular brauchst, das dem User eine Bearbeitung ermöglicht, sollte das mit in das Package. Damit kannst Du die Komponente wie gewünscht nutzen. Jetzt brauchst Du ein Designtimepackage. Darin kannst Du "Erweiterungen" für die IDE regestrieren, damit die IDE auch mit Deiner Komponente umgehen kann. Das ist etwas komplizierter als ein normales Package. Darin definiert man einen Komponenteneditor bzw. Propertyeditor und dazu passende Formulare, die dann von der IDE geöffnet werden. Ich habe immer noch nicht verstanden, ob Du nun einen Komponenteneditor oder einen Propertyeditor brauchst. Zeig mal Deine eigentliche Komponente und deren Eigenschaften und was Du davon in der IDE bearbeiten willst. Das Video kann ich mal raussuchen oder neu machen, aber sag erst mal genauer, was Du machen willst. |
AW: Komponente entwickeln mit TCollection, TCollectionItem PropertyEditor
Zitat:
Zitat:
Zitat:
- Login mit Benutzer, Passwort und Datenbankabfrage - Benutzer anlegen und das Passwort verschlüsselt in der Datenbank speichern. - Benutzer Passwort ändern - Angemeldet bleiben etc. Das wollte ich jetzt in eine Komponente packen Zitat:
Schön wäre es wenn ich im Object Inspector z.B. auf eine Eigenschaft wie Anmeldedialog [TForm] ... klicke und mir zur Designzeit ein Formular angezeigt wird das ich dann bearbeiten kann. Das Formular muss dann z.B. ein Interface einbinden oder gewisse Textfelder und Buttons enthalten auf die ich dann in der Komponente reagieren kann. Formulargröße, Labels, Groupboxen oder ein Logo sind dann frei wähl oder platzierbar. In der eigentlichen Komponente läuft das ab, was ich in meinem Projekt gemacht habe. Zur Runtime wird dieser Dialog dann zur Authorisation angezeigt. Ist das machbar? Oder sollte ich mir lieber eine Klasse schreiben, die ich jedes mal in ein Projekt einbinde. |
AW: Komponente entwickeln mit TCollection, TCollectionItem PropertyEditor
Also ich komme noch nicht ganz hinterher...
Ich würde folgendes empfehlen: Erstelle Dir eine normale Komponente, die Du für Deine IDE registrierst und somit auf Dein Formular ziehen kannst. In der Komponente kannst Du Eigenschaften veröffentlichen, die Du im Objektinspektor setzen kannst oder auch dynamisch zur Laufzeit. Da brauchst Du noch keinerlei Komponenten- oder Propertyeditor und auch kein Designtimepackage (einfach Komponente für eine Registerseite registrieren). Diese Editoren kannst Du bei Bedarf später in einem anderen Package erzeugen, das dann Dein "Komponentenpackage" benutzt. Diese Editoren würden Dir dann ja "nur" eine komfortablere Einstellung der Komponente zur Designtime ermöglichen. |
AW: Komponente entwickeln mit TCollection, TCollectionItem PropertyEditor
@daniel775 vielleich habe ich etwas missverstanden aber die Anforderung liest sich für mich etwas überspitzt wie:
Eine Komponente die ich auf was auch immer ziehen in der ich alle Forms meiner Anwendung designen kann? |
AW: Komponente entwickeln mit TCollection, TCollectionItem PropertyEditor
:) Warum versteht mich denn keiner?
Vielleicht bin ich zu Detailverliebt. Ok, vergessen wir es. Mir ist heute etwas eingefallen, wie ich es vielleicht einfacher angehen könnte. Jetzt mal rein hypothetisch: - Datei > Neu > Anwendung = Form1 - Form1 + MyComponent - Datei > Neu > Form = Form2 - Form2 + btnOK + btnCancel + txtUser + txtPass - Im OI unter Events von MyComponent ein doppelklick auf onInit Unit MyComponent
Code:
Unit Clientform... type TFormClass = class of TForm; TInitEvent = procedure(Sender: TObject; DlgFormClass: TFormClass) of Object; TMyComponent1 = class private FDlgFormClass: TFormClass; FDialog: TForm; FOnInit: TInitEvent; procedure setAnmeldeDlg(value: TFormClass); function getAnmeldeDlg: TFormClass; public constructor create; destructor destroy; procedure Init(Sender: TObject; DlgFormClass: TFormClass); procedure Test; published property AnmeldeDlg: TFormClass read FDlgFormClass write FDlgFormClass; property OnInit: TInitEvent read FOnInit write FOnInit; end; ... constructor TMyComponent1.create; begin inherited; OnInit := self.Init; end; destructor TMyComponent1.destroy; begin if assigned(FDialog) then FreeAndNil(FDialog); inherited; end; procedure TMyComponent1.setAnmeldeDlg(value: TFormClass); begin FDlgFormClass := value; end; function TMyComponent1.getAnmeldeDlg: TFormClass; begin result := FDlgFormClass; end; procedure TMyComponent1.Init(Sender: TObject; DlgFormClass: TFormClass); begin ... self.setAnmeldeDlg(DlgFormClass); ... end; procedure TMyComponent1.Test; begin freeAndNil(FDialog); try if not Assigned(FDialog) then begin FDialog := FDlgFormClass.Create(application); if assigned(FDialog) then begin FDialog.ShowModal; end; end; Except showMessage('error'); end; end;
Code:
Ich übergebe hier an die Komponente eine Klassenreferenz einer Form, damit der Nutzer dieser Komponente Gestaltungsfreiheit für den
procedure TForm1.FormShow(Sender: TObject);
var obj: TMyComponent1; begin obj := nil; if not assigned(obj) then obj := TMyComponent1.create; if assigned(obj) then begin // Aufruf der Objekt Methode Init und übergabe der Parameter Sender und TForm3 als Klassenreferenz an die Komponente. // Die anschliessende Instanzierung von TForm3 geschieht in der Komponente durch die Methode Test. obj.Init(self, Tform3); obj.Test; obj.destroy; end; end; Dialog zur Benutzerauthentifizerung hat. Innerhalb der Komponente kann dann durch gekapselte Methoden auf die Form zugegriffen bzw. angezeigt werden. Das wollte ich eigentlich erreichen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:04 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz