Announcement

Collapse
No announcement yet.

verschachtelte Komponenten

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • verschachtelte Komponenten

    Wie ist es möglich ein Komponente zu erzeugen die verschachtelte Definitionen hat. Wie z. B. Table.Fielddefs Tmainmenu.Menuitem usw.

    Der Versuch es bei TmainMenu abzugucken ist gescheitert.

    Hier mal der Code. Auf Funktionen etc. wurde erstmal absichtlich verzichtet. Ausgeklammerte Codezeilen entsprechen verschiedenen Lösungsansätzen die nicht viel gebracht haben.

    <pre>
    unit RegContainer;

    interface

    uses
    Windows, Messages, SysUtils, Classes, Controls, Registry;

    type
    TValueTyp = (vtString, vtInteger, vtBoolean);

    type
    TRegDefs = class(TComponent)
    private
    FValueTyp : TValueTyp;
    FCheck : Boolean;
    { Private-Deklarationen }
    protected
    { Protected-Deklarationen }
    public
    // constructor Create(AOwner: TComponent); override;
    { Public-Deklarationen }
    published
    property Valuetyp : TValueTyp read FValueTyp write FValueTyp;
    property Check : Boolean read FCheck write FCheck default True;
    { Published-Deklarationen }
    end;

    {TRegColection}

    type
    TRootkey = (HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE,
    HKEY_USERS, HKEY_PERFORMANCE_DATA, HKEY_CURRENT_CONFIG,
    HKEY_DYN_DATA);

    //type
    // TRegDefsList = Array of TRegDefs;

    type
    TRegcolection = class(TComponent)
    private
    FRootkey : TRootkey;
    FRegkeyCount : Integer;
    FRegkey : TRegDefs;//TRegDefsList;

    FRegistry : TRegistry;
    { Private-Deklarationen }
    protected
    { Protected-Deklarationen }
    public
    //constructor Create(AOwner: TComponent); override;
    { Public-Deklarationen }
    published
    property Rootkey : TRootkey read fRootkey write fRootkey;
    property Regdefs : TRegDefs read fRegkey write fRegkey;
    { Published-Deklarationen }
    end;

    procedure Register;

    implementation

    procedure Register;
    begin
    RegisterComponents('Beispiele', [TRegcolection]);
    end;

    { TRegDef }

    {constructor TRegDefs.Create(AOwner: TComponent);
    begin
    inherited Create(AOwner);
    end;}

    { TRegcolection }

    {constructor TRegcolection.Create(AOwner: TComponent);
    begin
    FRegkey := TRegDefs.Create(self)
    end;}
    end.
    </pre>

  • #2
    Ok ich muß zu geben, daß ich gestern wohl auf dem flaschen Weg war um das Problem zu lösen.

    Doch Dank des Kommentars von Herr Schumann der in einer anderen Diskussion auf folgenden Link verwies http://www.raize.com/DelphiByDesign/Delphi55.zip wurdem mir TCollection klar(er).

    Der ObjIns zeigt nun die von mir gewünschte Eigenschaft Regdefs... an. Wenn ich ... anklicke so erscheint auch ein Hinzufügen/löschen Dialog. Betätige ich allerdings den Button Hinzufügen erhalte ich eine Zugriffsverletzung.

    Hier mal der neue Code der Komponente.

    <pre>
    unit RegContainer;

    interface

    uses
    Windows, Messages, SysUtils, Classes, Controls, forms, Graphics;

    {TRegDef}

    type
    TValueTyp = (vtString, vtInteger, vtBoolean);

    type
    TRootkey = (HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE,
    HKEY_USERS, HKEY_PERFORMANCE_DATA, HKEY_CURRENT_CONFIG,
    HKEY_DYN_DATA);

    type
    TRegDef = class(TCollectionItem)
    private
    FValueTyp : TValueTyp;
    FCheck : Boolean;
    FIdent : String;
    FValue : String;
    protected
    procedure SetValueTyp(Value: TValueTyp ); virtual;
    procedure SetCheck( Value: Boolean ); virtual;
    procedure SetIdent( Value: String ); virtual;
    procedure SetValue( Value: String ); virtual;
    public
    constructor Create(Collectioin: TCollection); override;
    procedure Assign(Source: TPersistent); override;
    published
    property Valuetyp : TValueTyp read FValueTyp write SetValueTyp;
    property Check : Boolean read FCheck write SetCheck;
    property Ident : String read FIdent write SetIdent;
    property Value : String read FValue write SetValue;
    end;

    {TRegDefs}

    TRegCollection = class; // Forward Class Declaration

    TRegDefs = class(TCollection)
    private
    FRegCollection : TRegCollection;
    function GetItem(Index: Integer) : TRegDef;
    procedure SetItem(Index: Integer; Value : TRegDef);
    protected
    function GetOwner: TPersistent; override;
    procedure Update(Def : TCollectionItem); override;
    public
    constructor Create(Collection: TRegCollection);
    function Add: TRegdef;
    function AddDef(aValueTyp : TValueTyp; ACheck : Boolean;
    AIdent, AValue : String): TRegdef;
    published
    end;

    {TRegCollection}

    TRegCollection = class(TComponent)
    private
    FRootkey : TRootkey;
    FRegdefs : TRegdefs;
    protected
    procedure SetRootkey(Value: TRootkey); virtual;
    procedure SetRegdefs(Value: TRegdefs); virtual;
    public
    constructor Create (Aowner : TComponent); override;
    destructor Destroy; override;
    procedure AddDef (AValueTyp : TValueTyp; ACheck : Boolean;
    AIdent, AValue : String);
    published
    property Regdefs : TRegDefs read FRegdefs write SetRegDefs;
    property Rootkey : TRootkey read fRootkey write FRootkey;
    end;

    procedure Register;

    implementation

    procedure Register;
    begin
    RegisterComponents('Beispiele', [TRegcollection]);
    end;

    {************************************************* *****************************}
    { TRegdef }
    {************************************************* *****************************}
    constructor TRegDef.Create(Collectioin: TCollection);
    begin
    inherited Create( Collection );
    FValueTyp := vtString;
    FCheck := True;
    FIdent := '';
    FValue := '';
    end;

    procedure TRegDef.Assign( Source: TPersistent );
    begin
    if Source is TRegdef then
    begin
    Valuetyp := TRegdef( Source ).Valuetyp;
    Check := TRegdef( Source ).Check;
    Ident := TRegdef( Source ).Ident;
    Value := TRegdef( Source ).Value;
    end
    else
    inherited Assign( Source );
    end;

    procedure TRegDef.SetValueTyp(Value: TValueTyp );
    begin
    if FValueTyp <> Value then
    begin
    FValueTyp := Value;
    Changed( False ); // Um TRegDefs.Update aufzurufen
    end;
    end

    Comment


    • #3
      Um's zu präzisiern: Die Grundregel lautet, der Besitzer=Allocator eines Objectes ist für dessen Deallocation zuständig. Damit ist auch klar das der Objectinspector und alle PropertyEditoren bei Veränderungen eines Objectes als Eigenschaft, auf einer temporären Kopie arbeiten und dieses dann der tatsächlichen Object-Eigenschaft übergeben. Konsequenz: ALLE Objecte die alls Untereigenschaften von Objecten fungieren müssen mit einer <b>WRITE</b> Methode kopiert werden. Das hat zur Folge das solche Objecte immer von TPersistent oder descends dessen, abgeleit sein müssen, da erst TPersistent die virtuellen Methoden .Assign() und .AssignTo() implementieren. Schaut man sich mal die Delphi PropertyEditors an so stellt man fest das auch dort immer von TPersistent ausgegangen wird, gleiches gilt fürs Streaminsystem, siehe TWriter/TReader.

      Gruß Hage

      Comment

      Working...
      X