Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Klasse mit TObject Eigenschaft gibt Exception


FrankTheFox - Sa 24.05.08 15:19
Titel: Klasse mit TObject Eigenschaft gibt Exception
Hallo,

mein Code

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Contnrs;

Type

    TControlObjects = class(TObject)
    public
    Parent:TControlObjects;
    Children:array of TControlObjects;
    Data: TObject;
    MyProperties:integer;
    MyActions:integer;
    procedure Add(Obj: TControlObjects);
  end;

  TForm1 = class(TForm)
    procedure FormShow(Sender: TObject);
    procedure FormDestroy(Sender:TObject);

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Form2: TForm;
  MyButton:TButton;
  MyButton2:TButton;
  CtrlObjs: TControlObjects;


implementation

{$R *.dfm}


  procedure TControlObjects.Add(Obj: TControlObjects);
  begin
    SetLength(Children,High(Children)+1);
    Children[High(Children)]:=Obj;
  end;

  procedure TForm1.FormDestroy(Sender:TObject);
  begin
    CtrlObjs.Free;
  end;

  procedure TForm1.FormShow(Sender: TObject);
  begin

    CtrlObjs.Create;
    MyButton.Create(self);

    MyButton.Width:=111;
    MyButton.Height:=22;
    MyButton.Caption:='Knöpple';
    MyButton.Visible:=true;
    self.insertcomponent(MyButton);

    CtrlObjs.Data:=MyButton;
    MyButton2.Create(self);
    self.insertcomponent(MyButton);
    MyButton2:=CtrlObjs.Data as TButton;
    ShowMessage(inttostr(MyButton2.width));

  end;

end.

Ich versuche in der Klasse erzeugt Element TForm, TButton, TLabel, .... zu speichern.
Data soll dann das Object aufnehmen das gerade erzeugt wird z.B.: TForm (oder eben TButton) damit ich dann die Properties und Action auslesen kann.
MyProperties enthalt dann z.B. :=1+4+8+32 und ich weiß welche Properties gesetzt waren weil propWidth=1 propHeight=2 propCation=4 usw.
gleiches gilt dann für MyActions onClick=1 onDblClick=2 usw.

somit kann ich dann Infos über Forms rauschreiben z.B. in eine Datei.

Leider funktionert der obige Code nicht! Fehler: EAccessViolation in der Unit Projekt1 (wo steht Application.initialze....) beim end.


Irgendwas habe ich vergessen zu initialisieren, aber was?


Gruß
Franky


Gausi - Sa 24.05.08 15:29

Hallo,

Erstmal erzeugt man Objekte so

Delphi-Quelltext
1:
CtrlObjs := TControlObjects.Create;                    

und zweitens muss du das Object initialisieren - am Besten im Constructor der Klasse:

Delphi-Quelltext
1:
2:
3:
4:
5:
constructor TControlObjects.Create;
begin
  inherited Create;
  Data := TObject.Create;
end;

Im Destruktor dann wieder freigeben.


FrankTheFox - Sa 24.05.08 15:46

Neues Spiel altes Pech...

Ich habe den constructor eingefügt...

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Contnrs;

Type

    TControlObjects = class(TObject)
    public
    Parent:TControlObjects;
    Children:array of TControlObjects;
    Data: TObject;
    procedure Add(Obj: TControlObjects);
    constructor Create;
  end;

  TForm1 = class(TForm)
    procedure FormShow(Sender: TObject);
    procedure FormDestroy(Sender:TObject);

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Form2: TForm;
  MyButton:TButton;
  MyButton2:TButton;
  CtrlObjs: TControlObjects;


implementation

