Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Zugriff auf Objekt in TObjectList (https://www.delphipraxis.net/202792-zugriff-auf-objekt-tobjectlist.html)

Ykcim 9. Dez 2019 17:11

Zugriff auf Objekt in TObjectList
 
Hallo Zusammen,

Ich möchte in einer Design-Klasse einige Buttons mit Text versehen. Diesen Text hole ich mir vorher aus der DB.
Ich möchte der Procedure eine TObjectList mitgeben, damit dann alle Buttons der Liste mit dem Caption versehen werden.

Durch googln habe ich folgende Procedure geschrieben:
Delphi-Quellcode:
procedure TDesign.Design_LogIn;
var
   BList: TObjectList;
begin
   BList:= TOBjectList.Create;
   Try
      BList.Add(Form_LogIn.btn_login_abbruch);
      BList.Add(Form_LogIn.btn_login_ok);
      Labeling_GlowButtons(BList);
   Finally
      BList:= nil;
   End;
end;
Die Procedure Labeling_GlowButtons sieht so aus:
Delphi-Quellcode:
procedure TDesign.Labeling_GlowButtons(ButtonList: TObjectList);
var
   I: integer;
begin
   for I := 0 to ButtonList.Count -1 do begin
      (ButtonList.Items[I] as TTMSFNCToolBarButton).Text:= Data_Module.xDST_Sprache.FieldByName((ButtonList.Items[I] as TTMSFNCToolBarButton).Name).AsString;
   end;
end;
Jetzt habe ich das Problem, dass ich zwar abfragen kann, ob auch 2 Objekte in der ButtonList sind, aber ich kann nicht darauf zugreifen.
Mach ich bei dem Aufruf
Delphi-Quellcode:
(ButtonList.Items[I] as TTMSFNCToolBarButton).Text
etwas falsch?

Ich bekomme immer die Nachricht:
Zitat:

Cannot read property 'FName' of null | TypeError: Cannot read property 'FName' of null at Object.Design_LogIn (http://localhost:8000/NedCom_Web/Ned....js:119472:116) at Create_frmLogIn
Vielen Dank
Patrick

DieDolly 9. Dez 2019 17:17

AW: Zugriff auf Objekt in TObjectList
 
Zitat:

Mach ich bei dem Aufruf (ButtonList.Items[I] as TTMSFNCToolBarButton).Text etwas falsch?
Ich würde die Liste als erstes generisch deklarieren. Dann brauchst du das alles mit
Delphi-Quellcode:
as
nicht mehr.
Delphi-Quellcode:
BList: TObjectList<TTMSFNCToolBarButton>;
Das sieht dann so aus
Delphi-Quellcode:
for i ...
 ButtonList.Items[I].Text :=


Zitat:

Jetzt habe ich das Problem, dass ich zwar abfragen kann, ob auch 2 Objekte in der ButtonList sind, aber ich kann nicht darauf zugreifen.
Ich frage mich, wie du auf die Liste zugreifen willst, wenn du sie in
Delphi-Quellcode:
TDesign.Design_LogIn;
sofort freigibst nachdem sie erstellt wurde
Delphi-Quellcode:
   BList:= TOBjectList.Create;
   Try
      ...
   Finally
      BList:= nil;
   End;
Außerdem gibt man nicht mit
Delphi-Quellcode:
:= nil
frei.

hoika 9. Dez 2019 17:20

AW: Zugriff auf Objekt in TObjectList
 
Hallo,

ButtonList.Items[I].ClassName
oder
TObject(ButtonList.Items[I]).Name

Was ergibt das?

BList:= nil ersetzen durch BList.Free;
Aber Vorsicht!!! BList.OwnsObjects:= False vorher nicht vergessen.

Ausserdem würde ich mit einer lokalen Variable arbeiten (MyButton oder so),
das macht das Debuggen leichter.

Dennis07 9. Dez 2019 17:49

AW: Zugriff auf Objekt in TObjectList
 
Warum benutzt du TObjectList anstelle der generischen TObjectList<T>?
Gibt es dafür einen besonderen Grund?

DieDolly 9. Dez 2019 17:53

AW: Zugriff auf Objekt in TObjectList
 
Zitat:

BList:= nil ersetzen durch BList.Free;
Zitat:

Warum benutzt du TObjectList anstelle der generischen TObjectList<T>?
Ich würde das ganze Konzept noch einmal überarbeiten.

Man schreibt doch nicht Buttons in eine Liste, nur um sie danach wieder freizugeben. Man arbeitet mit der Liste weiter.

Uwe Raabe 9. Dez 2019 17:58

AW: Zugriff auf Objekt in TObjectList
 
Zitat:

Zitat von Dennis07 (Beitrag 1453088)
Warum benutzt du TObjectList anstelle der generischen TObjectList<T>?

Zitat:

Zitat von hoika (Beitrag 1453082)
Aber Vorsicht!!! BList.OwnsObjects:= False vorher nicht vergessen.

Dann doch lieber gleich
Delphi-Quellcode:
TList<T>
, oder?

Dennis07 9. Dez 2019 18:01

AW: Zugriff auf Objekt in TObjectList
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1453093)
Zitat:

Zitat von Dennis07 (Beitrag 1453088)
Warum benutzt du TObjectList anstelle der generischen TObjectList<T>?

Zitat:

Zitat von hoika (Beitrag 1453082)
Aber Vorsicht!!! BList.OwnsObjects:= False vorher nicht vergessen.

Dann doch lieber gleich
Delphi-Quellcode:
TList<T>
, oder?

Ob du lieber eine
Delphi-Quellcode:
TList<TMyObject>
oder eine
Delphi-Quellcode:
TObjectList<TMyObject>
mit
Delphi-Quellcode:
OwnsObjects = False
verwendest, ist Geschmackssache. Ich mache es lieber immer mit
Delphi-Quellcode:
TObjectList<T>
, sofern ich mit Klasseninstanzen arbeite. Aber Das ist nur meine Ansicht. Des Ergebnis ist ja das selbe.

himitsu 9. Dez 2019 18:24

AW: Zugriff auf Objekt in TObjectList
 
Jupp, die generischen Listen haben den Vorteil, dass hier automatisch der Cast eingebaut ist, also Items direkt den richtigen Typ liefert.

Eine TComponentList hat für TComponents (alles auf der Form) auch einige Vorteile,
denn wird die Komponente freigegeben (.Free), dann löscht sie sich selbstständig aus der Liste heraus. (List.Delete wird beim Free ausgelöst)

Die generische TList<T> im NextGen (Android/iOS) kann dort auch Week-Referenzen verwenden und dann wird dann Items auf nil gesetzt, wenn die Komponente extern freigegeben wird (Free).

Ykcim 9. Dez 2019 21:36

AW: Zugriff auf Objekt in TObjectList
 
Hallo Zusammen,

vielen Dank für die vielen guten Anregungen. Ich habe zuvor noch nie mit einer TObjectList gearbeitet und habe daher davon keine wirkliche Ahnung.

Ich habe gerade versucht Generics.Collections in meine uses einzufügen. Ich habe noch nicht erwähnt, dass ich das Projekt gerade als Web-Application mit TMS-WebCore umsetzen möchte. Da scheinen die Generics.Collections nicht unterstützt zu werden. Der Compiler meckert:
Zitat:

[Fehler] TDesignUnit.pas(5): can't find unit "Generics.Collections"
Der Gedanke war folgender:
Ich schreibe ein Programm, dass auf unterschiedlichen Forms immer wieder diese Art von Buttons haben wird (TTMSFNCToolBarButton) Ich möchte die Captions aus einer DB-Tabelle befüllen. Dazu möchte ich in der Design-klasse, eine eigene Unit, eine Procedure schreiben, der ich bei Bedarf diese Buttons übergebe, das entsprechende Design vornehme (hier gerade nur das Caption, später aber auch noch andere Einstellungen) und dann die Liste wieder freigebe.

Delphi-Quellcode:
procedure TDesign.Design_LogIn;
var
   BList: TObjectList<TTMSFNCToolBarButton>; // Ist das generisch? Das akzeptiert der Compiler nicht...
begin
   BList:= TOBjectList.Create;
   Try
      BList.Add(Form_LogIn.btn_login_abbruch);
      BList.Add(Form_LogIn.btn_login_ok);
      Labeling_GlowButtons(BList);  //Wenn hier die Design-Arbeiten abgeschlossen sind, brauche ich die Liste nicht mehr.
   Finally
      BList:= nil;   // Wenn ich free genommen habe, waren die Buttons zur Laufzeit von dem Form entfernt...
   End;
end;
Was bewirkt
Delphi-Quellcode:
BList.OwnsObjects:= False
? Ziehe die Frage zurück...
Zitat:

OwnsObjects gets or sets whether objects in the list are owned by the list or not. If entries are owned, when an entry object is removed from the list, the entry object is freed. Create initializes this property.
Was mache ich bei der Nutzung einer TObjectList falsch?

Wie löst man denn so eine Aufgabe elleganter?

Vielen Dank für Eure Unterstützung!
Patrick

hoika 9. Dez 2019 21:48

AW: Zugriff auf Objekt in TObjectList
 
Hallo,
ohne das OwnsObjects=False passiert folgendes

BList:= TOBjectList.Create;
Try
BList.Add(Form_LogIn.btn_login_abbruch);
Finally
BList.Free;


Freigabe des Buttons Form_LogIn.btn_login_abbruch -> Form_LogIn.btn_login_abbruch.free
wie das aussieht???
Vielleicht ist der Abbruch-Button nicht mehr sichtbar? -> Ausprobieren ;)
end;

