AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TObjectList sehr anfällig?

Ein Thema von EWeiss · begonnen am 26. Aug 2012 · letzter Beitrag vom 31. Aug 2012
Antwort Antwort
Seite 1 von 6  1 23     Letzte »    
EWeiss
(Gast)

n/a Beiträge
 
#1

TObjectList sehr anfällig?

  Alt 26. Aug 2012, 08:06
Versuche die TObjectList anstelle von Collection(VB) zu verwedenden.

Beim start der Anwendung wird ein Button erstellt der aber nicht in die TObjectList aufgenommen wird.
Das ergebis ist dann ListIndex überschreitet das Maximum(1)

Lasse ich den ersten Button weg und fange bei 0 an kommt die Meldung ListIndex überschreitet das Maximum(0)
Langsam bekomme ich einen Anfall und frage mich ob es nicht besser wäre einfach ein normales Array zu verwenden.
Ich dachte das es sinnvoll wäre da die Button während der Laufzeit auch wieder entfernt
bzw.. ReOrganisiert werden müssen.

FColButtons: TObjectList;

Delphi-Quellcode:
function TClsProgBar.Button(Btn: Integer): TClsButtonInfo;
var
  FSelButton: TObject;
begin
  FSelButton := nil;
  try
    try
      // auch ein FColButtons.Items[Btn- 1]) führt zu einem EListError
      FSelButton := (FColButtons.Items[Btn]) as TClsButtonInfo;
    except
      //
    end;
  finally
     Result := TClsButtonInfo(FSelButton);
  end;

end;
Delphi-Quellcode:
function TClsProgBar.ReOrgDisplay(Ctrl: TClsControls; oInit: Bool): Bool;
var
  Width: Integer;
  Height: Integer;
  Btn: Integer;
  oButton: TClsButtonInfo;

begin

  NewNumButtons := ButtonWidth * ButtonHeight;
  oButton := nil;

  // Lösche nicht benötigte Controls
  if NewNumButtons < FNumButtons then
  begin
     // lösche nichtverwendete Tasten, ausgenommen die erste
     for Btn := NewNumButtons + 1 to FNumButtons do
       Ctrl.RemoveButton(Btn);
  end;

  // lösche nichtverwendete einträge in der TObjectList
  if NewNumButtons < FColButtons.Count then
    // Lösche nicht benötigte Tasten, ausgenommen die erste
    for Btn := NewNumButtons + 1 to FNumButtons do
      RemoveButton(Btn);

  // erstelle neue Tasten wenn vorhanden
  Btn := 0;
  for Height := 1 to ButtonHeight do
  begin
    for Width := 1 to ButtonWidth do
    begin
      inc(Btn);
      if Btn > FNumButtons then
        Ctrl.AddButton(frmButtonHandle, Btn);

      Ctrl.PositionButton(Btn, Width, Height);

      if Btn > FColButtons.Count then
      begin
        try
          oButton := TClsButtonInfo.Create(nil);
          oButton.Num := Btn;
          AddButton(oButton);
        finally
          oButton := nil;
        end;
      end;
    end; // Width
  end; // Height

  // ButtonForm adjustieren
  Ctrl.Adjust(ButtonWidth, ButtonHeight);

  if oInit then
  begin
    // lösche die 1. Taste
    oButton := Button(1);
    if Assigned(oButton) then
    begin
      try
        oButton.BmpFile := '';
        oButton.ButtonKey := '';
        oButton.ToolTip := '';
        oButton.ButtonCmd := '';
      finally
        oButton := nil;
      end;
    end;
    // ProgBar-Properties zurücksetzen
    ClassNamen := '';
    ProgPath := '';
    ArbVerz := '';
    ProgTitle := '';
    ProgToolTips := '';
    ProgTrayMenu := '';
    Name := '';

    FNumButtons := 1;
  end else
  FNumButtons := NewNumButtons;

  if Assigned(SelButton) then
    SelButton.Free;

  result := True;
end;
Bedingt durch den Fehler fehlen mir immer irgendwelche Button
hier zum beispiel 2 .. sollten 8 sichtbar sein.

gruss

