Entwickler-Ecke

Sonstiges (Delphi) - Eigenschaften von Buttons


Major1337 - Fr 24.07.09 08:41
Titel: Eigenschaften von Buttons
*DELETE*


Nersgatt - Fr 24.07.09 08:51

Moin,

Du könntest eine kleine Hilfsklasse schaffen, die die Eingeschaften enthält, die Du jetzt in Tag, Hint und FOtherButtons hältst. Für jede Eigenschaft eine Property. Außerdem schaffst Du Dir eine TObjectList, in der Du eine Liste von Instanzen dieser Klassen hälst. Für jeden Button eine Instanz. Und schlussendlich speicherst Du im Tag des Buttons nur noch einen Verweis auf die Hilfsklase mit den Eingenschaften.
Das hat den Vorteil, dass Du nur die Hilfsklasse um Properties erweitern musst, wenn noch weitere Eigenschaften dazu kommen.

Gruß,
Jens


Major1337 - Fr 24.07.09 09:24

@Jens

Danke, dein Vorschlag ist wirklich gut.
Sollen die die Eigenschaften von Width, Height, Top etc. auch in der Hilfsklasse
bei den Proberties gespeichert werden?

Ich habe aber wirklich keine Ahnung wie ich das genau realsieren soll, könntest du mir mal zeigen wie sowas aussieht?
Ich weiß das ich soetwas alleine lösen sollte, aber ich komme mit den Klassen von Delphi nicht so klar. Da man i-wie die Klasse nach dem erstellen noch frei geben muss, wegen der Speicherbelegung und solche Dinge. Ich werde da auf jeden Fall noch lernen, aber jetzt muss ich erstmal diese Aufgabe lösen.

Mfg
DaaN


Nersgatt - Fr 24.07.09 09:34

Naja, das Width, Height und so weiter bezieht sich ja direkt auf den Button, bzw. ändert das Aussehen des Buttons. Daher sollte man sie auch im Button lassen.
Ich habe es so verstanden, dass noch weitere Eigenschaften hast, wofür Du Properties (z.B. das TAG) des Buttons "missbraucht" hast, um sie zu speichern. Das missbrauchen würde man mit der Hilfsklasse vermeiden.

Die generelle Funktion der TObjectList kannst Du hier durcharbeiten: http://www.delphi-treff.de/tutorials/vcl/tobjectlist/


Major1337 - Fr 24.07.09 09:45

hmm.. Kannst du mir das nicht bitte machen? Ich möchte endlich eine andere Aufgabe bekommen, da ich diese total hasse und wenn ich die jetzt noch alleine löse brauche ich dafür mind. 3 Std. bis das perfekt läuft. Du brauchst ja auch nicht alle proberties bei der Klasse zu deklarieren, die restlichen füge ich dann selber dazu.


Nersgatt - Fr 24.07.09 09:47

Was zahlst Du?

Sorry, aber ein bisschen Eigeninitiative musst Du schon zeigen. Das verlinkte Tutorial hast Du in < 1 Stunde durchgearbeitet und Du hast etwas gelernt!


Major1337 - Fr 24.07.09 09:53

bitte, es geht ja nicht nur im die Funktion TObjectList, die Klasse muss ja auch noch erstellt werden.
Wenn du mir das machen würdest, könnte ich das als Beispiel nehmen um zu verstehen wie soetwas "komplexes" aufgebaut ist.


Nersgatt - Fr 24.07.09 09:59

Eine Minimalklasse sieht z.B. so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
type
  THilfsklasse = class(TObject)
    Public
      Eigenschaft1 : integer;
      Eigenschaft2 : Integer;
      Eigenschaft3 : String;
  end;


Instanzen erstellst Du dann so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
var instanz : THilfsklasse;
begin

  instanz := THilfsklasse.Create(); {Instanz erzeugen}
  try

    {Eigenschaften zuweisen}
    instanz.Eigenschaft1 := 4711;
    instanz.Eigenschaft2 := 123;
    instanz.Eigenschaft3 := 'test';
  finally
    {Instanz wieder freigeben}
    instanz.Free;
  end;


end;


Major1337 - Fr 24.07.09 10:05

Danke, aber wo taucht jetzt da die Funktion TObjectList auf?


bummi - Fr 24.07.09 10:07

Leite Doch einfach eine eigene Klasse ab:

hier nur inkomplett zusammengehackt:

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:
unit MYButton;
interface
uses

     Windows, SysUtils, Messages, Classes, Controls, Forms , Buttons;
Type
  TMyButton = class(TButton)
  private
    F_iInfo1:Integer;
    F_sInfo1:String;  
  protected
  Procedure SetiInfo1(Value:Integer)
  Procedure SetsInfo1(Value:String)  
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
  Property iInfo1:Integer Read F_iInfo1 Write SetiInfo1;
  Property sInfo1:Integer Read F_sInfo1 Write SetsInfo1;
  end;

procedure Register;
implementation
Procedure TMyButton.SetiInfo1(Value:Integer);
begin
  F_iInfo1 := Value;
  // >> + was auch immer Du hier tun wills
end;

procedure Register;
begin
  RegisterComponents('WoAuchImmer', [TMyButton]);
end;


end.


Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


Nersgatt - Fr 24.07.09 10:07

Arbeite das Tutorial durch. Sorry, aber ich werde langsam wortkarg.


Major1337 - Fr 24.07.09 11:06

****DELETE********


Nersgatt - Fr 24.07.09 11:18

Das ist die Eigeninitiative, die ich sehen wollte! :zustimm: Dann werde ich auch wieder Gesprächiger.
Es gibt in Delphi 2 (3) Möglichkeiten, Properties zu erstellen.

In der ersten Möglichkeit wird in der Property-Deklaration direkt auf die Variablen verwiesen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  THilfklasse = class(TObject)
    Private
      {Wir deklarieren uns private Variablen, die die Daten halten}
      F_Eigenschaft1 : Integer;
      F_Eigenschaft2 : Integer;
      F_Eigenschaft3 : Integer;
    Public
      {Jetzt die Eigentlichen Properties}
      Property Eigenschaft1 : integer Read F_Eigenschaft1; {Diese Propertyp ist read only}
      Property Eigenschaft2 : integer Read F_Eigenschaft2 Write F_Eigenschaft2; {Diese Property ist read und write}
      Property Eigenschaft3 : integer Write F_Eigenschaft2; {Diese Property ist write only}
  end;


Bei der 2. Möglichkeit setzt Du die Werte mit Prozeduren:

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:
 THilfklasse = class(TObject)
    Private
      {Wir deklarieren uns private Variablen, die die Daten halten}
      F_Eigenschaft1 : Integer;
      F_Eigenschaft2 : Integer;
      F_Eigenschaft3 : Integer;
    function get_Eigenschaft1: integer;
    function get_Eigenschaft2: integer;
    procedure set_Eigenschaft2(const Value: integer);
    procedure set_Eigenschaft3(const Value: integer);
    Public
      {Jetzt die Eigentlichen Properties}
      Property Eigenschaft1 : integer Read get_Eigenschaft1; {Diese Propertyp ist read only}
      Property Eigenschaft2 : integer Read get_Eigenschaft2 Write set_Eigenschaft2; {Diese Property ist read und write}
      Property Eigenschaft3 : integer Write set_Eigenschaft3; {Diese Property ist write only}
  end;
implementation

{ THilfklasse }

function THilfklasse.get_Eigenschaft1: integer;
begin
  result := F_Eigenschaft1;
end;

function THilfklasse.get_Eigenschaft2: integer;
begin
  result := F_Eigenschaft2;
end;

procedure THilfklasse.set_Eigenschaft2(const Value: integer);
begin
  F_Eigenschaft2 := Value;
end;

procedure THilfklasse.set_Eigenschaft3(const Value: integer);
begin
  F_Eigenschaft3 := Value;
end;


Du kannst Möglichkeit 1 und 2 mischen, also z.B. im Read direkt auf die Variable verweisen, aber im Write die Prozedur verwenden.

Die 3. Möglichkeit hatte ich oben schon gezeigt, das sind einfach nur Public-Variablen. Diese Möglichkeit würde ich als Quick&Dirty bezeichnen. Für Deinen Zweck würde ich die erste Möglichkeit verwenden.

Jens


Delete - Fr 24.07.09 11:39

Kleine Anregung: statt die Tag-Property des Buttons als Verweis zu verwenden, würde ich eine Klasse anlegen, die die Zusatzinformationen und die Button-Referenz enthält und diese dann in einer TObjectlist verwalten.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
type 
  TMyButton = class
  private
    FAdditionalInfo: integer; //nur als Beispiel
    FButton: TButton;
  public
    property AdditionalInfo: integer read FAdditionalInfo write FAdditionalInfo;
    property Button: TButton read FButton;
  end;


Major1337 - Fr 24.07.09 11:40

***DELETE****


Nersgatt - Fr 24.07.09 11:46

Es ist in Delphi üblich, dass Du in diesem Fall die Variable mit F als Präfix benennst. Also oben:

Delphi-Quelltext
1:
2:
private
    F_CurrentActivityNumber: integer;


Immer, wenn Du einen Button erstellst, erstellst Du auch eine Instanz der Hilfsklasse, weißt die Properties zu und speicherst sie in der TObjectList.
Wobei ich sagen muss, dass ich den Vorschlag von DeddyH super finde. Würde ich einarbeiten.


Major1337 - Fr 24.07.09 11:50

@DeddyH

gute Idee. Die werde ich auf jeden Fall berücksichtigen.


@Jens

Danke für deine hilfreichen Tips, ich gehe nun erstmal in die Kantine essen und versuche danach danach die Instanzen zuerstellen. Ich hoffe du und andere bleiben mir noch weiter als Ansprechpartner zur Verfügung.


Major1337 - Fr 24.07.09 12:54

wenn ich aber den Präfix F davor setze, dann bekomme ich bei Read lauter Fehlermeldungen das get_"..." nicht deklariert ist. ;(


Delete - Fr 24.07.09 13:02

Du musst das F auch überall da davor setzen, wo die Variable gemeint ist.

Delphi-Quelltext
1:
2:
3:
4:
private
  FMyVar: integer;
public
  property MyVar: integer read FMyVar write FMyVar;


Nersgatt - Fr 24.07.09 13:03

Du musst es dann an den Stellen auch ändern, damit die Property direkt auf die Variable zugreift.


Major1337 - Fr 24.07.09 13:08

XXXXXXXXXXXX


Nersgatt - Fr 24.07.09 13:11


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:
type nameless = class(TObject)

    private

    F_CurrentActivityNumber: integer;
    F_NameOfButton: string;
    F_NextActivityNumber: integer;
    F_Telegramtyp :integer;

    {F_get_CurrentActivityNumber: integer;
    F_get_NameOfButton: string;
    F_get_NextActivityNumber: integer;
    F_get_Telegramtyp :integer;}



    {procedure set_CurrentActivityNumber(const Value: integer);
    procedure set_NameOfButton (const Value: integer);
    procedure set_ActivityNumber (const Value: integer);
    procedure set_Telegramtyp (const Value: integer);}


    Public

    {property CurrentActivityNumber : Integer Read F_get_CurrentActivityNumber Write set_CurrentActivityNumber;
    property NameOfButton : String Read F_get_NameOfButton Write set_NameOfButton;
    property TextActivityNumber : Integer Read F_get_NextActivityNumber Write set_ActivityNumber;
    property Telegramtyp : Integer Read F_get_Telegramtyp Write set_Telegramtyp;}


    property CurrentActivityNumber : Integer Read F_CurrentActivityNumber Write F_CurrentActivityNumber;
    property NameOfButton : String Read F_NameOfButton Write F_NameOfButton;
    property TextActivityNumber : Integer Read F_NextActivityNumber Write F_NextActivityNumber;
    property Telegramtyp : Integer Read F_Telegramtyp Write F_Telegramtyp;

  end;


Major1337 - Fr 24.07.09 13:15

XXXXXX


Delete - Fr 24.07.09 13:17

Du kannst natürlich auch Getter und Setter verwenden, aber das ist nur dann notwendig, wenn Du (im Setter) spezielle Überprüfungen durchführen oder weiteren Code ausführen möchtest.


Major1337 - Fr 24.07.09 13:42


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
type Tnameless = class(TObject)

    private

 F_CurrentActivityNumber: integer;
 F_NameOfButton: string;
 F_NextActivityNumber: integer;
 F_Telegramtyp :integer;

    procedure set_CurrentActivityNumber(const Value: integer);
    procedure set_NameOfButton (const Value: integer);
    procedure set_ActivityNumber (const Value: integer);
    procedure set_Telegramtyp (const Value: integer);

    Public

    property CurrentActivityNumber : Integer Read F_CurrentActivityNumber Write F_CurrentActivityNumber;
    property NameOfButton : String Read F_NameOfButton Write F_NameOfButton;
    property NextActivityNumber : Integer Read F_NextActivityNumber Write F_NextActivityNumber;
    property Telegramtyp : Integer Read F_Telegramtyp Write F_Telegramtyp;
  end;





Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
// Implementierung

begin

  Properties := Tnameless.Create();
  try

    properties.CurrentActivityNumber := tempList[0];
    properties.NameOfButton :=tempList[1] ;
    properties.NextActivityNumber := tempList[2];
    properties.Telegramtyp := tempList[3];

  finally
    properties.Free;
  end;



stimmt das soweit? :)


Nersgatt - Fr 24.07.09 13:51

Funktioniert es denn? :gruebel:
In Deiner Klasse brauchst Du Procedures nicht. Die hatte Dir ja eigentlich schon auskommentiert.


Major1337 - Fr 24.07.09 14:04

da templist eine String verlangt habe ich noch bei 3 Eigenschaften "IntToStr(tempList[?]) eingefügt.


Der einzigste Fehler:

MainForm.pas(479): E2250
Es gibt keine überladene Version von 'IntToStr', die man mit diesen Argumenten aufrufen kann


Liegt das daran das ich die Buttons noch nicht erstellt habe?


Delete - Fr 24.07.09 14:07

Was ist denn templist? Außerdem enthält Deine Klasse nicht die Buttonreferenz, sondern nur den Namen des Buttons, das hätte ich anders gemacht.


Major1337 - Fr 24.07.09 14:15

CCCCCC


Nersgatt - Fr 24.07.09 14:28

Andersrum: StrToInt. Du willst ja einen String in einen Integer wandeln und nicht einen Integer in String.


zuma - Fr 24.07.09 14:28

Du hast Deine Daten

21; Text1 DG11;21;21
22; Text2 DG12;22;21
23; Text3 DG13;23;21
%24; Text4 DG14;24;21
%34; Text 5 DG11;34;45

wie am anfang beschrieben, in eine Stringlist eingelesen,

templist[0] zeigt auf eine Zeile in deiner Liste,
also auf (0 = 1te Zeile)

21; Text1 DG11;21;21

du möchtest aber einen Wert aus der Zeile haben, also musst du die datenzeile 'nur noch' in einzelteile zerlegen, damit du auch die richtigen Werte zuweisen kannst


Major1337 - Fr 24.07.09 14:34

@Zuma

das hatte ich schon gestern gemacht:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
begin
            Readln(FDatafile, daten);
            if copy(daten,1,1) <> '%' then 
 begin
                tempList.Delimiter := ';';  
                tempList.StrictDelimiter := true;   
                tempList.DelimitedText := daten;



Ich muss jetzt nur noch die Buttons erstellen?


Delete - Fr 24.07.09 14:36

Ich hab jetzt doch einmal ein ausführlicheres Beispiel erstellt:

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:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
unit uButtontest;

interface

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

type
  TMyButtonclass = class
  private
    FAdditionaldata: Integer;
    FButton: TButton;
  public
    constructor Create;
    destructor Destroy;override;
    property AdditionalData: integer read FAdditionaldata write FAdditionaldata;
    property Button: TButton read FButton;
  end;

  TfrmButtontest = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    FButtons: TObjectList;
    procedure ShowButtonInfo(Sender: TObject);
  public
    { Public-Deklarationen }
  end;

var
  frmButtontest: TfrmButtontest;

implementation

{$R *.dfm}

const IniName = 'C:\temp\Test.ini';

{ TMyButtonclass }

//Im Konstruktor wird der Button automatisch erzeugt
constructor TMyButtonclass.Create;
begin
  inherited Create;
  FButton := TButton.Create(nil);
end;

//... und im Destruktor automatisch freigegeben
destructor TMyButtonclass.Destroy;
begin
  FButton.Free;
  inherited;
end;

procedure TfrmButtontest.FormCreate(Sender: TObject);
var iIni: TIniFile;
    Sections: TStringList;
    i: Integer;
    Buttonclass: TMyButtonclass;
begin
  //Objectlist anlegen
  FButtons := TObjectList.Create;
  iIni := TIniFile.Create(IniName);
  try
    //Ini auslesen
    Sections := TStringList.Create;
    try
      iIni.ReadSections(Sections);
      //pro Abschnitt ein Button
      for I := 0 to Sections.Count - 1 do
        begin
          Buttonclass := TMyButtonclass.Create;
          //Eigenschaften aus der Ini auslesen und zuweisen
          Buttonclass.Button.Name := Sections[i];
          Buttonclass.Button.Parent := Self;
          Buttonclass.Button.Left := iIni.ReadInteger(Sections[i],'Left',0);
          Buttonclass.Button.Top := iIni.ReadInteger(Sections[i],'Top',0);
          Buttonclass.Button.Width := iIni.ReadInteger(Sections[i],'Width',0);
          Buttonclass.Button.Height := iIni.ReadInteger(Sections[i],'Height',0);
          Buttonclass.Button.Caption := iIni.ReadString(Sections[i],'Caption','');
          //OnClick-Handler dynamisch zuweisen
          Buttonclass.Button.OnClick := ShowButtonInfo;
          Buttonclass.AdditionalData := i;
          //Button in der Objectlist ablegen
          FButtons.Add(Buttonclass);
        end;
    finally
      Sections.Free;
    end;
  finally
    iIni.Free;
  end;
end;

procedure TfrmButtontest.FormDestroy(Sender: TObject);
begin
  //Objectlist freigeben
  FButtons.Free;
end;

procedure TfrmButtontest.ShowButtonInfo(Sender: TObject);
begin
  if Sender is TButton then
    ShowMessage(Format('Ich bin der Button "%s", meine Caption ist "%s"',
                [TButton(Sender).Name,TButton(Sender).Caption]));
end;

end.

Die zugehörige Ini-Datei:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
[Bla]
Caption=Blubb
Left=1
Top=10
Width=75
Height=25

[Blubb]
Caption=Wuppdi
Left=1
Top=40
Width=75
Height=25


Nersgatt - Fr 24.07.09 14:45

Ist bei der TObjectList OwnsObjects standardmäßig True? Sonst noch auf True setzen. Oder den Konstruktor der TMyButtonClass ändern:

Delphi-Quelltext
1:
FButton := TButton.Create(self);                    


Delete - Fr 24.07.09 14:47

Jepp, ist standardmäßig true. Und self dürfte nicht funktionieren, da TMyButtonclass nicht von TComponent abgeleitet ist ;)


Major1337 - Fr 24.07.09 14:52

hmm.. ist das Beispiel von DeddyH schon eine TObjectList? :O


Delete - Fr 24.07.09 14:54

Zitat:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
 TfrmButtontest = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    FButtons: TObjectList;
    procedure ShowButtonInfo(Sender: TObject);
  public
    { Public-Deklarationen }
  end;

;)


Major1337 - Fr 24.07.09 14:56

@DeddyH


arghh.. dummer Fehler ich habe den Scrollbalken gar nicht gesehen, vielen Dank!


Major1337 - Fr 24.07.09 15:23

XXXXXX


Delete - Fr 24.07.09 15:40

Mein Code war ja nur ein Beispiel, um zu zeigen, wie man die Daten zusammenhalten kann. Dafür brauchst Du keine extra Ini-Datei, die hatte ich nur gepostet, um den von mir verwendeten Aufbau zu zeigen.


HelgeLange - Sa 25.07.09 03:06

Die beiden Vorredner, die Dir eine Neue Button-Klasse angeboten haben, haben durchaus recht, dass dies der beste Weg ist, weil Du

a) die Klassen-Instanzen eh dynamisch erzeugst
b) Du keine extra Liste brauchst um die zusätzlichen Eigenschaften der Buttons denselbigen zuzuordnen.

Was Du sicherlich nicht brauchst, sind Set/Get-Funktionen für properties. Wahscheinlich brauchst Du nichtmal properties, wenn Du nicht gerade etwas auf das setzen/lesen hin ausführen willst.

Also das einfachste, was ich mir da vorstellen kann :


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
Type TMyButton = class(TButton)
     public
       ExtraInteger1 : Integer;
       ExtraInteger2 : Integer;
       ExtraString1  : String;
       ExtraString2  : String;
     end;


Nun hast Du schon eine Button-Klasse, die macht alles, wie deine normalen Buttons, hat aber 4 zusätzliche Felder, wo Du was für jeden Button speichern kannst.

Beim Erzeugen brauchst Du nur die Klassen jeweils von TButton auf TMyButton ändern und während des Einlesens kannst Du die extrawerte in diese neuen variablen-Felder speichern.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
FMyButton := TMyButton.Create(Self);
FMyButton.ExtraInteger := 5;
FMyButton.ExtraString := 'TestString';
FMyButton.Height := 25;
FMyButton.Name := 'Button1';
FMyButton.Caption := 'Drück mich ganz lieb'


Major1337 - Sa 25.07.09 18:01

Hey HelgeLange,

brauch man für deinen Vorschlag keine TObjectList, reicht es einfach so?
Ich habe oben die ganze Procedure gepostet, wie es später aussehen sollte.


HelgeLange - Sa 25.07.09 18:30

Naja, Du hattest ja Dein Button array.
Ich selbst bevorzuge Listen, das würde dann so aussehen :


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
var FMyButtons : TList;
    MyButton : TMyButton;
begin
  For i := 1 To ButtonCount Do begin  // ButtonCount ist die Anzahl der Button, die Du aus der Datei holst
    MyButton := TMyButton.Create(Self);
    MyButton.Top := 23;               // hier setzt Du die Variablen, die Du aus der Datei liest
    ...
    MyButton.ExtraInteger1 := 15;     // hier die extra Werte
    ...
    FMyButtons.Add(MyButton);         // und in die Liste einfügen
    MyButton.OnClick := MyOnClick;
  end;
end;


Zum Zugreifen auf einen Button einfach aus der Liste raus drauf zugreifen mit einem TypeCast :


Delphi-Quelltext
1:
TMyButton(FMyButtons.Items[idx]).ExtraInteger1 := 444// idx ist der index in der Liste des jeweiligen Buttons                    


und später beim Programm beenden einfach alle freigeben


Delphi-Quelltext
1:
2:
3:
4:
5:
While FMyButtons.Count > 0 Do begin
  TMyButton(FMyButtons.Items[0]).Free;
  FMyButtons.Delete(0);
end;
FreeAndNil(FMyButtons);


Major1337 - Sa 25.07.09 18:43

XXXXXXXXXXXXXXX


HelgeLange - Sa 25.07.09 20:17

So wie ich das im ersten QuellCode sehe, erzeigst Du den Button in gibst ihn am Ende wieder frei. Ist das so gewollt ?
Normalerweise solltest Du, wenn die Buttons während der ganzen Laufzerit des Programms da sein sollten, beim FormCreate oder FormShow-event die Buttons erzeugen und mit dem Eigenschaften belegen, die Du aus deiner Datei liest.

Das kannst Du mit dem ersten QuellCode meines Beispiels machen.


Im OnClick-Event kannst Du einfach den Sender jeweils Typecasten und entsprechend auswerten anhand der Eigenschaften, was Du im OnClick machen sollst


Delphi-Quelltext
1:
TMyButton(Sender).ExtraInteger1 := 12;                    


und im FormClose- oder FormDestroy-Event kannst Du die Liste freigeben, wie ich es Dir gezeigt hatte.
Weiteren Zugriff brauchast Du wahrscheinlich nichtmal auf die Buttons in der Liste selbst, da sie sich wahrscheinlich nicht während der Laufzeit ändern ausser im OnClick-Event. Also ignorier die Liste soweit, dass Du sie erzeugst, die Buttons drin ablegst und am Ende durchgehst und die Buttons freigibst.


Major1337 - Sa 25.07.09 21:45

XXXX


HelgeLange - Sa 25.07.09 22:41

Einmal im FormShow oder FormCreate Event musst Du die Liste erzeugen


Delphi-Quelltext
1:
2:
3:
begin
  FMyButtons := TList.Create;
end;


und der Code zum leeren der Liste und das Freigeben muss im FormClose oder FormDestroy stehen.

Ich hoffe doch mal, dass Du weisst, wie Du Events belegst ;)


Major1337 - So 26.07.09 09:51

XX


Delete - So 26.07.09 12:20

Darf man fragen, wieso jetzt eine TList statt einer TObjectlist zum Einsatz kommt?


Major1337 - So 26.07.09 12:34

Mir ist es ehrlich gesagt egal ob es ein TList oder TObjectList ist, ihr wisst doch wie es geht, könnt ihr mir es bitte machen.
Ich glaube ich habe euch schon genug Eigeninitiative gezeigt.
Bitte ;)


Delete - So 26.07.09 13:11

Wir haben Dir das Rüstzeug doch bereits gegeben: Du hast nun einen Button mit erweiterten Eigenschaften sowie eine Liste zur Verwaltung von Instanzen dieses Buttons. Mehr brauchst Du doch nicht.


HelgeLange - So 26.07.09 17:25

mit events belegen meinte ich die FormCreate/FormDestroy des Forms, das ButtonEvent hast Du doch schon


Major1337 - So 26.07.09 19:08

ohh man solangsam bekomme ich Kopfweh von den TList oder TObjectList. Ich weiß einfach nicht wie ich das machen soll, das mit der Buttonklasse kann ich noch nachvollziehen. Könnt ihr mir Bitte diese Arbeit, die für euch sehr wahrscheinlich leicht erscheint machen. Ich bin ich euch so dankbar, wenn ihr das für mich macht!!


HelgeLange - Mo 27.07.09 02:01

Zitat:
Da ich aber jetzt ein mehrwöchiges Praktikum absolvieren muss und in unserer Umgebung leider keine Firmen gab

...
Könnt ihr mir Bitte diese Arbeit, die für euch sehr wahrscheinlich leicht erscheint machen. Ich bin ich euch so dankbar, wenn ihr das für mich macht!!


Wir sind ja nicht dazu da, Dir Deine Praktikumsarbeit zu machen, das wäre nicht der Sinn der ganzen Übung.

Wie man die TList macht, hab ich Dir geschrieben, das wirst Du Dir schon selbst in den Code kopieren müssen, wo, habe ich Dir auch gesagt.


Narses - Mi 29.07.09 11:31

Moin!

Thread wegen Vandalismus gesperrt, Rückfragen per VA ans Team.

cu
Narses