Ykcim 9. Dez 2019 21:55

AW: Zugriff auf Objekt in TObjectList
 
Ja, das habe ich auch bemerkt und gerade in der OH gefunden... :oops:

Aber warum kann ich nicht so auf die Objekte zugreifen?
Delphi-Quellcode:
ShowMessage((ButtonList.Items[0] as TTMSFNCToolBarButton).Name); //Ist nur zum Testen

Ich kann sehen, dass zwei Objekte in der Liste vorhanden sind...
Delphi-Quellcode:
ShowMessage('Anzahl Buttons: '+IntToStr(ButtonList.Count));

Das funktioniert auch nicht, wenn ich das "FREE" rausnehme...
Das verstehe ich nicht!

P.S.: Mit ShowMessages helfe ich mir gerade weiter, weil ich bei einem TMS-WebCore Projekt nicht schrittweise mit dem Debugger arbeiten kann...

DieDolly 9. Dez 2019 22:08

AW: Zugriff auf Objekt in TObjectList
 
Versuch mal
Delphi-Quellcode:
System.
Generics.Collections.

Zitat:

ohne das OwnsObjects=False passiert folgendes
Ich würde, wie erwähnt, das ganze System komplett neu machen. Es ist absoluter Quatsch erst eine Liste zu befüllen, nur um sie danach sofort wieder freizugeben.

