Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Problem mit Dynamischem Menü (https://www.delphipraxis.net/166364-problem-mit-dynamischem-menue.html)

Satyr 9. Feb 2012 15:41

Problem mit Dynamischem Menü
 
Huhu,

ich habe ein Problem, das einfach klingt, mich aber vor Rätsel stellt.
Ich erstelle PopUp Menü und einer der Einträge hat ein Untermenü, das ich dynamisch generiere, wenn es aufgerufen wird. Soweit kein Problem, das mache ich mit folgendem Code:

Delphi-Quellcode:
      fuunc.ASQLite3Query1.Active := false;
      fuunc.ASQLite3Query1.SQL.Clear;
      fuunc.ASQLite3Query1.SQL.Add('SELECT * FROM kontinente;');
      fuunc.ASQLite3Query1.Active := true;
 
      while not fuunc.ASQLite3Query1.Eof do begin
       SubItem := TMenuItem.Create(Self);
       SubItem.Caption := fuunc.ASQLite3Query1.FieldByName('name').AsString;
       BookArena1.Add(SubItem);
       fuunc.ASQLite3Query1.Next;
      end;
Geht sicher auch Eleganter aber es funktioniert.

Problem ist jetzt, das dieses SubMenü mehrfach aufgerufen werden kann und bei jedem Aufruf diese Punkte im Untermenü generiert. Also würde ich vorher gern erst alle (alten) Punkte löschen. Und da taucht mein Problem auf. Gelöscht bekomme ich jeh einen Eintrag, indem ich ihn genau anspreche. Durch ein "Count" weiß ich auch wieviele Einträge ich habe. Aber genau dieser Wert ändert sich ja, wenn ich einen Eintrag lösche. Ich kann ihn also nicht in einer einfachen for Schleife verwenden.
Als Abhilfe habe ich folgendes versucht:
Delphi-Quellcode:
while BookArena1.Count > 0 do begin
 BookArena1.Delete(BookArena1.Count);
end;
Ich dachte damit wird immer der letzte Menüeintrag gelöscht, bis keine mehr da sind.

Aber bei Ausführung des Codes, bekomme ich eine Zugriffsverletzung und Delphi stürzt komplett ab.

Was mache ich falsch? Wie macht man es richtig?

Gruß,
Andreas

DeddyH 9. Feb 2012 15:46

AW: Problem mit Dynamischem Menü
 
Zitat:

Delphi-Quellcode:
BookArena1.Delete(BookArena1.Count);

Da fehlt ein -1. Übrigens müsste es auch mit einer For-Schleife gehen, wenn man die rückwärts laufen lässt.
Delphi-Quellcode:
for i := BookArena1.Count - 1 downto 0 do
  BookArena1.Delete(i);

ChrisE 9. Feb 2012 15:47

AW: Problem mit Dynamischem Menü
 
Um alle zu löschen:
Delphi-Quellcode:
BookArena1.Clear;
// jetzt alles hinzufügen...
Den Rest kann man vergessen wegen der roten Box :-(

Um geziehlt zu löschen ist Delete richtig aber Count gibt die Anzahl an, d.h. der höchste ansprechbare Eintrag in der Liste ist immer Count -1

Dein Code damit:
Delphi-Quellcode:
while BookArena1.Count > 0 do begin
 BookArena1.Delete(BookArena1.Count-1);
end;
Oder auch per Schleife:
Delphi-Quellcode:
for i:= BookArena1.Count -1 downto 0 do
begin
  BookArena1.Delete(i);
end;
Gruß, Chris

Satyr 9. Feb 2012 15:58

AW: Problem mit Dynamischem Menü
 
Danke, das "-1" wars. Manchmal habe ich echt einen Knoten im Hirn. Clear hat den Nachteil, das damit alle propertys vom Objekt gelöscht werden und ich dann nicht mehr darauf zugreifen kann.

Aber jetzt habe ich leider ein neues Problem. Nach dem löschen versuche ich die dynamische Generierung des Untermenüs. Hier noch mal der Code:

Delphi-Quellcode:
     
      fuunc.ASQLite3Query1.Active := false;
      fuunc.ASQLite3Query1.SQL.Clear;
      fuunc.ASQLite3Query1.SQL.Add('SELECT * FROM kontinente;');
      fuunc.ASQLite3Query1.Active := true;

      while not fuunc.ASQLite3Query1.Eof do begin
       SubItem := TMenuItem.Create(Self);
       SubItem.Caption := fuunc.ASQLite3Query1.FieldByName('name').AsString;
       BookArena1.Add(SubItem);
       fuunc.ASQLite3Query1.Next;
      end;
Aber da scheint irgendwo ne Endlosschleife zu sein. Der Curser wird zum Stundenglas mit dem Schriftzug "SQL" darunter und flackert ein wenig. Das wars aber. Da wird nichts fertig und der Cursor bleibt so.

Das ganze rufe ich übrigens in folgender procedure auf:
Delphi-Quellcode:
procedure Tpl.BookArena1Click(Sender: TObject);
"BookArena1" ist ein Menüsegment in einem TPopUpMenu.

Was übersehe ich jetzt?

Gruß,
Andreas

ChrisE 10. Feb 2012 07:09

AW: Problem mit Dynamischem Menü
 
Zitat:

Zitat von Satyr (Beitrag 1150155)
...Clear hat den Nachteil, das damit alle propertys vom Objekt gelöscht werden und ich dann nicht mehr darauf zugreifen kann...

Das glaube ich so nicht ganz. In dem ganz konkreten Fall eines TMenuItems räumt Clear nur die SubItems auf.

Gruß, Chris

jaenicke 10. Feb 2012 09:01

AW: Problem mit Dynamischem Menü
 
Wozu denn die TMenuItems immer neu erstellen? Es reicht doch eine TObjectList<TMenuItem> mit den aktuellen Menüeinträgen, aus der ggf. überzählige Einträge gelöscht oder neue hinzugefügt werden um die neu gebrauchte Anzahl zu erreichen. Danach hat man dann die korrekte Anzahl und braucht nur die Überschriften neu zu setzen. ;-)

ChrisE 10. Feb 2012 09:07

AW: Problem mit Dynamischem Menü
 
Zitat:

Zitat von jaenicke (Beitrag 1150265)
Wozu denn die TMenuItems immer neu erstellen? Es reicht doch eine TObjectList<TMenuItem> mit den aktuellen Menüeinträgen, aus der ggf. überzählige Einträge gelöscht oder neue hinzugefügt werden um die neu gebrauchte Anzahl zu erreichen. Danach hat man dann die korrekte Anzahl und braucht nur die Überschriften neu zu setzen. ;-)

Ich glaube das wäre doppelt gemoppelt, da jedes TMenuItem seine SubItems selber verwaltet (Free etc.). Aber man könnte den Ansatz trotzdem verwenden mit eben genau dieser TMenuItem eigenen Items-Liste. Brauche ich mehr erzeuge ich welche, habe ich weniger vergerge/lösche ich diese. Danach wird jedes Item angepasst (Caption/OnClick/Tag etc.) :-)

Gruß, Chris

Satyr 10. Feb 2012 14:51

AW: Problem mit Dynamischem Menü
 
Danke für Eure Vorschläge, ich probier mal in der Richtung rum :).


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:21 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