{$R *.dfm}


  constructor TControlObjects.Create;
  begin
    inherited Create;
    Data := TObject.Create;
  end;

  procedure TControlObjects.Add(Obj: TControlObjects);
  begin
    SetLength(Children,High(Children)+1);
    Children[High(Children)]:=Obj;
  end;

  procedure TForm1.FormDestroy(Sender:TObject);
  begin
    CtrlObjs.Free;
  end;

  procedure TForm1.FormShow(Sender: TObject);
  begin

    CtrlObjs:=TControlObjects.Create;
    MyButton.Create(self);

    MyButton.Width:=111;
    MyButton.Height:=22;
    MyButton.Caption:='Knöpple';
    MyButton.Visible:=true;
    self.insertcomponent(MyButton);

    CtrlObjs.Data:=MyButton;
    MyButton2.Create(self);
    self.insertcomponent(MyButton);
    MyButton2:=CtrlObjs.Data as TButton;
    ShowMessage(inttostr(MyButton2.width));

  end;

end.


Allerdings habe ich die AccessViolation jetzt bei MyButton.Create(self);

Schiet..

Gruß
Franky


Gausi - Sa 24.05.08 15:48

MyButton := TButton.Create(Self) ;-)


FrankTheFox - Sa 24.05.08 16:11

Ok, vielleicht bin ich heute zu blöd, aber jetzt bekomme ich, wenn ich das Form schliesse eine
EIvalidPointer Exception

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Contnrs;

Type

    TControlObjects = class(TObject)
    public
    Parent:TControlObjects;
    Children:array of TControlObjects;
    Data: TObject;
    fProperties:integer;
    fActions:integer;
    procedure Add(Obj: TControlObjects);
    constructor Create;
    destructor Destroy;
  end;

  TForm1 = class(TForm)
    procedure FormShow(Sender: TObject);
    procedure FormDestroy(Sender:TObject);

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Form2: TForm;
  MyButton:TButton;
  MyButton2:TButton;
  CtrlObjs: TControlObjects;


implementation

{$R *.dfm}


  constructor TControlObjects.Create;
  begin
    inherited Create;
    Data := TObject.Create;
  end;

  destructor TControlObjects.Destroy;
  begin
    inherited Destroy;
    Data.free;
  end;

  procedure TControlObjects.Add(Obj: TControlObjects);
  begin
    SetLength(Children,High(Children)+1);
    Children[High(Children)]:=Obj;
  end;

  procedure TForm1.FormDestroy(Sender:TObject);
  begin
    ctrlobjs.Destroy;
    CtrlObjs.Free;
  end;

  procedure TForm1.FormShow(Sender: TObject);
  begin

    CtrlObjs:=TControlObjects.Create;
    MyButton:=TButton.Create(self);

    MyButton.Width:=111;
    MyButton.Height:=22;
    MyButton.Caption:='Knöpple';
    MyButton.Visible:=true;
    self.insertcomponent(MyButton);

    CtrlObjs.Data:=MyButton;
    MyButton2:=TButton.Create(self);
    //self.insertcomponent(MyButton);
    MyButton2:=CtrlObjs.Data as TButton;
    ShowMessage(inttostr(MyButton2.width));

  end;

end.




Gruß
Franky


Gausi - Sa 24.05.08 16:28

Ich glaubem du solltest dir nochmal die Grundlagen anschauen.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  procedure TForm1.FormDestroy(Sender:TObject); 
  begin 
    //ctrlobjs.Destroy; 
    // Destroy macht man nicht. Nur Free.
    CtrlObjs.Free; 
  end;


und was soll das werden? :gruebel:

Delphi-Quelltext
1:
2:
3:
    CtrlObjs.Data := MyButton; 
    MyButton2 := TButton.Create(self); 
    MyButton2 := CtrlObjs.Data as TButton;
Du erzeugst einen Button, und weist danach diesem Button ein TObject zu. Wenn am Ende die Form versucht, den Button freizugeben, und da nur ein Object findet...ich weiß nicht, ob das gut geht...

Und das self.insertcomponent(MyButton); hab ich auch noch nicht gesehen. Kann sein, dass das was sinnvolles ist, aber iirc fehlt ein MyButton.Parent = Self oder etwas vergleichbares.