Ykcim 9. Dez 2019 22:15

AW: Zugriff auf Objekt in TObjectList
 
Leider funktioniert das auch nicht. Ich bekomme wieder eine Fehlermeldung:
Zitat:

[Fehler] TDesignUnit.pas(5): can't find unit "Generics.Collections"
Zitat:

Ich würde, wie erwähnt, das ganze System komplett neu machen. Es ist absoluter Quatsch erst eine Liste zu befüllen, nur um sie danach sofort wieder freizugeben.
Welche Vorgehensweise würdest Du denn für gut befinden? Ich bin da für Anregungen sehr offen!

DieDolly 9. Dez 2019 22:18

AW: Zugriff auf Objekt in TObjectList
 
Zitat:

Welche Vorgehensweise würdest Du denn für gut befinden? Ich bin da für Anregungen sehr offen!
Was du da in die Liste packst ist ja gut. Aber dann gibt man die Liste doch nicht frei. Man erstellt sie wenn man sie braucht und gibt sie frei, wenn man sie nicht mehr braucht.
Aber wenn man da was reinpackt und später damit weiterarbeiten will, gebe ich die doch nicht sofort frei.

Ykcim 9. Dez 2019 22:24

AW: Zugriff auf Objekt in TObjectList
 
Okay, vielleicht habe ich einen Denkfehler:

Delphi-Quellcode:
procedure TDesign.Design_LogIn;
var
   BList: TObjectList;
begin
   BList:= TOBjectList.Create; //Ich erstelle die Liste
   Try
      BList.Add(Form_LogIn.btn_login_abbruch); //Packe die Buttons rein
      BList.Add(Form_LogIn.btn_login_ok);
      Labeling_GlowButtons(BList); //Hier verarbeite ich jeden einzelnen Button. Wenn diese Procedure fertig ist, sollen alle Buttons so aussehen, wie definiert und ich brauche die Liste nicht mehr, oder?
   Finally
      BList.OwnsObjects:= false;
      BList.Free; //Ich gebe die Liste wieder frei...
   End;
end;
Und das wäre die Procedure Labeling_GlowButtons:
Delphi-Quellcode:
procedure TDesign.Labeling_GlowButtons(ButtonList: TObjectList);
var
   I: integer;
begin
   for I := 0 to ButtonList.Count -1 do begin
      (ButtonList.Items[I] as TTMSFNCToolBarButton).Text:= Data_Module.xDST_Sprache.FieldByName((ButtonList.Items[I] as TTMSFNCToolBarButton).Name).AsString; //Aber hier klappt der Zugriff nicht...
   end;
end;
Ich dachte, damit gebe ich die Liste erst wieder frei, wenn ich sie nicht mehr brauche...

Gruß
Patrick

himitsu 10. Dez 2019 02:18

AW: Zugriff auf Objekt in TObjectList
 
Zitat:

[Fehler] TDesignUnit.pas(5): can't find unit "Generics.Collections"
Fehlen Default-Namespaces in den Projektoptionen?

Die Unit heißt inzwischen System.Generics.Collections und wenn kein "System" als Default-Namespace definiert wurde, dann wird sie nicht gefunden, außer man schreibt den kompletten Namen.