Geändert von EWeiss (11. Jul 2019 um 15:41 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: TObjectList sehr anfällig?

  Alt 26. Aug 2012, 09:01
Also eine TObjectList ist genauso anfällig wie ein Array, vor allem weil eine TObjectList ein gekapseltes Array ist. Und ein Griff neben die Kiste ( Index < 0 or Index >= Count ) würde auch bei einem Array Probleme geben.

Allerdings findet es eine TObjectList doof, wenn man eine Instanz in der Liste aus dem Speicher wirft, solange diese noch in selbiger verweilt.

Aus deinem Code entnehme ich, dass du da die Buttons entfernst und erst dann die Liste bereinigst. Diese Organisation sehe ich als den kritischen Teil an. Denn in der TObjectList sind ja die Verweise auf die Instanzen noch enthalten und wenn OwnsObjects auf true, dann versucht die TObjectList beim Entfernen aus der Liste ein Free auf diese (vermeintlich noch existierende) Instanz.

Evtl. ist da die Verantwortlichkeit (wer macht was wann) im Code nicht klar geregelt. Aber zur Beurteilung fehlt da der CodeTeil, der für den Eintrag und das Entfernen der Buttons.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#3

AW: TObjectList sehr anfällig?

  Alt 26. Aug 2012, 09:17
Zitat:
Aus deinem Code entnehme ich, dass du da die Buttons entfernst und erst dann die Liste bereinigst.
Das sehe ich nicht so zumindest nicht beim ersten start und da kracht es ja schon.
Denn..
NewNumButtons := ButtonWidth * ButtonHeight; "ButtonWidth * ButtonHeight" = 1 * 1

Da NewNumButtons in dem Fall 1 ist, also nicht weniger wie FColButtons.Count wird hier auch nichts gelöscht.

Nachher mag das zutreffend sein dafür muss ich einfach nur die beiden abfragen vertauschen.
Obwohl Ctrl.RemoveButton(Btn) nichts mit RemoveButton(Btn) zu tun hat.

Zitat:
der für den Eintrag und das Entfernen der Buttons.
Das dürften die fehlenden Funktionen sein.


Delphi-Quellcode:
function TClsProgBar.AddButton(var oButton: TClsButtonInfo): Bool;
begin
  if ButtonExists(oButton.Num) then
    RemoveButton(oButton.Num);

  FColButtons.Add(oButton);
  FColButtons.Insert(oButton.Num, oButton);

  Result := True;

end;
Delphi-Quellcode:
function TClsProgBar.ButtonExists(Btn: Integer): Bool;
begin
  FOButton := Button(Btn);
  Result := Assigned(FOButton);

end;
Beim ersten start kracht es schon (also EListError)
Notfalls kann ich den Source mal hochladen.

gruss

Geändert von EWeiss (26. Aug 2012 um 09:48 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.021 Beiträge
 
Delphi 12 Athens
 
#4

AW: TObjectList sehr anfällig?

  Alt 26. Aug 2012, 10:05
FColButtons.Add(oButton);
FColButtons.Insert(oButton.Num, oButton);
Ich vermute mal, daß FColButtons die TObjectList ist. Dann wird mit FColButtons.Add(oButton); der Button an die Liste angehängt und mit FColButtons.Insert(oButton.Num, oButton); nochmal an der Stelle oButton.Num eingefügt. Er befindet sich jetzt also zweimal in der Liste. Das bringt zumindest die Bedeutung von FColButtons.Count durcheinander.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: TObjectList sehr anfällig?

  Alt 26. Aug 2012, 10:10
Das ButtonExists würde ich umschreiben oder das Button( Btn : Integer ).

Delphi-Quellcode:
function TClsProgBar.ButtonExists( Btn : Integer ) : Bool;
begin
  Result := ( Btn >= 0 ) and ( Btn < FButtonList.Count );
end;
Die genaue Codierung hängt allerdings davon ab, ob du 0 basierend indizierst (so wie die Liste) oder 1 basierend.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

AW: TObjectList sehr anfällig?

  Alt 26. Aug 2012, 10:19
Das ButtonExists würde ich umschreiben oder das Button( Btn : Integer ).

Delphi-Quellcode:
function TClsProgBar.ButtonExists( Btn : Integer ) : Bool;
begin
  Result := ( Btn >= 0 ) and ( Btn < FButtonList.Count );
end;
Die genaue Codierung hängt allerdings davon ab, ob du 0 basierend indizierst (so wie die Liste) oder 1 basierend.
Danke euch werde die Infos mal durchgehen und sehen ob ich dann auf einen nenner komme.

gruss
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#7

AW: TObjectList sehr anfällig?

  Alt 26. Aug 2012, 10:34
Das umschreiben der ButtonExists sorgt zumindest dafür das es zu keinen ElistError mehr kommt.

Wenn ich hingegen irgendeine Zeile von AddButton entferne dann kracht es wieder.
Delphi-Quellcode:
function TClsProgBar.AddButton(var oButton: TClsButtonInfo): Bool;
begin
  if ButtonExists(oButton.Num) then
    RemoveButton(oButton.Num);

  FColButtons.Add(oButton); // kann nicht entfernt werden
  FColButtons.Insert(oButton.Num, oButton); // Das auch nicht

  Result := True;

end;

Wirklich kompiliziert die Collection von VB nach Delphi zu portieren.
Hier sind mal die VB Teile dazu..
mcolButtons = Collection und in Delphi halt die TObjectList.

Code:
Public Function AddButton(ByRef roButton As clsButtonInfo) As Boolean

    If ButtonExists(roButton.Num) Then RemoveButton roButton.Num

    mcolButtons.Add roButton, CStr(roButton.Num)

End Function
Code:
Public Property Get Button(ByVal vlBtn As Long) As clsButtonInfo

    On Error Resume Next

        Set moSelButton = mcolButtons.Item(CStr(vlBtn))

        Set Button = moSelButton
        Err.Clear

End Property
Code:
Private Function ButtonExists(ByVal vlBtn As Long) As Boolean

Dim oButton As clsButtonInfo

    Set oButton = Button(vlBtn)
    ButtonExists = CBool(Not oButton Is Nothing)

End Function
Nur das ihr den Unterschied sehen könnt.
Sorry habe mich noch nie mit der ObjectList beschäftigt.

Nebenbei:
Es geht hier nicht um Copy/Paste
Es ist ein Programm das ich 1999 in VB geschrieben habe was da auf der VB seite abgeht weiss ich und stellt kein problem dar.

gruss

Geändert von EWeiss (26. Aug 2012 um 10:40 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.021 Beiträge
 
Delphi 12 Athens
 
#8

AW: TObjectList sehr anfällig?

  Alt 26. Aug 2012, 11:10
Wenn ich hingegen irgendeine Zeile von AddButton entferne dann kracht es wieder.
Delphi-Quellcode:
function TClsProgBar.AddButton(var oButton: TClsButtonInfo): Bool;
begin
  if ButtonExists(oButton.Num) then
    RemoveButton(oButton.Num);

  FColButtons.Add(oButton); // kann nicht entfernt werden
  FColButtons.Insert(oButton.Num, oButton); // Das auch nicht

  Result := True;

end;
Dann solltest du herausfinden, warum es dann kracht, denn die beiden Zeilen machen zweimal das fast gleiche. Beim Add wird der Button an die TObjectList angehängt und beim Insert nochmal an der übergebenen Stelle eingefügt. Nach dem ersten Aufruf von AddButton enthält die TObjectList somit zwei Elemente (Buttons), wobei es sich aber um dieselbe Instanz eines Buttons handelt. Leider konnte ich nocht nicht erkennen, ob die TObjectList mit OwnsValues kreiert wurde. Dann gibt es nämlich spätestens beim Entfernen der Buttons ganz massive Probleme. Außerdem gibt TObjectList.Count die Anzahl der Elemente zurück, die immer das doppelte der Anzahl der Buttons entspricht.

Der Code mit Add und Insert ist in jedem Fall falsch.

Gib doch bitte mal den kompletten Code mitsamt ButtonExists uhnd RemoveButton, damit man mal den Überblick bekommt.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#9

AW: TObjectList sehr anfällig?

  Alt 26. Aug 2012, 11:16
Zitat:
Gib doch bitte mal den kompletten Code mitsamt ButtonExists uhnd RemoveButton, damit man mal den Überblick bekommt.
Dann wäre es einfacher den Quelltext anzuhängen.
Da hier zu viele dinge zugehörig sind.

Ich habe ihn so klein wie möglich gehalten zwei Skins müssen sein zum gegenprüfen.
Die aktuell relevanten teile befinden sich in uProgBar
Das ist eine Common Classe die später auch für ProgStart verwendet wird.

gruss

Geändert von EWeiss (26. Aug 2012 um 12:58 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.021 Beiträge
 
Delphi 12 Athens
 
#10

AW: TObjectList sehr anfällig?

  Alt 26. Aug 2012, 12:11
Ein paar Dinge gleich nach dem ersten Duchsehen:
  1. Der Index in TObjectList ist 0-basiert, TClsButtonInfo.Num fängt aber bei 1 an.
  2. Das Löchen von Elementen aus einer Liste funktioniert nur dann richtig, wenn man for I:=<ende> downto <start> do verwendet.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 6  1 23     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:12 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz