Autor Beitrag
FrankTheFox
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 51



BeitragVerfasst: Di 20.05.08 12:24 
Hi,


wenn ich per Code TControls bzw. TcxControls erzeugen will, kann ich das über

...Create(self) oder Create(Mein_spezielles_TForm)

wenn ich aber dann über die Controls, die ich erzeuge zsaätliche Attibute (die sie so nicht bestitzen) wie z.B: idX...

speichern will, wie mache ich das am besten ? Über einen dynamischen Array auf einen Record z.B.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
...
   type TcxControlsRec = Record
      Control: TWinControl;
      idX : String;
      DateCreated: String;
    End;


    arrTcxControlsRec := Array of TcxControlsRec;
...


als verkettte Liste....?


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
...
 type TcxControlsRec = Record
      Control: TWinControl;
      idX : String;
      DateCreated: String;
    End;
pTcxControlsList = ^TcxControlList;
TTcxControlsList = record
   data:TcxControlsRec;
   next:pTcxControlsList;
end;
...

oder mit TObjectList (hier fehlen mir aber Delphiprogrammiererfahrung...wäre also schön ein Beispiel zu bekommen)?

Also der Sinn ist k Controls zu erzeugen und dann Infos über die Controls zu speichern, und diese dann auch über deren eigene Attribute anzusprechen!!!!


Gruß
Franky
FrankTheFox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 51



BeitragVerfasst: Mi 21.05.08 12:13 
Titel: Hab 'mal ein Beispiel....
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
...
Type
    TMyObjects = class(TObjectList)
    public
    idX: integer;
    Author: String;
    Location: String;
  end;
...


Deklaration
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
...
var
  Form1: TForm1;
  MyObjects: TMyObjects;
  MyButton:TButton;

...

dann in z.B. FormShow...
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
...
  MyObjects.Create;
  MyObjects.idX:=1002;
  MyObjects.add( MyButton);
...



erzeugt aber einen Fehler "EAccessViolation" sobald ich mit MyObjects arbeite.

Weiß jemand warum?

Muss ich noch was beachten?

Gruß
Franky
SvenAbeln
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 334
Erhaltene Danke: 3



BeitragVerfasst: Mi 21.05.08 12:46 
Objekte werden so erzeugt:
ausblenden Delphi-Quelltext
1:
  MyObject := TMyObjects.Create;					


Du versuchst eine Funktion von einem noch nicht erzeugten Objekt aufzurufen, daher
bekommst du die "EAccessViolation".
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 21.05.08 12:46 
MyObjects.Create; bringt dir nix, du versuchst die Methode Create eines Objekts aufzurufen, das du noch gar nicht erzeugt hast. Du musst ein Objekt des Typs erzeugen und in deine Variable tun: MyObjects := TMyObjects.Create;
FrankTheFox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 51



BeitragVerfasst: Do 22.05.08 06:47 
Derzeit habe ich das so gemacht

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
...
Type 
  TMyObjects = class (TObjectList)
  public
   idX: integer;
   Location: String;
end;

TForm1 = class(TForm)
...


und dann...
ausblenden Delphi-Quelltext
1:
2:
3:
4:
Var
 Form1: TForm;
 MyObjects: TMyObjects;
...


um dann ...
ausblenden volle Höhe 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:
procedure TForm1.FormShow(Sender: TObject);
Var
  MyButton: TButton;
Begin
  MyButton:=TButton.Create(Self);
  MyButton.Caption:='Knöppi';
  MyButton.Top:=10;
  MyButton.Left:=10;
  MyButton.Width:=100;
  MyButton.Height:=20;
  MyButton.Parent:=self;
  MyButton.OnClick:=Buttonlick;


  Self.InsertComponent(MyButton);
  

  MyButton:=TButton.Create(Self);
  MyButton.Caption:='Knöpple';
  MyButton.Top:=10;
  MyButton.Left:=30;
  MyButton.Width:=100;
  MyButton.Height:=20;
  MyButton.Parent:=self;
  MyButton.OnClick:=Buttonlick;

  Self.InsertComponent(MyButton);
  
  MyObjects:=TMyObjects.Create;
  MyObjects.idX:=1002;
  MyObjects.Location:='D:\....';
  MyObjects.add(MyButton);

end;



und dann die Ereignissmethode
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.ButtonClick(Sender: TObject);
begin
  if Sender is TButton then
  begin
    if  TButton(Sender).Caption = 'Knöppi' Then
    ....
    //irgendwas mit idX
    

    if TButton(Sender.Caption = 'Knöpple' Then
    ....
    //irgendwas mit idX

    TButton(Sender).DoSomething;

  end;

end;


aber wie ordne ich denn nun die idX genau einem Button zu, weil ich glaube (...war vielleicht auch schon spät gestern...),
das ich so nicht genau einem Button eine idX zuordnen kann, oder sehe ich dass falsch?
Ich blick im Augenblick da nicht mehr so durch.

Gruß
Franky
Silas
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 478

Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
BeitragVerfasst: Do 22.05.08 07:10 
Morgen,

jede Komponente hat eine Tag-Eigenschaft, die sich beliebig verwenden lässt. Da sie ein 32-Bit Integer ist, kannst du sie einfach als Pointer zweckentfremden:

ausblenden volle Höhe Ein Beispiel
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:
unit MyUnit;

interface

uses ...

type
  PMyObjAttributes = ^TMyObjAttributes
  TMyObjAttributes = record
    MyAttribute1: Integer;
    MyAttribute2: Double;
    MyAttribute3: String;
  end;

...

implementation

procedure TMyForm.FormCreate(Sender: TObject);
var PAttrStruct: PMyObjAttributes;
begin
  GetMem(PAttrStruct, sizeof(TMyObjAttributes));
  MyButton.Tag := Integer(PAttrStruct);
end;

procedure TMyForm.MyButtonClick(Sender: TObject);
begin
  with PMyObjAttributes(MyButton.Tag)^ do begin
    ShowMessage(MyAttribute3);
    MyLabel.Caption := IntToStr(MyAttribute1);
  end;
end;

procedure TMyForm.OnDestroy(Sender: TObject);
begin
  FreeMem(PMyObjAttributes(MyButton.Tag));
end;

Die Buttons kannst du natürlich auch in ein Array packen und dann in einer Schleife durchlaufen.

Mit Klassen statt Records ist das Ganze noch etwas einfacher, wenn du möchtest, kann ich dir dazu auch ein Beispiel geben. ;)

_________________
Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat ;-)
FrankTheFox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 51



BeitragVerfasst: Do 22.05.08 07:57 
Hi,

das mit der Tag Eigenschaft ist cool.

Ich hatte mir schon sowas überlegt
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
 type
    TFormComponent class(TObject)
     idX: integer;
     location:string;
 end;

 TComponentList = class(TObjectList)
  private
    function GetComponent(index: integer): TFormComponent;     
  public
    poperty Items[Index: integer]:TFormComnponent;
    read GetComponent;
end;


aber ich weiss nicht ob das so schlau ist und zuviel Overhead bedeutet und sich dann etliche Fehlerquellen
einschleichen können. Weil mit dem Tag Prop. müsste das ja einfacher gehen.

Gruß
Franky
Silas
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 478

Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
BeitragVerfasst: Do 22.05.08 08:17 
user profile iconFrankTheFox hat folgendes geschrieben:
Ich hatte mir schon sowas überlegt
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
TComponentList = class(TObjectList)
  private
    function GetComponent(index: integer): TFormComponent;     
  public
    poperty Items[Index: integer]:TFormComnponent;
    read GetComponent;
end;

:shock: Was wird denn das?! Eine ObjectList ist eine Liste aus Objekten. ;) Da musst du so rangehn (Wenn deine Attibutsammlung eine Klasse ist):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
var 
  Attrs: TMyObjectAttributes;
  List: TObjectList;
...
begin
  Attrs := TMyObjectAttributes.Create;
  Attrs.Attribute1 := 42;
  Attrs.Attribute2 := 13.37;
  Attrs.Attribute3 := 'Hello World!';
  List.Add(Attrs);
  ...
  ShowMessage((List[i] as TMyObjectAttributes).Attribute3);
  ...
  for i := 0 to List.Count-1 do List[i].Free;
  List.Free;
end;

Davon würd ich aber eher abraten, weil du damit Objekte trennst, die eigentlich zusammengehören.


Mit einer Klasse würde die Tag-Geschichte folgendermaßen aussehen:

ausblenden volle Höhe Ein Beispiel, diesmal mit Klassen
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:
unit MyUnit;

interface

uses ...

type
  TMyObjAttributes = class
    public
      MyAttribute1: Integer;
      MyAttribute2: Double;
      MyAttribute3: String;
  end;

...

implementation

procedure TMyForm.FormCreate(Sender: TObject);
begin
  MyButton.Tag := Integer(TMyObjAttributes.Create);
end;

procedure TMyForm.MyButtonClick(Sender: TObject);
begin
  with TMyObjAttributes(MyButton.Tag) do begin
    ShowMessage(MyAttribute3);
    MyLabel.Caption := IntToStr(MyAttribute1);
  end;
end;

procedure TMyForm.OnDestroy(Sender: TObject);
begin
  TMyObjAttributes(MyButton.Tag).Free;
end;

Das funktioniert im Endeffekt genauso (nur ist es weniger chaotisch ;) ), weil Klassen auch nur Pointer und damit eigentlich Integer sind. Wenn du wirklich Massenweise (>1000) Objekte verwalten willst, würde ich vielleicht eher die Record-Methode verwenden, weil sie ein Stück performanter ist.

_________________
Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat ;-)
FrankTheFox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 51



BeitragVerfasst: Do 22.05.08 09:21 
Hi,


ich kann die Tag-Eigenschaft nicht benutzen, weil sie anderweitig verwendet werden soll.
Also muß ich das anders machen. Ich hatte auch schon an einen Record gedacht, aus dem ich dann einen Array mache, denn ich dann dynamisch erweitere. Aber nach Möglichkeit soll ich eine ObjectList nutzen. Ich krieg 'nen Vogel!



Gruß
Franky
Silas
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 478

Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
BeitragVerfasst: Do 22.05.08 09:38 
user profile iconFrankTheFox hat folgendes geschrieben:
Ich kann die Tag-Eigenschaft nicht benutzen, weil sie anderweitig verwendet werden soll.
Dann musst du eben auf die Object-List-Möglichkeit zurückgreifen, oder du speicherst den Wert, den die Tag-Eigenschaft eigentlich haben soll, ebenfalls in deinem Record / deiner Klasse.

_________________
Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat ;-)
FrankTheFox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 51



BeitragVerfasst: Do 22.05.08 13:32 
Hi,

ich denke ich gehe ganz anders ran! Da ich die Controls (T....) ja dynamisch erzeugen will (vielleich aus einer XML Datei)
kann ich mir für alle Controls eine Klasse bauen....


also mein Versuch...

speichere Struktur zur Laufzeit...
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
...TDesignTimeObject = class
      Children: array of TDesignTimeObject;
      Parent: TDesignTimeObject;
      Typ: String;
      idX: integer;
  end;
...


dann habe ich ja pro Control unterschiedliche Attribute die ich so dann jeweils einbinden kann

wie z.B.:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
...

 TAttrCxControl = class (TDesignTimeObject)
     private
      { Private-Deklarationen }
     public
      { Public-Deklarationen }
    property Height: integer;
    property Width: integer;

  end;

...


ich weiß aber nicht ob das so wirklich helle ist, da ich ja dann für jedes Control eine Klasse definieren muß.
Ich hatte schon gedacht, die Attributlisten dynamisch an die Klasse TDesignTimeObject zu binden, aber mir fallen da nur Interfaces ein... Aber ob ich Interfaces... hua.
Attibutlisten sind dann ...
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
...
  Width :Integer;
  Height:Integer;
  Caption:String;
  Tag:integer;
  Top:Integer;
...


in den Klassen.

Gruß
Franky