TList = Liste mit beliebigen Zeigern (Pointer, Objekte oder sonstwas, was in einen Pointer/Integer gecastet werden kann)
TObjectList = Liste außschließlich mit Objektzeigeren (TObject und Nachfahren)
TComponentList = die kennt auch den TComponent-Typen und sein Notify-System (sie lässt sich informieren wenn ein Objekt gelöscht wird und entfernt dann auch das Item)
Die generischen TList<TTMSFNCToolBarButton> und TObjectList<TTMSFNCToolBarButton> wie oben, inkl. strikter/impliziter Typisierung.
Delphi-Quellcode:
x := ButtonList.Items[0]; // hier kommt der generische Typ raus (x ist er oder dessen Vorfahre)
ButtonList.Items[0].irgendwas // hier ebenso direkt der generische Typ
ButtonList.Items[0] := x; // hier geht er rein, nur er und dessen Nachfahren
TObjectList weiß was ein Objekt ist, kann daher auch Free/Destroy aufrufen, wenn ein Item gelöscht wird (wenn Owns=True, z.B. beim List.Delete ... nicht beim List.Extract :zwinker:)
Die Generischen haben den Cast eingebaut, also
Delphi-Quellcode:
ButtonList.Items[0].Name
statt dem weichen Cast
Delphi-Quellcode:
(ButtonList.Items[0] as TTMSFNCToolBarButton).Name
oder des Harten
Delphi-Quellcode:
TTMSFNCToolBarButton(ButtonList.Items[0]).Name
.

Und Default-Property (das default in Bezug auf Array-Property) kann man auch weglassen, weil bei Array-Zugriff implizit zum Default weitergeleitet wird.
Delphi-Quellcode:
ButtonList[0].Name
bzw.
Delphi-Quellcode:
(ButtonList[0] as TTMSFNCToolBarButton).Name
oder
Delphi-Quellcode:
TTMSFNCToolBarButton(ButtonList[0]).Name

haentschman 10. Dez 2019 06:10

AW: Zugriff auf Objekt in TObjectList
 
Hallöle...8-)
Zitat:

Okay, vielleicht habe ich einen Denkfehler
...ganz gewaltig. :warn:
Zitat:

Man erstellt sie wenn man sie braucht und gibt sie frei, wenn man sie nicht mehr braucht.
Aber wenn man da was reinpackt und später damit weiterarbeiten will, gebe ich die doch nicht sofort frei.
...die anderen haben das schon mehrfach gesagt. :roll:

Da wir Autovergleiche haben, mache ich das mal mit einem Supermarkt...:stupid:
Delphi-Quellcode:
procedure TDesign.Design_LogIn;
var
   BList: TObjectList;
begin
   BList:= TOBjectList.Create; //Ich erstelle die Liste
   Try
      BList.Add(Form_LogIn.btn_login_abbruch); //Packe die Buttons rein
      BList.Add(Form_LogIn.btn_login_ok);
      Labeling_GlowButtons(BList); //Hier verarbeite ich jeden einzelnen Button. Wenn diese Procedure fertig ist, sollen alle Buttons so aussehen, wie definiert und ich brauche die Liste nicht mehr, oder?
   Finally
      BList.OwnsObjects:= false;
      BList.Free; //Ich gebe die Liste wieder frei...
   End;
end;
Dieser Code bedeutet: Du kaufst dir an der Kasse eine Tüte.(Create) Du wirfst die Produkte direkt in die Tüte.(Add). Dann wirfst du die Tüte drauße direkt in den Papierkorb. (Free)
Frage: Wieviele Produkte hast jetzt im Auto? :roll:


eine der Lösungen:
Delphi-Quellcode:
private
  FBList:= TList<TTMSFNCToolBarButton>;
...
procedure TDesign.Create;
begin
  FBList:= TList<TTMSFNCToolBarButton>.Create;
end;

procedure TDesign.Destroy;
begin
  FBList.Free;
  inherited;
end;

procedure TDesign.Design_LogIn;
begin
  FBList.Add(Form_LogIn.btn_login_abbruch); //Packe die Buttons rein
  FBList.Add(Form_LogIn.btn_login_ok);
  Labeling_GlowButtons(FBList); //Hier verarbeite ich jeden einzelnen Button. Wenn diese Procedure fertig ist, sollen alle Buttons so aussehen, wie definiert und ich brauche die Liste nicht mehr, oder?
end;
Mit dieser Lösung behällst du die Liste und die Buttons, und kannst später durch die Liste iterieren. (Nochmaliges Ändern der Properties)

:wink:

hoika 10. Dez 2019 06:13

AW: Zugriff auf Objekt in TObjectList
 
Hallo,
Du arbeitest leider viel zu wenig mit lokalen Variablen.

(ButtonList.Items[I] as TTMSFNCToolBarButton).Text:= Data_Module.xDST_Sprache.FieldByName((ButtonList.I tems[I] as TTMSFNCToolBarButton).Name).AsString;

Vieleicht schlägt ja auch das hier fehl?

Data_Module.xDST_Sprache.FieldByName

Packe beide Sachen in 2 lokale Variablen!
Und dann mache Dein ShowMessage.

freimatz 10. Dez 2019 07:14

AW: Zugriff auf Objekt in TObjectList
 
Also z.B. so: (ungetested)
Delphi-Quellcode:
procedure TDesign.Labeling_GlowButtons(ButtonList: TObjectList);
var
   I: integer;
   button: TTMSFNCToolBarButton;
   bezeichnung : String;
begin
   for I := 0 to ButtonList.Count -1 do begin
      button := ButtonList.Items[I] as TTMSFNCToolBarButton;
      bezeichnung := Data_Module.xDST_Sprache.FieldByName(button.Name).AsString
      button.Text:= bezeichnung;
   end;
end;
Es geht noch mehr, aber das wäre mal ein erster Schritt, genauer die ersten zwei Schritte.

DieDolly 10. Dez 2019 07:45

AW: Zugriff auf Objekt in TObjectList
 
Delphi-Quellcode:
button := ButtonList.Items[I] as TTMSFNCToolBarButton;
Braucht man diesen Cast, wenn ButtonList generisch ist?

Kann ignoriert werden. Im Prozedurkopf steht TObjectList.

hoika 10. Dez 2019 07:56

AW: Zugriff auf Objekt in TObjectList
 
Hallo,
Freimatz
genau das meinte ich mit "Verwendung von lokalen Variablen".

Ykcim 10. Dez 2019 08:00

AW: Zugriff auf Objekt in TObjectList
 
Guten Morgen Zusammen,

vielen Dank für die Unterstützung. Leider klappt es noch immer nicht...
Ich habe jetzt Folgendes gemacht:

Delphi-Quellcode:
Type
   TDesign=class
      private
         FListe_Button: TObjectList;
Delphi-Quellcode:
constructor TDesign.Create;
begin
   FListe_Button:= TObjectList.Create;
end;
Delphi-Quellcode:
procedure TDesign.Design_LogIn;
begin
   FListe_Button.Add(Form_LogIn.btn_login_abbruch);
   FListe_Button.Add(Form_LogIn.btn_login_ok);
   Labeling_GlowButtons;
end;
Delphi-Quellcode:
procedure TDesign.Labeling_GlowButtons;
var
   I: integer;
   MyButton: TTMSFNCToolBarButton;
   Button_Text: string;
begin
   for I := 0 to FListe_Button.Count -1 do begin
      MyButton:=FListe_Button.Items[I] as TTMSFNCToolBarButton;
      Button_Text:=Data_Module.xDST_Sprache.FieldByName(MyButton.Name).AsString;
      MyButton.Text:=Button_Text;
   end;
end;
Ich bekomme leider nach wie vor die Fehlermeldung:
Zitat:

ERROR
Uncaught TypeError: Cannot read property 'FName' of null | TypeError: Cannot read property 'FName' of null at Object.Labeling_GlowButtons (http://localhost:8000/NedCom_Web/Ned...b.js:119380:52) at Object.Design_LogIn
Aus irgendeinem Grund kann er auf die Objekte in der TObjectList anscheinend nicht zugreifen. Ich habe aber mit
Delphi-Quellcode:
ShowMessage('Anzahl Buttons: '+IntToStr(FListe_Button.Count));
geprüft, dass 2 Objekte in der Liste enhalten sind und haben mit
Delphi-Quellcode:
ShowMessage(Data_Module.xDST_Sprache.FieldByName('btn_login_abbruch').AsString);
geprüft, dass die Daten aus der DB auch vorhanden sind.

Ich weiß nicht, wo es hakt...

Gruß
Patrick

DieDolly 10. Dez 2019 08:57

AW: Zugriff auf Objekt in TObjectList
 
Zitat:

Aus irgendeinem Grund kann er auf die Objekte in der TObjectList anscheinend nicht zugreifen. Ich habe aber mit
Die Fehlermeldung sagt nichts über die TObjectList aus.

Ykcim 10. Dez 2019 09:12

AW: Zugriff auf Objekt in TObjectList
 
Der Fehler tritt aber auf, sobald ich versuche auf ein Objekt zuzugreifen.
Delphi-Quellcode:
MyButton:=FListe_Button.Items[I] as TTMSFNCToolBarButton; //Das funktioniert noch
ShowMessage(MyButton.Name);//Hier knallt es
Ich habe alle Schritte davor getestet!

freimatz 10. Dez 2019 09:13

AW: Zugriff auf Objekt in TObjectList
 
und warum? Kannst Du debuggen?

Ist "FListe_Button.Items[I]" leer oder hat es den falschen Typ oder ist das Objekt schon wieder weg.
Mache davor ein "if Assigned(FListe_Button.Items[I]). Wenn ok lass dir "FListe_Button.Items[I].Classname"anzeigen.


Zitat:

Zitat von hoika (Beitrag 1453125)
Hallo,
Freimatz
genau das meinte ich mit "Verwendung von lokalen Variablen".

Ja. Danke für Deinen Hinweis. Ich dachte dann ein Beispiel wäre für nicht schlecht.

Klaus01 10. Dez 2019 09:13

AW: Zugriff auf Objekt in TObjectList
 
.. hat MyButton denn eine Adresse oder null?

Grüße
Klaus

hoika 10. Dez 2019 09:43

AW: Zugriff auf Objekt in TObjectList
 
Hallo,


Zitat:

FListe_Button.Add(Form_LogIn.btn_login_abbruch);
Mach mal danach

Delphi-Quellcode:
ShowMessage(Form_LogIn.btn_login_abbruch.Name);
und

Delphi-Quellcode:
if FListe_Button.Items[0] is TTMSFNCToolBarButton then
begin
  ShowMessage('OK');
end;

Ykcim 10. Dez 2019 09:51

AW: Zugriff auf Objekt in TObjectList
 
Wie es aussieht, ist das Objekt schon wieder weg... :shock:

Delphi-Quellcode:
for I := 0 to FListe_Button.Count -1 do begin
      if Assigned(FListe_Button.Items[I]) then
         ShowMessage(FListe_Button.Items[I].ClassName)
      else
         ShowMessage('Not assigned');
   end;
Ergebnis lautet: Not assigned...

Aber warum ist das so? Vorher frage ich die Anzahl der Objekte in der Liste ab und bekomme das Ergebnis 2.
Delphi-Quellcode:
ShowMessage('Anzahl Buttons: '+IntToStr(FListe_Button.Count));
Delphi-Quellcode:
      if FListe_Button.Items[I] is TTMSFNCToolBarButton then
         ShowMessage('OK')
      else
         ShowMessage('Not OK');

Auch hier lautet das Ergebnis: Not OK!

Ich gebe die Liste aktuell auch nicht wieder frei...

Vielen Dank
Patrick

DieDolly 10. Dez 2019 09:52

AW: Zugriff auf Objekt in TObjectList
 
Zeig mal deinen abgeänderten Code. Also alles meine ich was wichtig ist.

Jumpy 10. Dez 2019 09:54

AW: Zugriff auf Objekt in TObjectList
 
Für mich sieht das so aus, als ob du in die Liste schon ein Nil-Object reinpackst. Sprich gibt es die Button zu dem Zeitpunkt wo die Prozedur läuft schon?

hoika 10. Dez 2019 10:05

AW: Zugriff auf Objekt in TObjectList
 
Hallo,
Zitat:

Form_LogIn.btn_login_abbruch
entweder das Form ist bereits freigegeben, oder der Button ist gar kein TTMSFNCToolBarButton.
Zeig mal die DFM (falls es das noch gibt, ich kenne mich mit WebCore nicht aus).

Ykcim 10. Dez 2019 10:06

AW: Zugriff auf Objekt in TObjectList
 
Zitat:

Für mich sieht das so aus, als ob du in die Liste schon ein Nil-Object reinpackst. Sprich gibt es die Button zu dem Zeitpunkt wo die Prozedur läuft schon?
Wahrscheinlich liegt hier der Fehler. Ich habe gerade mal getestet, ob ich in der Procedure, die die Buttons in die Liste packt, den Button.Name abgreifen kann. Das Ergebnis war wieder der gleiche Error...

Hier der Aufbau meines Programm-Starts. Ich habe die richtige Reihenfolge mit den nummerierten ShowMessages abgeprüft!

Form_NMain
Delphi-Quellcode:
implementation

uses
   Form_LogInUnit, Form_UebersichtUnit, Form_DispoUnit, TDataUnit, TDesignUnit,
   TLogicUnit;
Delphi-Quellcode:
procedure TForm_NMain.WebFormShow(Sender: TObject);
begin
   FullScreen;
   ShowMessage('1 Main_Show');
   ShowMessage(Sheet_LogIn.Name);
   Data_Module.xConnection_connect(procedure
      begin
         ShowMessage('3 AonConnect');
         Data_Module.Get_Property;
         ShowMessage('4 Get_Property done');
         Data_Module.Get_Sprache(Create_frmLogIn);
      end
      );
end;
Data_Module
Delphi-Quellcode:
implementation

uses TLogicUnit, TDesignUnit;
Delphi-Quellcode:
procedure TData_Module.xConnection_connect (AOnConnect: TConnectCallback);
   procedure OnConnect;
   begin
      if Assigned(AOnConnect) then begin
         ShowMessage('2 Connection Ready');
         AOnConnect();
      end;
   end;
   procedure OnError(Error: TXDataWebConnectionError);
   begin
      ShowMessage('XData server connection failed with error: ' +
      Error.ErrorMessage);
   end;
begin
   if xConnection.Connected then begin
      if Assigned(AOnConnect) then begin
         AOnConnect();
      end;
   end
   else begin
      xConnection.Open(@OnConnect, @OnError);
   end;
end;
Delphi-Quellcode:
procedure TData_Module.Get_Sprache(AOnDataRecieved: TDataRecievedCallback);
   procedure OnResponse(Response: TXDataClientResponse);
   begin
      JSON_DataSet(xDST_Sprache, Response);
      ShowMessage('6 GetSprache DataReceived');
      if Assigned(AOnDataRecieved) then begin
         AOnDataRecieved();
      end;
   end;
begin
   xClient.RawInvoke('IData_xChangeService.Get_Sprache',[], @OnResponse);
   ShowMessage('5 GetSprache');
end;

Form_NMain
Delphi-Quellcode:
procedure TForm_NMain.Create_frmLogIn;
begin
   ShowMessage('7 Create FrameLogin');
   if not Assigned(Form_LogIn) then begin
      Form_LogIn := TForm_LogIn.CreateNew(Form_NMain.Sheet_LogIn.ElementID, nil);
      Form_LogIn.OnLogIn_Run:=Logic.Run_LogIn;
      Design.Design_LogIn;
   end;
   Form_NMain.Frame_Control.TabIndex:=0;
end;
Unit Design
Delphi-Quellcode:
implementation
uses TDataUnit, TLogicUnit, Form_NMainUnit, Form_LogInUnit;
Delphi-Quellcode:
procedure TDesign.Design_LogIn;
begin
   ShowMessage('8 Design LogIn');
   FListe_Button.Add(Form_LogIn.btn_login_abbruch);
   FListe_Button.Add(Form_LogIn.btn_login_ok);
   Labeling_GlowButtons;
end;
Delphi-Quellcode:
procedure TDesign.Labeling_GlowButtons;
var
   I: integer;
   MyButton: TTMSFNCToolBarButton;
   Button_Text: string;
begin
   Showmessage('9 Labeling LogIn');
   ShowMessage('Anzahl Buttons: '+IntToStr(FListe_Button.Count));
   ShowMessage('Anzahl Sprach-Einträge: '+IntToStr(Data_Module.xDST_Sprache.RecordCount));
   ShowMessage(Data_Module.xDST_Sprache.FieldByName('btn_login_abbruch').AsString);
   for I := 0 to FListe_Button.Count -1 do begin
      if Assigned(FListe_Button.Items[I]) then
         ShowMessage(FListe_Button.Items[I].ClassName)
      else
         ShowMessage('Not assigned'); //Das ist das Ergbenis

      if FListe_Button.Items[I] is TTMSFNCToolBarButton then
         ShowMessage('OK')
      else
         ShowMessage('Not OK'); //Das ist das Ergebnis
   end;
end;
Die Reihenfolge 1-9 wird in korrekter Reihenfolge aufgerufen.

Sieht jemand, was ich falsch mache???

Vielen Dank für Eure Unterstützung!
Patrick

hoika 10. Dez 2019 10:11

AW: Zugriff auf Objekt in TObjectList
 
Hallo,
was wird denn hier

ShowMessage(FListe_Button.Items[I].ClassName)

angezeigt?

Ykcim 10. Dez 2019 10:13

AW: Zugriff auf Objekt in TObjectList
 
Er springt nach else und gibt "Not assigned" aus...

Delphi-Quellcode:
for I := 0 to FListe_Button.Count -1 do begin
      ShowMessage(FListe_Button.Items[I].ClassName);
      if Assigned(FListe_Button.Items[I]) then
         ShowMessage(FListe_Button.Items[I].ClassName)
      else
         ShowMessage('Not assigned');
      if FListe_Button.Items[I] is TTMSFNCToolBarButton then
         ShowMessage('OK')
      else
         ShowMessage('Not OK');
   end;

Und wenn ich das assigned nicht abprüfe gibt er folgenden Error aus:
Zitat:

TypeError: Cannot read property '$classname' of null at Object.Labeling_GlowButtons

hoika 10. Dez 2019 10:18

AW: Zugriff auf Objekt in TObjectList
 
Hallo,
ok, oder auch nicht, dann weiter

ShowMessage(Form_LogIn.ClassName)
ShowMessage(Form_LogIn.btn_login_abbruch.ClassName )

und zwar unmittelbar vor dem
Labeling_GlowButtons;


und noch was
Delphi-Quellcode:
procedure TForm_NMain.Create_frmLogIn;
begin
   ShowMessage('7 Create FrameLogin');
   if not Assigned(Form_LogIn) then begin
-->>     ShowMessage('7.1 TForm_LogIn.CreateNew');
      Form_LogIn := TForm_LogIn.CreateNew(Form_NMain.Sheet_LogIn.ElementID, nil);
      Form_LogIn.OnLogIn_Run:=Logic.Run_LogIn;
      Design.Design_LogIn;
   end;

   Form_NMain.Frame_Control.TabIndex:=0;
end;

Ykcim 10. Dez 2019 10:25

AW: Zugriff auf Objekt in TObjectList
 
Also,

Delphi-Quellcode:
ShowMessage('7.1 TForm_LogIn.CreateNew');
hat 7.1 ... korrekt angezeigt.
Delphi-Quellcode:
ShowMessage(Form_LogIn.ClassName);
hat TForm_LogIn ausgegeben

Delphi-Quellcode:
ShowMessage(Form_LogIn.btn_login_abbruch.ClassName );
hat wieder zu einem Error geführt:
Zitat:

ERROR
Uncaught TypeError: Cannot read property '$classname' of null | TypeError: Cannot read property '$classname' of null at Object.Design_LogIn (http://localhost:8000/NedCom_Web/Ned...b.js:119492:89) at Create_frmLogIn
Wenn ich die Autovervollständigung nutze [STRG+LEERTASTE], dann erkennt Delphi den btn_login_abbruch und zeigt auch an, dass es ein TTMSFNCToolBarButton ist. Aber auf den Button kann ich trotzdem nicht zugreifen...

Ykcim 10. Dez 2019 11:07

AW: Zugriff auf Objekt in TObjectList
 
Es funktioniert!

Ich verstehe zwar nicht, warum es gerade nicht funktioniert hat, aber ich habe Folgendes geändert:

Aus der Procedure Create_frmLogIn habe ich das Design.Design_LogIn gelöscht.
Delphi-Quellcode:
procedure TForm_NMain.Create_frmLogIn;
begin
   ShowMessage('7 Create FrameLogin');
   if not Assigned(Form_LogIn) then begin
      ShowMessage('7.1 TForm_LogIn.CreateNew');
      Form_LogIn := TForm_LogIn.CreateNew(Form_NMain.Sheet_LogIn.ElementID, nil);
      Form_LogIn.OnLogIn_Run:=Logic.Run_LogIn;
      //Design.Design_LogIn;
   end;
   Form_NMain.Frame_Control.TabIndex:=0;
end;
In der Procedure WebFormShow habe ich erst das Form LogIn created und das Design als CallBack von Get_Sprache gesetzt.
Delphi-Quellcode:
procedure TForm_NMain.WebFormShow(Sender: TObject);
begin
   FullScreen;
   Create_frmLogIn;
   ShowMessage('1 Main_Show');
   ShowMessage(Sheet_LogIn.Name);
   Data_Module.xConnection_connect(procedure
      begin
         ShowMessage('3 AonConnect');
         Data_Module.Get_Property;
         ShowMessage('4 Get_Property done');
         Data_Module.Get_Sprache(Design.Design_LogIn);
      end
      );
end;
Eigentlich hätte ich erwartet, dass das keinen Unterschied macht...

Vielen Dank für die tolle Unterstützung!!!!

Patrick

DieDolly 10. Dez 2019 11:19

AW: Zugriff auf Objekt in TObjectList
 
Jetzt mach noch was als Lösung in https://www.delphipraxis.net/1453114-post17.html vorgeschlagen wurde und alles ist sauber.

Ykcim 10. Dez 2019 11:32

AW: Zugriff auf Objekt in TObjectList
 
Sorry, dass ich da noch einmal nachfragen muss.

Delphi-Quellcode:
procedure TDesign.Design_LogIn;
var
   BList: TObjectList;
begin
   BList:= TObjectList.Create;
   BList.OwnsObjects:= false;
   Try
      BList.Add(Form_LogIn.btn_login_abbruch);
      BList.Add(Form_LogIn.btn_login_ok);
      Design.Labeling_GlowButtons(BList); // Bringe ich nicht hier die Tüte zum Auto? (Ich finde das Beispiel klasse!)
   Finally
      BList.Free; //Werfe ich die Tüte nicht erst jetzt, wo ich meine Einkäufe im Auto habe, weg?
   End;
end;
Oder geht es darum, dass ich diese Liste im weiteren Programm immer wieder mal heranziehen soll, wenn benötigt?

Vielen Dank
Patrick

hoika 10. Dez 2019 11:39

AW: Zugriff auf Objekt in TObjectList
 
Hallo,
so, wie Du das machst, ist es (auch) OK.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:23 Uhr.
Seite 1 von 2  1 2      

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